summaryrefslogtreecommitdiffstats
path: root/hw/vfio/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/vfio/common.c')
-rw-r--r--hw/vfio/common.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 2b1f78fdfa..159f910421 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -40,6 +40,7 @@
#include "trace.h"
#include "qapi/error.h"
#include "migration/migration.h"
+#include "sysemu/tpm.h"
VFIOGroupList vfio_group_list =
QLIST_HEAD_INITIALIZER(vfio_group_list);
@@ -861,6 +862,22 @@ static void vfio_unregister_ram_discard_listener(VFIOContainer *container,
g_free(vrdl);
}
+static bool vfio_known_safe_misalignment(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;
+}
+
static void vfio_listener_region_add(MemoryListener *listener,
MemoryRegionSection *section)
{
@@ -884,7 +901,15 @@ static void vfio_listener_region_add(MemoryListener *listener,
if (unlikely((section->offset_within_address_space &
~qemu_real_host_page_mask()) !=
(section->offset_within_region & ~qemu_real_host_page_mask()))) {
- error_report("%s received unaligned region", __func__);
+ if (!vfio_known_safe_misalignment(section)) {
+ error_report("%s received unaligned region %s iova=0x%"PRIx64
+ " offset_within_region=0x%"PRIx64
+ " qemu_real_host_page_size=0x%"PRIxPTR,
+ __func__, memory_region_name(section->mr),
+ section->offset_within_address_space,
+ section->offset_within_region,
+ qemu_real_host_page_size());
+ }
return;
}
@@ -992,7 +1017,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
* device emulation the VFIO iommu handles to use).
*/
giommu = g_malloc0(sizeof(*giommu));
- giommu->iommu = iommu_mr;
+ giommu->iommu_mr = iommu_mr;
giommu->iommu_offset = section->offset_within_address_space -
section->offset_within_region;
giommu->container = container;
@@ -1007,7 +1032,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
int128_get64(llend),
iommu_idx);
- ret = memory_region_iommu_set_page_size_mask(giommu->iommu,
+ ret = memory_region_iommu_set_page_size_mask(giommu->iommu_mr,
container->pgsizes,
&err);
if (ret) {
@@ -1022,7 +1047,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
goto fail;
}
QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next);
- memory_region_iommu_replay(giommu->iommu, &giommu->n);
+ memory_region_iommu_replay(giommu->iommu_mr, &giommu->n);
return;
}
@@ -1128,7 +1153,7 @@ static void vfio_listener_region_del(MemoryListener *listener,
VFIOGuestIOMMU *giommu;
QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) {
- if (MEMORY_REGION(giommu->iommu) == section->mr &&
+ if (MEMORY_REGION(giommu->iommu_mr) == section->mr &&
giommu->n.start == section->offset_within_region) {
memory_region_unregister_iommu_notifier(section->mr,
&giommu->n);
@@ -1393,11 +1418,11 @@ static int vfio_sync_dirty_bitmap(VFIOContainer *container,
VFIOGuestIOMMU *giommu;
QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) {
- if (MEMORY_REGION(giommu->iommu) == section->mr &&
+ if (MEMORY_REGION(giommu->iommu_mr) == section->mr &&
giommu->n.start == section->offset_within_region) {
Int128 llend;
vfio_giommu_dirty_notifier gdn = { .giommu = giommu };
- int idx = memory_region_iommu_attrs_to_index(giommu->iommu,
+ int idx = memory_region_iommu_attrs_to_index(giommu->iommu_mr,
MEMTXATTRS_UNSPECIFIED);
llend = int128_add(int128_make64(section->offset_within_region),
@@ -1410,7 +1435,7 @@ static int vfio_sync_dirty_bitmap(VFIOContainer *container,
section->offset_within_region,
int128_get64(llend),
idx);
- memory_region_iommu_replay(giommu->iommu, &gdn.n);
+ memory_region_iommu_replay(giommu->iommu_mr, &gdn.n);
break;
}
}
@@ -1544,11 +1569,10 @@ static int vfio_setup_region_sparse_mmaps(VFIORegion *region,
region->mmaps = g_new0(VFIOMmap, sparse->nr_areas);
for (i = 0, j = 0; i < sparse->nr_areas; i++) {
- trace_vfio_region_sparse_mmap_entry(i, sparse->areas[i].offset,
- sparse->areas[i].offset +
- sparse->areas[i].size);
-
if (sparse->areas[i].size) {
+ trace_vfio_region_sparse_mmap_entry(i, sparse->areas[i].offset,
+ sparse->areas[i].offset +
+ sparse->areas[i].size - 1);
region->mmaps[j].offset = sparse->areas[i].offset;
region->mmaps[j].size = sparse->areas[i].size;
j++;
@@ -2246,7 +2270,7 @@ static void vfio_disconnect_container(VFIOGroup *group)
QLIST_FOREACH_SAFE(giommu, &container->giommu_list, giommu_next, tmp) {
memory_region_unregister_iommu_notifier(
- MEMORY_REGION(giommu->iommu), &giommu->n);
+ MEMORY_REGION(giommu->iommu_mr), &giommu->n);
QLIST_REMOVE(giommu, giommu_next);
g_free(giommu);
}