From: sashiko-bot@kernel.org
To: "Paolo Bonzini" <pbonzini@redhat.com>
Cc: dri-devel@lists.freedesktop.org, kvm@vger.kernel.org
Subject: Re: [PATCH RFT 3/3] drm/ttm, drm/vmwgfx: directly create writable PTEs when mkwrite is in use
Date: Fri, 31 Jul 2026 17:04:08 +0000 [thread overview]
Message-ID: <20260731170408.A6E2C1F00AC4@smtp.kernel.org> (raw)
In-Reply-To: <20260731164341.1109827-4-pbonzini@redhat.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [Critical] The dirty tracking structure `vbo->dirty` can be freed concurrently by `vmw_bo_dirty_release()` without holding the buffer object's reservation lock, causing a use-after-free in `vmw_bo_dirty_mkwrite()`.
- [High] Inverted error handling in ttm_bo_vm_fault_reserved masks primary fault errors (causing infinite page fault loops) and erroneously surfaces speculative prefault errors.
--
--- Patch [3]: [PATCH RFT 3/3] drm/ttm, drm/vmwgfx: directly create writable PTEs when mkwrite is in use ---
commit 894d8cfbec765789074f38bcd9f120fdcf49cba5
Author: Paolo Bonzini <pbonzini@redhat.com>
drm/ttm, drm/vmwgfx: directly create writable PTEs when mkwrite is in use
This commit changes the fault handler to directly insert writable PTEs for the
first page when write access is requested. It achieves this by manually
recording the write fault instead of relying on the .pfn_mkwrite() callback.
> diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> index a80510489c456..ef27a2d7afc07 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> @@ -263,7 +263,8 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
> * at arbitrary times while the data is mmap'ed.
> * See vmf_insert_pfn_prot() for a discussion.
> */
> - ret = vmf_insert_pfn_prot(vma, address, pfn, prot);
> + ret = __vmf_insert_pfn_prot(vma, address, pfn, prot,
> + i == 0 && !!(vmf->flags & FAULT_FLAG_WRITE));
>
> /* Never error on prefaulted PTEs */
> if (unlikely((ret & VM_FAULT_ERROR))) {
> if (i == 0)
> return VM_FAULT_NOPAGE;
> else
> break;
> }
[Severity: High]
This is a pre-existing issue, but could this error handling in
ttm_bo_vm_fault_reserved() lead to infinite page fault loops or unwarranted
SIGBUS crashes?
If __vmf_insert_pfn_prot() returns an error like VM_FAULT_SIGBUS or
VM_FAULT_OOM, and it is the primary fault (i == 0), this block returns
VM_FAULT_NOPAGE (success). Does this cause the kernel to infinitely retry
the faulting instruction?
Also, if it is a speculative prefault (i > 0), the loop breaks and returns
the prefault error, crashing the application even though the primary fault
succeeded. Is this the intended behavior?
[ ... ]
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
> index 45561bc1c9eff..3099558c0762f 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
> @@ -398,15 +398,33 @@ void vmw_bo_dirty_clear_res(struct vmw_resource *res)
> dirty->end = res_start;
> }
>
> +static vm_fault_t vmw_bo_dirty_mkwrite(struct vm_fault *vmf, struct ttm_buffer_object *bo)
> +{
> + unsigned long page_offset;
> + struct vmw_bo *vbo = to_vmw_bo(&bo->base);
> +
> + page_offset = vmf->pgoff - drm_vma_node_start(&bo->base.vma_node);
> + if (unlikely(page_offset >= PFN_UP(bo->resource->size)))
> + return VM_FAULT_SIGBUS;
> +
> + if (vbo->dirty && vbo->dirty->method == VMW_BO_DIRTY_MKWRITE &&
> + !test_bit(page_offset, &vbo->dirty->bitmap[0])) {
> + struct vmw_bo_dirty *dirty = vbo->dirty;
> +
> + __set_bit(page_offset, &dirty->bitmap[0]);
> + dirty->start = min(dirty->start, page_offset);
> + dirty->end = max(dirty->end, page_offset + 1);
> + }
[Severity: Critical]
This isn't a bug introduced by this patch, but is it possible for vbo->dirty
to be freed concurrently without holding the buffer object's reservation lock?
If user space destroys the framebuffer, vmw_bo_dirty_release() is called,
which modifies and frees vbo->dirty:
void vmw_bo_dirty_release(struct vmw_bo *vbo)
{
struct vmw_bo_dirty *dirty = vbo->dirty;
if (dirty && kref_put(&dirty->ref_count, vmw_bo_dirty_free))
vbo->dirty = NULL;
}
Since vmw_bo_dirty_release() doesn't appear to take the resv lock, can a
concurrent write to a mapped buffer object (which triggers the page fault
handler and calls vmw_bo_dirty_mkwrite() under the resv lock) dereference
the freed vbo->dirty memory here, leading to a use-after-free?
> + return 0;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260731164341.1109827-1-pbonzini@redhat.com?part=3
prev parent reply other threads:[~2026-07-31 17:04 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 16:43 [PATCH RFT 0/3] mm, drm: ensure .fault() does not have to be followed by .pfn_mkwrite() for write faults Paolo Bonzini
2026-07-31 16:43 ` [PATCH RFT 1/3] mm: export variants of vmf_insert_pfn* for use with pfn_mkwrite() Paolo Bonzini
2026-07-31 16:43 ` [PATCH RFT 2/3] drm/shmem_helper: use vmf_insert_pfn_mkwrite() Paolo Bonzini
2026-07-31 17:06 ` sashiko-bot
2026-07-31 16:43 ` [PATCH RFT 3/3] drm/ttm, drm/vmwgfx: directly create writable PTEs when mkwrite is in use Paolo Bonzini
2026-07-31 17:04 ` sashiko-bot [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260731170408.A6E2C1F00AC4@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox