Message ID | 20241212180423.1578358-22-smostafa@google.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | KVM: Arm SMMUv3 driver for pKVM | expand |
On Thursday 12 Dec 2024 at 18:03:45 (+0000), Mostafa Saleh wrote: > From: Jean-Philippe Brucker <jean-philippe@linaro.org> > +/* > + * Temporarily unmap a page from the host stage-2, if @remove is true, or put it > + * back. After restoring the ownership to host, the page will be lazy-mapped. > + */ > +int __pkvm_host_add_remove_page(u64 pfn, bool remove) > +{ > + int ret; > + u64 host_addr = hyp_pfn_to_phys(pfn); > + u8 owner = remove ? PKVM_ID_HYP : PKVM_ID_HOST; > + > + host_lock_component(); > + ret = host_stage2_set_owner_locked(host_addr, PAGE_SIZE, owner); Any reason why this can't be expressed using __pkvm_host_donate_hyp() and __pkvm_hyp_donate_host()? This doesn't check any state, so it feels like a dangerous primitive to have. Is the issue the overhead of mapping/unmapping into EL2 stage-1?
On Thu, Dec 19, 2024 at 11:10:23AM +0000, Quentin Perret wrote: > On Thursday 12 Dec 2024 at 18:03:45 (+0000), Mostafa Saleh wrote: > > From: Jean-Philippe Brucker <jean-philippe@linaro.org> > > +/* > > + * Temporarily unmap a page from the host stage-2, if @remove is true, or put it > > + * back. After restoring the ownership to host, the page will be lazy-mapped. > > + */ > > +int __pkvm_host_add_remove_page(u64 pfn, bool remove) > > +{ > > + int ret; > > + u64 host_addr = hyp_pfn_to_phys(pfn); > > + u8 owner = remove ? PKVM_ID_HYP : PKVM_ID_HOST; > > + > > + host_lock_component(); > > + ret = host_stage2_set_owner_locked(host_addr, PAGE_SIZE, owner); > > Any reason why this can't be expressed using __pkvm_host_donate_hyp() > and __pkvm_hyp_donate_host()? That makes more sense, I will fix it. > > This doesn't check any state, so it feels like a dangerous primitive to > have. Is the issue the overhead of mapping/unmapping into EL2 stage-1?
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index d75e64e59596..c8f49b335093 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -94,6 +94,7 @@ int __pkvm_guest_relinquish_to_host(struct pkvm_hyp_vcpu *vcpu, u64 ipa, u64 *ppa); int __pkvm_host_use_dma(u64 phys_addr, size_t size); int __pkvm_host_unuse_dma(u64 phys_addr, size_t size); +int __pkvm_host_add_remove_page(u64 pfn, bool remove); bool addr_is_memory(phys_addr_t phys); int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot); diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 0840af20c366..a428ad9ca871 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -2521,3 +2521,20 @@ int host_stage2_get_leaf(phys_addr_t phys, kvm_pte_t *ptep, s8 *level) return ret; } + +/* + * Temporarily unmap a page from the host stage-2, if @remove is true, or put it + * back. After restoring the ownership to host, the page will be lazy-mapped. + */ +int __pkvm_host_add_remove_page(u64 pfn, bool remove) +{ + int ret; + u64 host_addr = hyp_pfn_to_phys(pfn); + u8 owner = remove ? PKVM_ID_HYP : PKVM_ID_HOST; + + host_lock_component(); + ret = host_stage2_set_owner_locked(host_addr, PAGE_SIZE, owner); + host_unlock_component(); + + return ret; +}