From: Nuno Das Neves <[email protected]> Sent: Thursday, November 6, 2025 2:14 PM > > The current check is incorrect; it only checks if the beginning or end > of a region is within an existing region. This doesn't account for > userspace specifying a region that begins before and ends after an > existing region. > > Change the logic to a range intersection check against gfns and uaddrs > for each region. > > Remove mshv_partition_region_by_uaddr() as it is no longer used. > > Fixes: 621191d709b1 ("Drivers: hv: Introduce mshv_root module to expose > /dev/mshv to VMMs") > Reported-by: Michael Kelley <[email protected]> > Closes: > https://lore.kernel.org/linux-hyperv/sn6pr02mb41575be0406d3ab22e1d7db5d4...@sn6pr02mb4157.namprd02.prod.outlook.com/ > Signed-off-by: Nuno Das Neves <[email protected]> > --- > drivers/hv/mshv_root_main.c | 31 +++++++++++-------------------- > 1 file changed, 11 insertions(+), 20 deletions(-) > > diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c > index 814465a0912d..25a68912a78d 100644 > --- a/drivers/hv/mshv_root_main.c > +++ b/drivers/hv/mshv_root_main.c > @@ -1206,21 +1206,6 @@ mshv_partition_region_by_gfn(struct mshv_partition > *partition, u64 gfn) > return NULL; > } > > -static struct mshv_mem_region * > -mshv_partition_region_by_uaddr(struct mshv_partition *partition, u64 uaddr) > -{ > - struct mshv_mem_region *region; > - > - hlist_for_each_entry(region, &partition->pt_mem_regions, hnode) { > - if (uaddr >= region->start_uaddr && > - uaddr < region->start_uaddr + > - (region->nr_pages << HV_HYP_PAGE_SHIFT)) > - return region; > - } > - > - return NULL; > -} > - > /* > * NB: caller checks and makes sure mem->size is page aligned > * Returns: 0 with regionpp updated on success, or -errno > @@ -1230,15 +1215,21 @@ static int mshv_partition_create_region(struct > mshv_partition *partition, > struct mshv_mem_region **regionpp, > bool is_mmio) > { > - struct mshv_mem_region *region; > + struct mshv_mem_region *region, *rg; > u64 nr_pages = HVPFN_DOWN(mem->size); > > /* Reject overlapping regions */ > - if (mshv_partition_region_by_gfn(partition, mem->guest_pfn) || > - mshv_partition_region_by_gfn(partition, mem->guest_pfn + nr_pages - > 1) || > - mshv_partition_region_by_uaddr(partition, mem->userspace_addr) || > - mshv_partition_region_by_uaddr(partition, mem->userspace_addr + > mem->size - 1)) > + hlist_for_each_entry(rg, &partition->pt_mem_regions, hnode) { > + u64 rg_size = rg->nr_pages << HV_HYP_PAGE_SHIFT; > + > + if ((mem->guest_pfn + nr_pages <= rg->start_gfn || > + rg->start_gfn + rg->nr_pages <= mem->guest_pfn) && > + (mem->userspace_addr + mem->size <= rg->start_uaddr || > + rg->start_uaddr + rg_size <= mem->userspace_addr)) > + continue; > + > return -EEXIST; > + } > > region = vzalloc(sizeof(*region) + sizeof(struct page *) * nr_pages); > if (!region) > -- > 2.34.1
Reviewed-by: Michael Kelley <[email protected]>
