All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] vfio/listener: Replace misalignment whitelist with DMA capability check
@ 2026-07-08 13:36 Cédric Le Goater
  2026-07-08 15:06 ` Alex Williamson
  0 siblings, 1 reply; 3+ messages in thread
From: Cédric Le Goater @ 2026-07-08 13:36 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: Alex Williamson, Eric Auger, Cédric Le Goater, Peter Maydell

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



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-08 15:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-08 13:36 [PATCH v2] vfio/listener: Replace misalignment whitelist with DMA capability check Cédric Le Goater
2026-07-08 15:06 ` Alex Williamson
2026-07-08 15:20   ` Cédric Le Goater

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.