On Fri, Aug 9, 2024 at 9:09 AM Peter Xu <peterx@xxxxxxxxxx> wrote: > > Use the new pfnmap API to allow huge MMIO mappings for VMs. The rest work > is done perfectly on the other side (host_pfn_mapping_level()). I don't think it has to be done in this series, but a future optimization to consider is having follow_pfnmap just tell the caller about the mapping level directly. It already found this information as part of its walk. I think there's a possibility to simplify KVM / avoid it having to do its own walk again later. > > > Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx> > Cc: Sean Christopherson <seanjc@xxxxxxxxxx> > Signed-off-by: Peter Xu <peterx@xxxxxxxxxx> > --- > virt/kvm/kvm_main.c | 19 +++++++------------ > 1 file changed, 7 insertions(+), 12 deletions(-) > > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c > index d0788d0a72cc..9fb1c527a8e1 100644 > --- a/virt/kvm/kvm_main.c > +++ b/virt/kvm/kvm_main.c > @@ -2862,13 +2862,11 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma, > unsigned long addr, bool write_fault, > bool *writable, kvm_pfn_t *p_pfn) > { > + struct follow_pfnmap_args args = { .vma = vma, .address = addr }; > kvm_pfn_t pfn; > - pte_t *ptep; > - pte_t pte; > - spinlock_t *ptl; > int r; > > - r = follow_pte(vma, addr, &ptep, &ptl); > + r = follow_pfnmap_start(&args); > if (r) { > /* > * get_user_pages fails for VM_IO and VM_PFNMAP vmas and does > @@ -2883,21 +2881,19 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma, > if (r) > return r; > > - r = follow_pte(vma, addr, &ptep, &ptl); > + r = follow_pfnmap_start(&args); > if (r) > return r; > } > > - pte = ptep_get(ptep); > - > - if (write_fault && !pte_write(pte)) { > + if (write_fault && !args.writable) { > pfn = KVM_PFN_ERR_RO_FAULT; > goto out; > } > > if (writable) > - *writable = pte_write(pte); > - pfn = pte_pfn(pte); > + *writable = args.writable; > + pfn = args.pfn; > > /* > * Get a reference here because callers of *hva_to_pfn* and > @@ -2918,9 +2914,8 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma, > */ > if (!kvm_try_get_pfn(pfn)) > r = -EFAULT; > - > out: > - pte_unmap_unlock(ptep, ptl); > + follow_pfnmap_end(&args); > *p_pfn = pfn; > > return r; > -- > 2.45.0 >