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

* Re: [PATCH v2] vfio/listener: Replace misalignment whitelist with DMA capability check
  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
  0 siblings, 1 reply; 3+ messages in thread
From: Alex Williamson @ 2026-07-08 15:06 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: qemu-devel, qemu-arm, Eric Auger, Peter Maydell, alex

On Wed,  8 Jul 2026 15:36:04 +0200
Cédric Le Goater <clg@redhat.com> wrote:

> 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.

Arguable as we have exactly one class of device so far that's validated
as safe.

> 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.

But it's the composition into the address space and how that address
space is defined to the guest that matters.  Imagine a minimum counter
example to the test presented here, a page-size range of RAM in the VM
is composed by a device as two contiguous sub-page MemoryRegions.  We
only see the individual MRs here, they're each sub-page, the shape
suggests they're not DMA targets, but together they map contiguously
into the VM address space.  KVM can trap and emulate them as normal
RAM.  QEMU emulated devices can DMA to them as RAM.  VFIO cannot map
them through the IOMMU.

That is what this test is meant to validate.  The judgment that the
control register range for a TPM device presented as a RAM MR is not a
meaningful DMA target for a vfio device is the thing that cannot be
determined based only on the shape of the MR.

> This removes the TPM CRB dependency from the VFIO listener and
> eliminates the need for per-device whitelisting entirely.

And removes the diagnostic it provided.  Thanks,

Alex


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

* Re: [PATCH v2] vfio/listener: Replace misalignment whitelist with DMA capability check
  2026-07-08 15:06 ` Alex Williamson
@ 2026-07-08 15:20   ` Cédric Le Goater
  0 siblings, 0 replies; 3+ messages in thread
From: Cédric Le Goater @ 2026-07-08 15:20 UTC (permalink / raw)
  To: Alex Williamson; +Cc: qemu-devel, qemu-arm, Eric Auger, Peter Maydell

On 7/8/26 17:06, Alex Williamson wrote:
> On Wed,  8 Jul 2026 15:36:04 +0200
> Cédric Le Goater <clg@redhat.com> wrote:
> 
>> 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.
> 
> Arguable as we have exactly one class of device so far that's validated
> as safe.
> 
>> 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.
> 
> But it's the composition into the address space and how that address
> space is defined to the guest that matters.  Imagine a minimum counter
> example to the test presented here, a page-size range of RAM in the VM
> is composed by a device as two contiguous sub-page MemoryRegions.  We
> only see the individual MRs here, they're each sub-page, the shape
> suggests they're not DMA targets, but together they map contiguously
> into the VM address space.  KVM can trap and emulate them as normal
> RAM.  QEMU emulated devices can DMA to them as RAM.  VFIO cannot map
> them through the IOMMU.
> 
> That is what this test is meant to validate.  The judgment that the
> control register range for a TPM device presented as a RAM MR is not a
> meaningful DMA target for a vfio device is the thing that cannot be
> determined based only on the shape of the MR.

ok. I understand. this is difficult to address cleanly without a
white list then. Which is what "Extend safe misalignment check to
tpm-ppi region" proposes. I will let it cool down.

This change is not critical. It is part of a broader effort to
avoid giving users the wrong impression that the problem comes
from VFIO when analyzing diagnostic logs with errors/warnings
spread across the system. This is not the only VFIO message in
this category.
C.



^ permalink raw reply	[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.