Re: [PATCH] drm/gem-shmem: Install writable PTEs for write faults
Boris Brezillon <[email protected]> Tue, 4 Aug 2026 16:29:24 +0200
| Newsgroups | gmane.linux.kernel.stable,gmane.comp.video.dri.devel,gmane.linux.kernel.mm,gmane.linux.kernel |
|---|---|
| Organization | Collabora |
| Message-ID | <[email protected]> |
Hello Konstantin, On Tue, 4 Aug 2026 17:04:03 +0300 Konstantin Fastov <[email protected]> wrote: > Since the introduction of dirty tracking, drm_gem_shmem_vm_ops has a > .pfn_mkwrite handler. Its presence makes vma_wants_writenotify() true, > so vma_set_page_prot() removes the write bit from vm_page_prot of > shared mappings, and the vmf_insert_pfn() call in the fault handler now > installs read-only PTEs even when serving a write fault. > > For regular CPU accesses this is transparent: the retried access faults > again on the present read-only PTE, goes through wp_pfn_shared() into > .pfn_mkwrite() and the PTE is upgraded to writable. But consumers that > resolve faults through fixup_user_fault() + follow_pfnmap_start() > perform no such retry. In particular KVM's hva_to_pfn_remapped(), > after "successfully" handling a write fault, finds a present read-only > PTE, treats it as KVM_PFN_ERR_RO_FAULT and fails the vcpu run with > EFAULT. Observed as AsahiLinux/linux#560: muvm/libkrun microVMs > mapping virtio-gpu blob resources die with EFAULT on first GPU access. > The traced failing sequence: > > follow_pfnmap_start() -> -EINVAL (no PTE yet) > fixup_user_fault(WRITE) > drm_gem_shmem_fault() > vmf_insert_pfn() -> NOPAGE (read-only PTE installed) > fixup_user_fault() -> 0 (fault "handled") > follow_pfnmap_start() -> 0, !writable > hva_to_pfn() -> KVM_PFN_ERR_RO_FAULT > > Fix it the same way commit cb2a2a5b37ad ("drm/shmem_helper: Make sure > PMD entries get the writeable upgrade") did for the PMD path: when the > fault is a write fault, install a writable entry directly and record > the write for dirty tracking, instead of relying on a refault that not > every fault-resolution path performs. > > To do that at PTE level, add vmf_insert_pfn_mkwrite(), the VM_PFNMAP > counterpart of vmf_insert_mixed_mkwrite(): insert_pfn() already > implements the mkwrite semantics, there was just no wrapper exposing it > for pfn inserts with the default pgprot. The same issue is being discussed here [1]. Regards, Boris [1]https://lore.kernel.org/dri-devel/[email protected]/