From: Val Packett <val@invisiblethingslab.com>
To: Juergen Gross <jgross@suse.com>,
Stefano Stabellini <sstabellini@kernel.org>,
Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Cc: "Val Packett" <val@invisiblethingslab.com>,
"Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>,
xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org,
virtualization@lists.linux.dev
Subject: [PATCH] xen: privcmd: fix ioeventfd crash under PV domain
Date: Wed, 8 Jul 2026 05:18:03 -0300 [thread overview]
Message-ID: <20260708082934.16038-1-val@invisiblethingslab.com> (raw)
Starting a virtio backend in a PV domain would panic the kernel in
alloc_ioreq, trying to dereference vma->vm_private_data as a pages
pointer when in reality it stayed as PRIV_VMA_LOCKED.
Avoid crashing by handling the PRIV_VMA_LOCKED case in alloc_ioreq.
PV support requires mapping the virtio ioreq page explicitly into
the kernel's page tables, so do it on-demand when PRIV_VMA_LOCKED
is seen.
Signed-off-by: Val Packett <val@invisiblethingslab.com>
---
Hi. This was previously submitted as an RFC[1] but got no feedback
in many many months.. Let's try again :)
This is all that's needed to make the ioeventfd facility work with
a PV dom0, which we still use in Qubes OS (yeah yeah we should move
to PVH dom0 but there are still regressions to debug there).
So we would really like to get this merged.
[1]: https://lore.kernel.org/all/20251126062124.117425-1-val@invisiblethingslab.com/
Thanks,
~val
---
drivers/xen/privcmd.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index 725a49a0eee7..05775a518948 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -833,6 +833,8 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
DOMID_SELF : kdata.dom;
int num, *errs = (int *)pfns;
+ vma->vm_pgoff = pfns[0]; /* store the acquired pfn for ioeventfd access */
+
BUILD_BUG_ON(sizeof(*errs) > sizeof(*pfns));
num = xen_remap_domain_mfn_array(vma,
kdata.addr & PAGE_MASK,
@@ -1264,10 +1266,38 @@ struct privcmd_kernel_ioreq *alloc_ioreq(struct privcmd_ioeventfd *ioeventfd)
goto error_kfree;
}
- pages = vma->vm_private_data;
- kioreq->ioreq = (struct ioreq *)(page_to_virt(pages[0]));
mmap_write_unlock(mm);
+ /* In a PV domain, we must manually map the pages into the kernel */
+ if (vma->vm_private_data == PRIV_VMA_LOCKED) {
+ /* This should never ever happen outside of PV */
+ if (WARN_ON_ONCE(!xen_pv_domain())) {
+ ret = -EINVAL;
+ goto error_kfree;
+ }
+
+ /* xen_remap_domain_mfn_array only really needs the mm */
+ struct vm_area_struct kern_vma = {
+ .vm_flags = VM_PFNMAP | VM_IO,
+ .vm_mm = &init_mm,
+ };
+ xen_pfn_t pfn = vma->vm_pgoff;
+ int num, err;
+
+ /* Don't provide NULL as the errors array as that results in pfn increment */
+ num = xen_remap_domain_mfn_array(&kern_vma, (unsigned long)pfn_to_kaddr(pfn),
+ &pfn, 1, &err, PAGE_KERNEL, ioeventfd->dom);
+ if (num < 0) {
+ ret = num;
+ goto error_kfree;
+ }
+
+ kioreq->ioreq = (struct ioreq *)(pfn_to_kaddr(pfn));
+ } else {
+ pages = vma->vm_private_data;
+ kioreq->ioreq = (struct ioreq *)(page_to_virt(pages[0]));
+ }
+
ports = memdup_array_user(u64_to_user_ptr(ioeventfd->ports),
kioreq->vcpus, sizeof(*ports));
if (IS_ERR(ports)) {
--
2.54.0
reply other threads:[~2026-07-08 8:30 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20260708082934.16038-1-val@invisiblethingslab.com \
--to=val@invisiblethingslab.com \
--cc=jgross@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=marmarek@invisiblethingslab.com \
--cc=oleksandr_tyshchenko@epam.com \
--cc=sstabellini@kernel.org \
--cc=virtualization@lists.linux.dev \
--cc=xen-devel@lists.xenproject.org \
/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