Currently MMIO checks are done for ranges where memory_region_find() finds no regions within the entire range, or for cases where non-RAM/ROM regions at the beginning of the range. However, if the first region in the range is a normal RAM/ROM region, then the portion of the conversion range that overlaps the region is processed normally, but any MMIO holes that might be present at the beginning are ignored, so the checks are bypassed for those ranges. Plumb the 'start' GPA that was used to query memory_region_find(), and pass that into the MMIO-processing helper so that these gaps can be detected and MMIO checks can be applied appropriately. Fixes: c5d9425ef4da ("kvm/tdx: Don't complain when converting vMMIO region to shared") Signed-off-by: Michael Roth --- accel/kvm/kvm-all.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 62565a544d..463bbdadd2 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -3344,9 +3344,14 @@ static void kvm_eat_signals(CPUState *cpu) * non-RAM/ROM region that should be skipped as MMIO. In the latter case, the * 'skip' parameter will be set. Returns < 0 if the conversion request is not * valid. + * + * 'start' corresponds to the starting range memory_region_find() was + * called for, and is used to determine if there are any MMIO holes preceding + * the region passed in so the appropriate checks can be made on those + * ranges. */ static int handle_memory_hole(MemoryRegionSection *section, bool to_private, - bool *skip) + hwaddr start, bool *skip) { MemoryRegion *mr = section->mr; @@ -3391,6 +3396,15 @@ static int handle_memory_hole(MemoryRegionSection *section, bool to_private, } } + /* + * In this case the region should be processed as normal + * guest_memfd-backed RAM/ROM, but still need to check if there are + * preceding holes to apply the MMIO checks against. + */ + if (start < section->offset_within_address_space && to_private) { + return -EINVAL; + } + *skip = false; return 0; } @@ -3475,7 +3489,7 @@ int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private) assert(section_end > start); assert(section_end - start <= size); - ret = handle_memory_hole(§ion, to_private, &skip); + ret = handle_memory_hole(§ion, to_private, start, &skip); if (ret || skip) { memory_region_unref(section.mr); break; -- 2.43.0