@@ -883,11 +883,13 @@ static int vfio_setup_region_sparse_mmaps(VFIORegion *region,
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);
+ sparse->areas[i].size,
+ sparse->areas[i].disablable);
if (sparse->areas[i].size) {
region->mmaps[j].offset = sparse->areas[i].offset;
region->mmaps[j].size = sparse->areas[i].size;
+ region->mmaps[j].disablable = sparse->areas[i].disablable;
j++;
}
}
@@ -1084,6 +1086,30 @@ void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled)
enabled);
}
+/**
+ * enable/disable vfio regions with mmaped subregions
+ * It only disable mmapped subregions with disablable flag on
+ */
+void vfio_region_disablable_mmaps_set_enabled(VFIORegion *region, bool enabled)
+{
+ int i;
+
+ if (!region->mem) {
+ return;
+ }
+
+ for (i = 0; i < region->nr_mmaps; i++) {
+ if (region->mmaps[i].mmap && region->mmaps[i].disablable) {
+ memory_region_set_enabled(®ion->mmaps[i].mem, enabled);
+ trace_vfio_region_disablable_mmaps_set_enabled(
+ memory_region_name(region->mem),
+ region->mmaps[i].offset,
+ region->mmaps[i].offset + region->mmaps[i].size,
+ enabled);
+ }
+ }
+}
+
void vfio_reset_handler(void *opaque)
{
VFIOGroup *group;
@@ -113,7 +113,7 @@ vfio_region_finalize(const char *name, int index) "Device %s, region %d"
vfio_region_mmaps_set_enabled(const char *name, bool enabled) "Region %s mmaps enabled: %d"
vfio_region_unmap(const char *name, unsigned long offset, unsigned long end) "Region %s unmap [0x%lx - 0x%lx]"
vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) "Device %s region %d: %d sparse mmap entries"
-vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) "sparse entry %d [0x%lx - 0x%lx]"
+vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end, bool disablable) "sparse entry %d [0x%lx - 0x%lx] disablable %d"
vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%0x8"
vfio_dma_unmap_overflow_workaround(void) ""
@@ -161,3 +161,4 @@ vfio_load_device_config_state(char *name) " (%s)"
vfio_load_state(char *name, uint64_t data) " (%s) data 0x%"PRIx64
vfio_load_state_device_data(char *name, uint64_t data_offset, uint64_t data_size) " (%s) Offset 0x%"PRIx64" size 0x%"PRIx64
vfio_get_dirty_page_list(char *name, uint64_t start, uint64_t pfn_count, uint64_t page_size) " (%s) start 0x%"PRIx64" pfn_count 0x%"PRIx64 " page size 0x%"PRIx64
+vfio_region_disablable_mmaps_set_enabled(const char *name, unsigned long offset, unsigned long end, bool enabled) "Region %s mmaps [0x%lx - 0x%lx] set to %d"
@@ -45,6 +45,7 @@ typedef struct VFIOMmap {
void *mmap;
off_t offset;
size_t size;
+ bool disablable; /* whether this region is able to get diabled */
} VFIOMmap;
typedef struct VFIORegion {
@@ -187,6 +188,7 @@ int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region,
int index, const char *name);
int vfio_region_mmap(VFIORegion *region);
void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled);
+void vfio_region_disablable_mmaps_set_enabled(VFIORegion *region, bool enabled);
void vfio_region_unmap(VFIORegion *region);
void vfio_region_exit(VFIORegion *region);
void vfio_region_finalize(VFIORegion *region);
@@ -258,6 +258,8 @@ struct vfio_region_info {
struct vfio_region_sparse_mmap_area {
__u64 offset; /* Offset of mmap'able area within region */
__u64 size; /* Size of mmap'able area */
+ __u32 disablable; /* whether this mmap'able are able to
+ be dynamically disbled */
};
struct vfio_region_info_cap_sparse_mmap {
add a 'disablable' flag to each each sparse mmaped region and this flag is by default off. vfio_region_disablable_mmaps_set_enabled() will enable/disable mmapped subregions if its 'disablable' flag is on. Cc: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Yan Zhao <yan.y.zhao@intel.com> --- hw/vfio/common.c | 28 +++++++++++++++++++++++++++- hw/vfio/trace-events | 3 ++- include/hw/vfio/vfio-common.h | 2 ++ linux-headers/linux/vfio.h | 2 ++ 4 files changed, 33 insertions(+), 2 deletions(-)