From: "Cédric Le Goater" <clg@redhat.com>
To: qemu-devel@nongnu.org, qemu-arm@nongnu.org
Cc: "Alex Williamson" <alex@shazbot.org>,
"Eric Auger" <eric.auger@redhat.com>,
"Cédric Le Goater" <clg@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>
Subject: [PATCH v2] vfio/listener: Replace misalignment whitelist with DMA capability check
Date: Wed, 8 Jul 2026 15:36:04 +0200 [thread overview]
Message-ID: <20260708133604.1606448-1-clg@redhat.com> (raw)
The vfio_known_safe_misalignment() whitelist (currently TPM CRB only)
requires a new entry every time a device exposes a non-page-aligned
region, which does not scale.
Replace it with a DMA capability check: a region that is not
page-aligned or is smaller than a host page can never be a valid DMA
target, so a page-offset mismatch is harmless and only traced. Only
warn for page-aligned, page-sized regions where the mismatch could
indicate a real mapping problem.
This removes the TPM CRB dependency from the VFIO listener and
eliminates the need for per-device whitelisting entirely.
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260702160640.3875666-1-clg@redhat.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
hw/vfio/listener.c | 47 +++++++++++++++++++++++++-------------------
hw/vfio/trace-events | 2 +-
2 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
index c19600e980a8d02217b5d9df4aca8f879ab2c5d5..f2c3603a920b99002630d6f47af5bbbdfed8be86 100644
--- a/hw/vfio/listener.c
+++ b/hw/vfio/listener.c
@@ -40,7 +40,6 @@
#include "migration/misc.h"
#include "migration/qemu-file.h"
#include "system/tcg.h"
-#include "system/tpm.h"
#include "vfio-migration-internal.h"
#include "vfio-helpers.h"
#include "vfio-listener.h"
@@ -352,20 +351,17 @@ static void vfio_ram_discard_unregister_listener(VFIOContainer *bcontainer,
g_free(vrdl);
}
-static bool vfio_known_safe_misalignment(MemoryRegionSection *section)
+static bool vfio_section_misaligned(MemoryRegionSection *section)
{
- MemoryRegion *mr = section->mr;
-
- if (!TPM_IS_CRB(mr->owner)) {
- return false;
- }
+ return (section->offset_within_address_space & ~qemu_real_host_page_mask()) !=
+ (section->offset_within_region & ~qemu_real_host_page_mask());
+}
- /* this is a known safe misaligned region, just trace for debug purpose */
- trace_vfio_known_safe_misalignment(memory_region_name(mr),
- section->offset_within_address_space,
- section->offset_within_region,
- qemu_real_host_page_size());
- return true;
+static bool vfio_section_dma_capable(MemoryRegionSection *section)
+{
+ return QEMU_IS_ALIGNED(section->offset_within_address_space,
+ qemu_real_host_page_size()) &&
+ int128_ge(section->size, int128_make64(qemu_real_host_page_size()));
}
static bool vfio_listener_valid_section(MemoryRegionSection *section,
@@ -379,17 +375,28 @@ static bool vfio_listener_valid_section(MemoryRegionSection *section,
return false;
}
- if (unlikely((section->offset_within_address_space &
- ~qemu_real_host_page_mask()) !=
- (section->offset_within_region & ~qemu_real_host_page_mask()))) {
- if (!vfio_known_safe_misalignment(section)) {
- error_report("%s received unaligned region %s iova=0x%"PRIx64
+ if (unlikely(vfio_section_misaligned(section))) {
+ /*
+ * A region that is not page-aligned or is smaller than a host
+ * page can never be a valid DMA target, so the misalignment is
+ * harmless. Only warn for page-aligned, page-sized regions
+ * where the offset mismatch could indicate a real problem.
+ */
+ if (vfio_section_dma_capable(section)) {
+ error_report("vfio: region %s page-offset mismatch prevents"
+ " DMA mapping (iova=0x%"PRIx64
" offset_within_region=0x%"PRIx64
- " qemu_real_host_page_size=0x%"PRIxPTR,
- __func__, memory_region_name(section->mr),
+ " page_size=0x%"PRIxPTR ")",
+ memory_region_name(section->mr),
section->offset_within_address_space,
section->offset_within_region,
qemu_real_host_page_size());
+ } else {
+ trace_vfio_listener_region_misaligned(
+ memory_region_name(section->mr),
+ section->offset_within_address_space,
+ section->offset_within_region,
+ qemu_real_host_page_size());
}
return false;
}
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index bfdaf229e42b0d9d40e38c828c97cf47eb831a87..8cbad9ad0f3a4cbcbb3b5f00ac7afe392a821071 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -99,7 +99,7 @@ vfio_spapr_group_attach(int groupfd, int tablefd) "Attached groupfd %d to liobn
vfio_listener_region_add_iommu(const char* name, uint64_t start, uint64_t end) "region_add [iommu] %s 0x%"PRIx64" - 0x%"PRIx64
vfio_listener_region_del_iommu(const char *name) "region_del [iommu] %s"
vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]"
-vfio_known_safe_misalignment(const char *name, uint64_t iova, uint64_t offset_within_region, uintptr_t page_size) "Region \"%s\" iova=0x%"PRIx64" offset_within_region=0x%"PRIx64" qemu_real_host_page_size=0x%"PRIxPTR
+vfio_listener_region_misaligned(const char *name, uint64_t iova, uint64_t offset_within_region, uintptr_t page_size) "Region \"%s\" iova=0x%"PRIx64" offset_within_region=0x%"PRIx64" qemu_real_host_page_size=0x%"PRIxPTR
vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint64_t size, uint64_t page_size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" is not aligned to 0x%"PRIx64" and cannot be mapped for DMA"
vfio_listener_region_skip_dma_map(const char *name, uint64_t iova, uint64_t size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" marked to skip IOMMU mapping"
vfio_listener_region_del(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64
--
2.54.0
next reply other threads:[~2026-07-08 13:36 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-08 13:36 Cédric Le Goater [this message]
2026-07-08 15:06 ` [PATCH v2] vfio/listener: Replace misalignment whitelist with DMA capability check Alex Williamson
2026-07-08 15:20 ` Cédric Le Goater
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=20260708133604.1606448-1-clg@redhat.com \
--to=clg@redhat.com \
--cc=alex@shazbot.org \
--cc=eric.auger@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.