hw/vfio/device.c | 2 +- hw/vfio/listener.c | 33 +++++++++++++++------------------ hw/vfio/trace-events | 2 +- 3 files changed, 17 insertions(+), 20 deletions(-)
Any device on the board can have non-page-aligned memory regions. The
VFIO listener should not warn about misalignment for regions that are
not VFIO-related.
Replace the vfio_known_safe_misalignment() whitelist with a
vfio_get_vfio_device() ownership check: only warn when a VFIO device's
own region is misaligned. For all other regions, emit a trace event
and silently skip. Extract the misalignment test into a
vfio_section_misaligned() helper for readability.
Note: vfio_get_vfio_device() currently only covers VFIO PCI devices,
including vfio-user-pci. Other VFIO backends (AP, CCW) don't expose
memory regions through this path so this is sufficient for now.
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
hw/vfio/device.c | 2 +-
hw/vfio/listener.c | 33 +++++++++++++++------------------
hw/vfio/trace-events | 2 +-
3 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/hw/vfio/device.c b/hw/vfio/device.c
index 1a7f8088aad9583ee96fc303be917fdb2f100df9..3a47109efb35c6dc28719dcc19acb85bef1d26cd 100644
--- a/hw/vfio/device.c
+++ b/hw/vfio/device.c
@@ -439,7 +439,7 @@ bool vfio_device_hiod_create_and_realize(VFIODevice *vbasedev,
VFIODevice *vfio_get_vfio_device(Object *obj)
{
- if (object_dynamic_cast(obj, TYPE_VFIO_PCI)) {
+ if (object_dynamic_cast(obj, TYPE_VFIO_PCI_DEVICE)) {
return &VFIO_PCI_DEVICE(obj)->vbasedev;
} else {
return NULL;
diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
index c19600e980a8d02217b5d9df4aca8f879ab2c5d5..76b9b02f8163f18d20994e4ec1f914a4d148fa92 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,10 @@ 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;
- }
-
- /* 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;
+ return (section->offset_within_address_space & ~qemu_real_host_page_mask()) !=
+ (section->offset_within_region & ~qemu_real_host_page_mask());
}
static bool vfio_listener_valid_section(MemoryRegionSection *section,
@@ -379,10 +368,12 @@ 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)) {
+ if (unlikely(vfio_section_misaligned(section))) {
+ /*
+ * Only warn for VFIO device regions. Other VFIO backends
+ * (AP, CCW) don't expose memory regions through this path.
+ */
+ if (vfio_get_vfio_device(memory_region_owner(section->mr))) {
error_report("%s received unaligned region %s iova=0x%"PRIx64
" offset_within_region=0x%"PRIx64
" qemu_real_host_page_size=0x%"PRIxPTR,
@@ -390,6 +381,12 @@ static bool vfio_listener_valid_section(MemoryRegionSection *section,
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 f71d0bbc0a5440e4ccd374fac4733af08438e7be..5056b9942027938cd6bc832198acc9809739399f 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -98,7 +98,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
On Thu, 2 Jul 2026 18:06:40 +0200
Cédric Le Goater <clg@redhat.com> wrote:
> Any device on the board can have non-page-aligned memory regions. The
> VFIO listener should not warn about misalignment for regions that are
> not VFIO-related.
>
> Replace the vfio_known_safe_misalignment() whitelist with a
> vfio_get_vfio_device() ownership check: only warn when a VFIO device's
> own region is misaligned. For all other regions, emit a trace event
> and silently skip. Extract the misalignment test into a
> vfio_section_misaligned() helper for readability.
>
> Note: vfio_get_vfio_device() currently only covers VFIO PCI devices,
> including vfio-user-pci. Other VFIO backends (AP, CCW) don't expose
> memory regions through this path so this is sufficient for now.
I thought the whole point was to warn when there are non-vfio devices
that we cannot insert into the DMA map. 851d6d1a0ff2 added tpm-crb-cmd
to an ignore list because it's not a DMA target. The intention of that
ignore list was to continue to evaluate devices that are misaligned
and either add them to the ignore list or determine they could be a
valid DMA target and correct the alignment.
Can this even legitimately trigger with a vfio-pci device? Thanks,
Alex
>
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Cédric Le Goater <clg@redhat.com>
> ---
> hw/vfio/device.c | 2 +-
> hw/vfio/listener.c | 33 +++++++++++++++------------------
> hw/vfio/trace-events | 2 +-
> 3 files changed, 17 insertions(+), 20 deletions(-)
>
> diff --git a/hw/vfio/device.c b/hw/vfio/device.c
> index 1a7f8088aad9583ee96fc303be917fdb2f100df9..3a47109efb35c6dc28719dcc19acb85bef1d26cd 100644
> --- a/hw/vfio/device.c
> +++ b/hw/vfio/device.c
> @@ -439,7 +439,7 @@ bool vfio_device_hiod_create_and_realize(VFIODevice *vbasedev,
>
> VFIODevice *vfio_get_vfio_device(Object *obj)
> {
> - if (object_dynamic_cast(obj, TYPE_VFIO_PCI)) {
> + if (object_dynamic_cast(obj, TYPE_VFIO_PCI_DEVICE)) {
> return &VFIO_PCI_DEVICE(obj)->vbasedev;
> } else {
> return NULL;
> diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
> index c19600e980a8d02217b5d9df4aca8f879ab2c5d5..76b9b02f8163f18d20994e4ec1f914a4d148fa92 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,10 @@ 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;
> - }
> -
> - /* 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;
> + return (section->offset_within_address_space & ~qemu_real_host_page_mask()) !=
> + (section->offset_within_region & ~qemu_real_host_page_mask());
> }
>
> static bool vfio_listener_valid_section(MemoryRegionSection *section,
> @@ -379,10 +368,12 @@ 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)) {
> + if (unlikely(vfio_section_misaligned(section))) {
> + /*
> + * Only warn for VFIO device regions. Other VFIO backends
> + * (AP, CCW) don't expose memory regions through this path.
> + */
> + if (vfio_get_vfio_device(memory_region_owner(section->mr))) {
> error_report("%s received unaligned region %s iova=0x%"PRIx64
> " offset_within_region=0x%"PRIx64
> " qemu_real_host_page_size=0x%"PRIxPTR,
> @@ -390,6 +381,12 @@ static bool vfio_listener_valid_section(MemoryRegionSection *section,
> 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 f71d0bbc0a5440e4ccd374fac4733af08438e7be..5056b9942027938cd6bc832198acc9809739399f 100644
> --- a/hw/vfio/trace-events
> +++ b/hw/vfio/trace-events
> @@ -98,7 +98,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
On 7/6/26 16:20, Alex Williamson wrote:
> On Thu, 2 Jul 2026 18:06:40 +0200
> Cédric Le Goater <clg@redhat.com> wrote:
>
>> Any device on the board can have non-page-aligned memory regions. The
>> VFIO listener should not warn about misalignment for regions that are
>> not VFIO-related.
>>
>> Replace the vfio_known_safe_misalignment() whitelist with a
>> vfio_get_vfio_device() ownership check: only warn when a VFIO device's
>> own region is misaligned. For all other regions, emit a trace event
>> and silently skip. Extract the misalignment test into a
>> vfio_section_misaligned() helper for readability.
>>
>> Note: vfio_get_vfio_device() currently only covers VFIO PCI devices,
>> including vfio-user-pci. Other VFIO backends (AP, CCW) don't expose
>> memory regions through this path so this is sufficient for now.
>
> I thought the whole point was to warn when there are non-vfio devices
> that we cannot insert into the DMA map. 851d6d1a0ff2 added tpm-crb-cmd
> to an ignore list because it's not a DMA target. The intention of that
> ignore list was to continue to evaluate devices that are misaligned
> and either add them to the ignore list or determine they could be a
> valid DMA target and correct the alignment.
If the goal was to use the VFIO listener to catch all misaligned regions,
and potentially fix them, we should reconsider that approach :
https://lore.kernel.org/qemu-devel/20260701080843.2418461-1-clg@redhat.com/
As Peter pointed out, regions that are not page-aligned regions are valid :
https://lore.kernel.org/qemu-devel/CAFEAcA-QHJ=HaBc5WSLLap8NdDw+tty4EFfGt6cmmNOK6e_m7w@mail.gmail.com/
and aligning them would require a machine compat for migration.
Not addressed in :
https://lore.kernel.org/qemu-devel/20260630173245.2070268-1-clg@redhat.com/
> Can this even legitimately trigger with a vfio-pci device?
This would be a real error to report. Right ?
Thanks,
C.
> Thanks,
>
> Alex
>
>>
>> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
>> Signed-off-by: Cédric Le Goater <clg@redhat.com>
>> ---
>> hw/vfio/device.c | 2 +-
>> hw/vfio/listener.c | 33 +++++++++++++++------------------
>> hw/vfio/trace-events | 2 +-
>> 3 files changed, 17 insertions(+), 20 deletions(-)
>>
>> diff --git a/hw/vfio/device.c b/hw/vfio/device.c
>> index 1a7f8088aad9583ee96fc303be917fdb2f100df9..3a47109efb35c6dc28719dcc19acb85bef1d26cd 100644
>> --- a/hw/vfio/device.c
>> +++ b/hw/vfio/device.c
>> @@ -439,7 +439,7 @@ bool vfio_device_hiod_create_and_realize(VFIODevice *vbasedev,
>>
>> VFIODevice *vfio_get_vfio_device(Object *obj)
>> {
>> - if (object_dynamic_cast(obj, TYPE_VFIO_PCI)) {
>> + if (object_dynamic_cast(obj, TYPE_VFIO_PCI_DEVICE)) {
>> return &VFIO_PCI_DEVICE(obj)->vbasedev;
>> } else {
>> return NULL;
>> diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
>> index c19600e980a8d02217b5d9df4aca8f879ab2c5d5..76b9b02f8163f18d20994e4ec1f914a4d148fa92 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,10 @@ 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;
>> - }
>> -
>> - /* 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;
>> + return (section->offset_within_address_space & ~qemu_real_host_page_mask()) !=
>> + (section->offset_within_region & ~qemu_real_host_page_mask());
>> }
>>
>> static bool vfio_listener_valid_section(MemoryRegionSection *section,
>> @@ -379,10 +368,12 @@ 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)) {
>> + if (unlikely(vfio_section_misaligned(section))) {
>> + /*
>> + * Only warn for VFIO device regions. Other VFIO backends
>> + * (AP, CCW) don't expose memory regions through this path.
>> + */
>> + if (vfio_get_vfio_device(memory_region_owner(section->mr))) {
>> error_report("%s received unaligned region %s iova=0x%"PRIx64
>> " offset_within_region=0x%"PRIx64
>> " qemu_real_host_page_size=0x%"PRIxPTR,
>> @@ -390,6 +381,12 @@ static bool vfio_listener_valid_section(MemoryRegionSection *section,
>> 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 f71d0bbc0a5440e4ccd374fac4733af08438e7be..5056b9942027938cd6bc832198acc9809739399f 100644
>> --- a/hw/vfio/trace-events
>> +++ b/hw/vfio/trace-events
>> @@ -98,7 +98,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
>
On Mon, 6 Jul 2026 17:12:07 +0200 Cédric Le Goater <clg@redhat.com> wrote: > On 7/6/26 16:20, Alex Williamson wrote: > > On Thu, 2 Jul 2026 18:06:40 +0200 > > Cédric Le Goater <clg@redhat.com> wrote: > > > >> Any device on the board can have non-page-aligned memory regions. The > >> VFIO listener should not warn about misalignment for regions that are > >> not VFIO-related. > >> > >> Replace the vfio_known_safe_misalignment() whitelist with a > >> vfio_get_vfio_device() ownership check: only warn when a VFIO device's > >> own region is misaligned. For all other regions, emit a trace event > >> and silently skip. Extract the misalignment test into a > >> vfio_section_misaligned() helper for readability. > >> > >> Note: vfio_get_vfio_device() currently only covers VFIO PCI devices, > >> including vfio-user-pci. Other VFIO backends (AP, CCW) don't expose > >> memory regions through this path so this is sufficient for now. > > > > I thought the whole point was to warn when there are non-vfio devices > > that we cannot insert into the DMA map. 851d6d1a0ff2 added tpm-crb-cmd > > to an ignore list because it's not a DMA target. The intention of that > > ignore list was to continue to evaluate devices that are misaligned > > and either add them to the ignore list or determine they could be a > > valid DMA target and correct the alignment. > > If the goal was to use the VFIO listener to catch all misaligned regions, > and potentially fix them, we should reconsider that approach : > > https://lore.kernel.org/qemu-devel/20260701080843.2418461-1-clg@redhat.com/ Arguably ok, likely no tpm device is a useful DMA target. > As Peter pointed out, regions that are not page-aligned regions are valid : > > https://lore.kernel.org/qemu-devel/CAFEAcA-QHJ=HaBc5WSLLap8NdDw+tty4EFfGt6cmmNOK6e_m7w@mail.gmail.com/ Yes, they are valid, no argument. We're trying to DMA map things. We can't DMA map things that aren't page-aligned and sized. If it's not likely a DMA target, well, that's the purpose of the ignore list. If it might be a DMA target, this is intended to log why the VM may not work correctly vs bare metal. > and aligning them would require a machine compat for migration. > Not addressed in : > > https://lore.kernel.org/qemu-devel/20260630173245.2070268-1-clg@redhat.com/ Which I think highlights why we might rather see warnings than bury the issue in traces. > > Can this even legitimately trigger with a vfio-pci device? > > This would be a real error to report. Right ? I suspect it's not possible, so as proposed here we're turning a blind eye to the issue we intended to monitor and validate, and we replace it with likely dead code. Thanks, Alex
On Mon, 6 Jul 2026 at 16:12, Cédric Le Goater <clg@redhat.com> wrote: > > On 7/6/26 16:20, Alex Williamson wrote: > > On Thu, 2 Jul 2026 18:06:40 +0200 > > Cédric Le Goater <clg@redhat.com> wrote: > > > >> Any device on the board can have non-page-aligned memory regions. The > >> VFIO listener should not warn about misalignment for regions that are > >> not VFIO-related. > >> > >> Replace the vfio_known_safe_misalignment() whitelist with a > >> vfio_get_vfio_device() ownership check: only warn when a VFIO device's > >> own region is misaligned. For all other regions, emit a trace event > >> and silently skip. Extract the misalignment test into a > >> vfio_section_misaligned() helper for readability. > >> > >> Note: vfio_get_vfio_device() currently only covers VFIO PCI devices, > >> including vfio-user-pci. Other VFIO backends (AP, CCW) don't expose > >> memory regions through this path so this is sufficient for now. > > > > I thought the whole point was to warn when there are non-vfio devices > > that we cannot insert into the DMA map. 851d6d1a0ff2 added tpm-crb-cmd > > to an ignore list because it's not a DMA target. The intention of that > > ignore list was to continue to evaluate devices that are misaligned > > and either add them to the ignore list or determine they could be a > > valid DMA target and correct the alignment. > > If the goal was to use the VFIO listener to catch all misaligned regions, > and potentially fix them, we should reconsider that approach : > > https://lore.kernel.org/qemu-devel/20260701080843.2418461-1-clg@redhat.com/ > > As Peter pointed out, regions that are not page-aligned regions are valid : > > https://lore.kernel.org/qemu-devel/CAFEAcA-QHJ=HaBc5WSLLap8NdDw+tty4EFfGt6cmmNOK6e_m7w@mail.gmail.com/ > > and aligning them would require a machine compat for migration. It seems very unlikely that anything not page-aligned is going to be a sensible target for DMA ops from a device: the main reason to have a non-page-aligned or non-page-sized region is that it's the way we've chosen to implement a device, or it's some "RAM but not general-purpose RAM" thing. If there's a path to warn/error if it's actually used for a DMA op that would be worthwhile, but as it stands I think all this warning will ever cause us to do is add more entries to its whitelist every time it complains. thanks -- PMM
On Mon, 6 Jul 2026 16:27:46 +0100 Peter Maydell <peter.maydell@linaro.org> wrote: > On Mon, 6 Jul 2026 at 16:12, Cédric Le Goater <clg@redhat.com> wrote: > > > > On 7/6/26 16:20, Alex Williamson wrote: > > > On Thu, 2 Jul 2026 18:06:40 +0200 > > > Cédric Le Goater <clg@redhat.com> wrote: > > > > > >> Any device on the board can have non-page-aligned memory regions. The > > >> VFIO listener should not warn about misalignment for regions that are > > >> not VFIO-related. > > >> > > >> Replace the vfio_known_safe_misalignment() whitelist with a > > >> vfio_get_vfio_device() ownership check: only warn when a VFIO device's > > >> own region is misaligned. For all other regions, emit a trace event > > >> and silently skip. Extract the misalignment test into a > > >> vfio_section_misaligned() helper for readability. > > >> > > >> Note: vfio_get_vfio_device() currently only covers VFIO PCI devices, > > >> including vfio-user-pci. Other VFIO backends (AP, CCW) don't expose > > >> memory regions through this path so this is sufficient for now. > > > > > > I thought the whole point was to warn when there are non-vfio devices > > > that we cannot insert into the DMA map. 851d6d1a0ff2 added tpm-crb-cmd > > > to an ignore list because it's not a DMA target. The intention of that > > > ignore list was to continue to evaluate devices that are misaligned > > > and either add them to the ignore list or determine they could be a > > > valid DMA target and correct the alignment. > > > > If the goal was to use the VFIO listener to catch all misaligned regions, > > and potentially fix them, we should reconsider that approach : > > > > https://lore.kernel.org/qemu-devel/20260701080843.2418461-1-clg@redhat.com/ > > > > As Peter pointed out, regions that are not page-aligned regions are valid : > > > > https://lore.kernel.org/qemu-devel/CAFEAcA-QHJ=HaBc5WSLLap8NdDw+tty4EFfGt6cmmNOK6e_m7w@mail.gmail.com/ > > > > and aligning them would require a machine compat for migration. > > It seems very unlikely that anything not page-aligned is going > to be a sensible target for DMA ops from a device: the main > reason to have a non-page-aligned or non-page-sized region is that > it's the way we've chosen to implement a device, or it's some > "RAM but not general-purpose RAM" thing. If there's a path to > warn/error if it's actually used for a DMA op that would be worthwhile, But for a vfio-pci device there is no DMA op, it either gets mapped into the IOMMU for direct access to the device or not. This is the point at which that decision is made. > but as it stands I think all this warning will ever cause us to > do is add more entries to its whitelist every time it complains. IMO, that's ok. That's the purpose. We're up to one whole class of device so far, we don't care about mapping failures to TPM devices. If some day this does fire on something we care about, especially a regression, it'll earn its keep. It doesn't seem like an excessive burden yet. Thanks, Alex
On Mon, 6 Jul 2026 at 16:42, Alex Williamson <alex@shazbot.org> wrote: > > On Mon, 6 Jul 2026 16:27:46 +0100 > Peter Maydell <peter.maydell@linaro.org> wrote: > > It seems very unlikely that anything not page-aligned is going > > to be a sensible target for DMA ops from a device: the main > > reason to have a non-page-aligned or non-page-sized region is that > > it's the way we've chosen to implement a device, or it's some > > "RAM but not general-purpose RAM" thing. If there's a path to > > warn/error if it's actually used for a DMA op that would be worthwhile, > > But for a vfio-pci device there is no DMA op, it either gets mapped > into the IOMMU for direct access to the device or not. This is the > point at which that decision is made. Why is small RAM different from MMIO register regions here? Those also you're not going to be able to have a device do direct memory access to. > > but as it stands I think all this warning will ever cause us to > > do is add more entries to its whitelist every time it complains. > > IMO, that's ok. That's the purpose. We're up to one whole class of > device so far, we don't care about mapping failures to TPM devices. If > some day this does fire on something we care about, especially a > regression, it'll earn its keep. It doesn't seem like an excessive > burden yet. Thanks, The reason we're having this conversation is because it just fired again, and the warning gives the impression that the right thing to do is to somehow change the misaligned memory region, not to add something to the whitelist. That's already wasted several people's time. You could add a comment saying /* * If this warning ever fires, then it will almost certainly * be because of a legitimately non-aligned RAM-backed * MemoryRegion that needs adding to the whitelist. */ But I think that it would be much better just to dump the warning, so we don't have to keep doing this. thanks -- PMM
On Mon, 6 Jul 2026 17:12:35 +0100 Peter Maydell <peter.maydell@linaro.org> wrote: > On Mon, 6 Jul 2026 at 16:42, Alex Williamson <alex@shazbot.org> wrote: > > > > On Mon, 6 Jul 2026 16:27:46 +0100 > > Peter Maydell <peter.maydell@linaro.org> wrote: > > > It seems very unlikely that anything not page-aligned is going > > > to be a sensible target for DMA ops from a device: the main > > > reason to have a non-page-aligned or non-page-sized region is that > > > it's the way we've chosen to implement a device, or it's some > > > "RAM but not general-purpose RAM" thing. If there's a path to > > > warn/error if it's actually used for a DMA op that would be worthwhile, > > > > But for a vfio-pci device there is no DMA op, it either gets mapped > > into the IOMMU for direct access to the device or not. This is the > > point at which that decision is made. > > Why is small RAM different from MMIO register regions here? > Those also you're not going to be able to have a device do > direct memory access to. There's a precedent for bare metal, peer-to-peer DMA is less reliable and drivers don't typically have blind faith in it working. Peer-to-peer DMA also has specific use cases, drivers don't arbitrarily pick a peer device to DMA to, they have specific use cases and target regions are inherently sized and aligned appropriately. Here we have RAM and we're trying to determine whether it's RAM that could be allocated as a DMA buffer or expect a DMA access from a device. Commit 851d6d1a0ff2 spelled out that we could have declared these sorts of regions as RAM device, solving the problem with a simple test, but that wasn't well received (for reasons I don't remember), so we were forced to create this mechanism and maintenance issue. > > > but as it stands I think all this warning will ever cause us to > > > do is add more entries to its whitelist every time it complains. > > > > IMO, that's ok. That's the purpose. We're up to one whole class of > > device so far, we don't care about mapping failures to TPM devices. If > > some day this does fire on something we care about, especially a > > regression, it'll earn its keep. It doesn't seem like an excessive > > burden yet. Thanks, > > The reason we're having this conversation is because it just fired > again, and the warning gives the impression that the right thing > to do is to somehow change the misaligned memory region, not to > add something to the whitelist. That's already wasted several > people's time. Since being introduced 4 years ago, we've iterated on one class of device. It doesn't feel like there's a persistent time sink here. > You could add a comment saying > > /* > * If this warning ever fires, then it will almost certainly > * be because of a legitimately non-aligned RAM-backed > * MemoryRegion that needs adding to the whitelist. > */ Personally I'd start with the error log itself, providing a hint that the region is presented as RAM but isn't sized/aligned for DMA from a vfio device, with a hint to mark it as safe if it is legitimately not a valid DMA target. Thanks, Alex
On Mon, 6 Jul 2026 at 18:16, Alex Williamson <alex@shazbot.org> wrote: > > On Mon, 6 Jul 2026 17:12:35 +0100 > Peter Maydell <peter.maydell@linaro.org> wrote: > > > On Mon, 6 Jul 2026 at 16:42, Alex Williamson <alex@shazbot.org> wrote: > > > > > > On Mon, 6 Jul 2026 16:27:46 +0100 > > > Peter Maydell <peter.maydell@linaro.org> wrote: > > > > It seems very unlikely that anything not page-aligned is going > > > > to be a sensible target for DMA ops from a device: the main > > > > reason to have a non-page-aligned or non-page-sized region is that > > > > it's the way we've chosen to implement a device, or it's some > > > > "RAM but not general-purpose RAM" thing. If there's a path to > > > > warn/error if it's actually used for a DMA op that would be worthwhile, > > > > > > But for a vfio-pci device there is no DMA op, it either gets mapped > > > into the IOMMU for direct access to the device or not. This is the > > > point at which that decision is made. > > > > Why is small RAM different from MMIO register regions here? > > Those also you're not going to be able to have a device do > > direct memory access to. > > There's a precedent for bare metal, peer-to-peer DMA is less reliable > and drivers don't typically have blind faith in it working. > Peer-to-peer DMA also has specific use cases, drivers don't arbitrarily > pick a peer device to DMA to, they have specific use cases and target > regions are inherently sized and aligned appropriately. Sure, but if a guest does try it then it's going to fall over. This is exactly the same as if it tries to do DMA to a small MemoryRegion that we happen to have implemented as backed by RAM rather than MMIO functions. In both cases the QEMU implementation of the device is fine, and the guest has done something silly. > Here we have RAM and we're trying to determine whether it's RAM that > could be allocated as a DMA buffer or expect a DMA access from a > device. I think that there are no examples of memory-backed MemoryRegions that aren't page-aligned that are going to expect a DMA access. So a reasonable proxy test for "is this RAM that could expect a DMA access" is "is it page aligned and at least a page in size?". All blocks of real for-the-guest RAM will satisfy that. > Commit 851d6d1a0ff2 spelled out that we could have declared these sorts > of regions as RAM device, solving the problem with a simple test, but > that wasn't well received (for reasons I don't remember), so we were > forced to create this mechanism and maintenance issue. Isn't a RAM device for "this MemoryRegion is backed by memory from some actual host hardware device"? In this case it is not, so not a good fit. But either way, if the RAM-device MR is not page aligned then the guest can't DMA to it either. So "is this a RAM device or not" doesn't seem like the test you want for whether you want to flag a problem. thanks -- PMM
Hello !
On 7/2/26 18:06, Cédric Le Goater wrote:
> Any device on the board can have non-page-aligned memory regions. The
> VFIO listener should not warn about misalignment for regions that are
> not VFIO-related.
>
> Replace the vfio_known_safe_misalignment() whitelist with a
> vfio_get_vfio_device() ownership check: only warn when a VFIO device's
> own region is misaligned. For all other regions, emit a trace event
> and silently skip. Extract the misalignment test into a
> vfio_section_misaligned() helper for readability.
>
> Note: vfio_get_vfio_device() currently only covers VFIO PCI devices,
> including vfio-user-pci. Other VFIO backends (AP, CCW) don't expose
> memory regions through this path so this is sufficient for now.
>
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Cédric Le Goater <clg@redhat.com>
> ---
> hw/vfio/device.c | 2 +-
> hw/vfio/listener.c | 33 +++++++++++++++------------------
> hw/vfio/trace-events | 2 +-
> 3 files changed, 17 insertions(+), 20 deletions(-)
Could someone please take a look and Ack this change (or not :) ?
Thanks,
C.
>
> diff --git a/hw/vfio/device.c b/hw/vfio/device.c
> index 1a7f8088aad9583ee96fc303be917fdb2f100df9..3a47109efb35c6dc28719dcc19acb85bef1d26cd 100644
> --- a/hw/vfio/device.c
> +++ b/hw/vfio/device.c
> @@ -439,7 +439,7 @@ bool vfio_device_hiod_create_and_realize(VFIODevice *vbasedev,
>
> VFIODevice *vfio_get_vfio_device(Object *obj)
> {
> - if (object_dynamic_cast(obj, TYPE_VFIO_PCI)) {
> + if (object_dynamic_cast(obj, TYPE_VFIO_PCI_DEVICE)) {
> return &VFIO_PCI_DEVICE(obj)->vbasedev;
> } else {
> return NULL;
> diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
> index c19600e980a8d02217b5d9df4aca8f879ab2c5d5..76b9b02f8163f18d20994e4ec1f914a4d148fa92 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,10 @@ 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;
> - }
> -
> - /* 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;
> + return (section->offset_within_address_space & ~qemu_real_host_page_mask()) !=
> + (section->offset_within_region & ~qemu_real_host_page_mask());
> }
>
> static bool vfio_listener_valid_section(MemoryRegionSection *section,
> @@ -379,10 +368,12 @@ 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)) {
> + if (unlikely(vfio_section_misaligned(section))) {
> + /*
> + * Only warn for VFIO device regions. Other VFIO backends
> + * (AP, CCW) don't expose memory regions through this path.
> + */
> + if (vfio_get_vfio_device(memory_region_owner(section->mr))) {
> error_report("%s received unaligned region %s iova=0x%"PRIx64
> " offset_within_region=0x%"PRIx64
> " qemu_real_host_page_size=0x%"PRIxPTR,
> @@ -390,6 +381,12 @@ static bool vfio_listener_valid_section(MemoryRegionSection *section,
> 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 f71d0bbc0a5440e4ccd374fac4733af08438e7be..5056b9942027938cd6bc832198acc9809739399f 100644
> --- a/hw/vfio/trace-events
> +++ b/hw/vfio/trace-events
> @@ -98,7 +98,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
© 2016 - 2026 Red Hat, Inc.