Move mshv_prepare_pinned_region() from mshv_root_main.c to mshv_regions.c and rename it to mshv_map_pinned_region(). This co-locates the pinned region logic with the rest of the memory region operations.
Make mshv_region_pin(), mshv_region_map(), mshv_region_share(), mshv_region_unshare(), and mshv_region_invalidate() static, as they are no longer called outside of mshv_regions.c. Also fix a bug in the error handling where a mshv_region_map() failure on a non-encrypted partition would be silently ignored, returning success instead of propagating the error code. Signed-off-by: Stanislav Kinsburskii <[email protected]> --- drivers/hv/mshv_regions.c | 79 ++++++++++++++++++++++++++++++++++++++++--- drivers/hv/mshv_root.h | 6 +-- drivers/hv/mshv_root_main.c | 70 +------------------------------------- 3 files changed, 76 insertions(+), 79 deletions(-) diff --git a/drivers/hv/mshv_regions.c b/drivers/hv/mshv_regions.c index 1bb1bfe177e2..133ec7771812 100644 --- a/drivers/hv/mshv_regions.c +++ b/drivers/hv/mshv_regions.c @@ -287,7 +287,7 @@ static int mshv_region_chunk_share(struct mshv_mem_region *region, flags, true); } -int mshv_region_share(struct mshv_mem_region *region) +static int mshv_region_share(struct mshv_mem_region *region) { u32 flags = HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_SHARED; @@ -313,7 +313,7 @@ static int mshv_region_chunk_unshare(struct mshv_mem_region *region, flags, false); } -int mshv_region_unshare(struct mshv_mem_region *region) +static int mshv_region_unshare(struct mshv_mem_region *region) { u32 flags = HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_EXCLUSIVE; @@ -353,7 +353,7 @@ static int mshv_region_remap_pfns(struct mshv_mem_region *region, mshv_region_chunk_remap); } -int mshv_region_map(struct mshv_mem_region *region) +static int mshv_region_map(struct mshv_mem_region *region) { u32 map_flags = region->hv_map_flags; @@ -377,12 +377,12 @@ static void mshv_region_invalidate_pfns(struct mshv_mem_region *region, } } -void mshv_region_invalidate(struct mshv_mem_region *region) +static void mshv_region_invalidate(struct mshv_mem_region *region) { mshv_region_invalidate_pfns(region, 0, region->nr_pfns); } -int mshv_region_pin(struct mshv_mem_region *region) +static int mshv_region_pin(struct mshv_mem_region *region) { u64 done_count, nr_pfns, i; unsigned long *pfns; @@ -731,3 +731,72 @@ bool mshv_region_movable_init(struct mshv_mem_region *region) return true; } + +/** + * mshv_map_pinned_region - Pin and map memory regions + * @region: Pointer to the memory region structure + * + * This function processes memory regions that are explicitly marked as pinned. + * Pinned regions are preallocated, mapped upfront, and do not rely on fault-based + * population. The function ensures the region is properly populated, handles + * encryption requirements for SNP partitions if applicable, maps the region, + * and performs necessary sharing or eviction operations based on the mapping + * result. + * + * Return: 0 on success, negative error code on failure. + */ +int mshv_map_pinned_region(struct mshv_mem_region *region) +{ + struct mshv_partition *partition = region->partition; + int ret; + + ret = mshv_region_pin(region); + if (ret) { + pt_err(partition, "Failed to pin memory region: %d\n", + ret); + goto err_out; + } + + /* + * For an SNP partition it is a requirement that for every memory region + * that we are going to map for this partition we should make sure that + * host access to that region is released. This is ensured by doing an + * additional hypercall which will update the SLAT to release host + * access to guest memory regions. + */ + if (mshv_partition_encrypted(partition)) { + ret = mshv_region_unshare(region); + if (ret) { + pt_err(partition, + "Failed to unshare memory region (guest_pfn: %llu): %d\n", + region->start_gfn, ret); + goto invalidate_region; + } + } + + ret = mshv_region_map(region); + if (!ret) + return 0; + + if (mshv_partition_encrypted(partition)) { + int shrc; + + shrc = mshv_region_share(region); + if (!shrc) + goto invalidate_region; + + pt_err(partition, + "Failed to share memory region (guest_pfn: %llu): %d\n", + region->start_gfn, shrc); + /* + * Don't unpin if marking shared failed because pages are no + * longer mapped in the host, ie root, anymore. + */ + goto err_out; + } + +invalidate_region: + mshv_region_invalidate(region); +err_out: + return ret; +} diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h index f1d4bee97a3f..d2e65a137bf4 100644 --- a/drivers/hv/mshv_root.h +++ b/drivers/hv/mshv_root.h @@ -368,15 +368,11 @@ extern u8 * __percpu *hv_synic_eventring_tail; struct mshv_mem_region *mshv_region_create(u64 guest_pfn, u64 nr_pages, u64 uaddr, u32 flags); -int mshv_region_share(struct mshv_mem_region *region); -int mshv_region_unshare(struct mshv_mem_region *region); -int mshv_region_map(struct mshv_mem_region *region); -void mshv_region_invalidate(struct mshv_mem_region *region); -int mshv_region_pin(struct mshv_mem_region *region); void mshv_region_put(struct mshv_mem_region *region); int mshv_region_get(struct mshv_mem_region *region); bool mshv_region_handle_gfn_fault(struct mshv_mem_region *region, u64 gfn); void mshv_region_movable_fini(struct mshv_mem_region *region); bool mshv_region_movable_init(struct mshv_mem_region *region); +int mshv_map_pinned_region(struct mshv_mem_region *region); #endif /* _MSHV_ROOT_H_ */ diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c index 685e4b562186..c393b5144e0b 100644 --- a/drivers/hv/mshv_root_main.c +++ b/drivers/hv/mshv_root_main.c @@ -1254,74 +1254,6 @@ static int mshv_partition_create_region(struct mshv_partition *partition, return 0; } -/** - * mshv_prepare_pinned_region - Pin and map memory regions - * @region: Pointer to the memory region structure - * - * This function processes memory regions that are explicitly marked as pinned. - * Pinned regions are preallocated, mapped upfront, and do not rely on fault-based - * population. The function ensures the region is properly populated, handles - * encryption requirements for SNP partitions if applicable, maps the region, - * and performs necessary sharing or eviction operations based on the mapping - * result. - * - * Return: 0 on success, negative error code on failure. - */ -static int mshv_prepare_pinned_region(struct mshv_mem_region *region) -{ - struct mshv_partition *partition = region->partition; - int ret; - - ret = mshv_region_pin(region); - if (ret) { - pt_err(partition, "Failed to pin memory region: %d\n", - ret); - goto err_out; - } - - /* - * For an SNP partition it is a requirement that for every memory region - * that we are going to map for this partition we should make sure that - * host access to that region is released. This is ensured by doing an - * additional hypercall which will update the SLAT to release host - * access to guest memory regions. - */ - if (mshv_partition_encrypted(partition)) { - ret = mshv_region_unshare(region); - if (ret) { - pt_err(partition, - "Failed to unshare memory region (guest_pfn: %llu): %d\n", - region->start_gfn, ret); - goto invalidate_region; - } - } - - ret = mshv_region_map(region); - if (ret && mshv_partition_encrypted(partition)) { - int shrc; - - shrc = mshv_region_share(region); - if (!shrc) - goto invalidate_region; - - pt_err(partition, - "Failed to share memory region (guest_pfn: %llu): %d\n", - region->start_gfn, shrc); - /* - * Don't unpin if marking shared failed because pages are no - * longer mapped in the host, ie root, anymore. - */ - goto err_out; - } - - return 0; - -invalidate_region: - mshv_region_invalidate(region); -err_out: - return ret; -} - /* * This maps two things: guest RAM and for pci passthru mmio space. * @@ -1364,7 +1296,7 @@ mshv_map_user_memory(struct mshv_partition *partition, switch (region->mreg_type) { case MSHV_REGION_TYPE_MEM_PINNED: - ret = mshv_prepare_pinned_region(region); + ret = mshv_map_pinned_region(region); break; case MSHV_REGION_TYPE_MEM_MOVABLE: /*

