Re: [PATCH] KVM: have hva_to_pfn_remapped write-upgrade PTEs
Sergio Lopez Pascual <[email protected]> Thu, 30 Jul 2026 04:36:52 -0400
| Newsgroups | dev.linux.lists.sashiko-reviews,org.kernel.vger.kvm |
|---|---|
| Message-ID | <CAAiTLFVTN-KWF3hzPxB-RR6SuLF+9JAWbrLA2um7ZkgXUcdxAw@mail.gmail.com> |
[email protected] writes: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > > Pre-existing issues: > - [High] Incomplete fix for VM_PFNMAP write-upgrades, bypassing already-populated read-only PTEs > -- > > --- Patch [1]: [PATCH] KVM: have hva_to_pfn_remapped write-upgrade PTEs --- > commit 8ea7b308a68b0aabea9b703efac8ec9af51170aa > Author: Sergio Lopez <[email protected]> > Subject: KVM: have hva_to_pfn_remapped write-upgrade PTEs > > This patch introduces a second fixup_user_fault call to handle > write-upgrades for VM_PFNMAP mappings that install read-only PTEs on > write faults (such as DRM GEM BOs). > >> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c >> index b4baa69a55402..b7fb9278f198b 100644 >> --- a/virt/kvm/kvm_main.c >> +++ b/virt/kvm/kvm_main.c >> @@ -2958,6 +2958,8 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma, > [ ... ] >> r = follow_pfnmap_start(&args); >> if (r) { >> /* >> * get_user_pages fails for VM_IO and VM_PFNMAP vmas and does >> * not call the fault handler, so do it here. >> */ >> bool unlocked = false; >> + bool write_upgrade = false; >> +do_write_upgrade: >> r = fixup_user_fault(current->mm, kfp->hva, >> (write_fault ? FAULT_FLAG_WRITE : 0), >> &unlocked); >> @@ -2969,6 +2971,17 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma, >> r = follow_pfnmap_start(&args); >> if (r) >> return r; >> + >> + if (write_fault && !args.writable && !write_upgrade) { >> + /* >> + * VM_PFNMAP fault handlers may install read-only PTEs >> + * via vmf_insert_pfn(), deferring the write upgrade to >> + * a second fault. Trigger that upgrade now. >> + */ >> + write_upgrade = true; >> + follow_pfnmap_end(&args); >> + goto do_write_upgrade; >> + } >> } >> >> if (write_fault && !args.writable) { > ^^^^ > > [Severity: High] > This is a pre-existing issue, but does this placement miss the case where > the PTE is already populated but read-only? > > If a guest first reads from the DRM GEM BO, triggering a read fault, the > DRM GEM fault handler installs a read-only PTE. If the guest later attempts > to write to the same page, hva_to_pfn_remapped() calls follow_pfnmap_start(), > which finds the read-only PTE and returns 0 (success). > > Since r == 0, the entire if (r) block containing the new write upgrade logic > is bypassed. The code then reaches this check and incorrectly returns > KVM_PFN_ERR_RO_FAULT instead of performing the write upgrade. > > Should the upgrade logic be placed outside of the if (r) block so it can also > handle already-populated read-only PTEs? Yes, I've confirmed this scenario is possible. I'll send a v2. Thanks, Sergio.