From: Stanislav Kinsburskii <[email protected]> Sent: Tuesday,
March 3, 2026 4:24 PM
>
> Deposit enough pages upfront to avoid partition initialization failures due
> to low memory. This also speeds up partition initialization.
>
> Move page depositing from the hypercall wrapper to the partition
> initialization code. The required number of pages is empirical. This logic
> fits better in the partition initialization code than in the hypercall
> wrapper.
>
> A partition with nested capability requires 40x more pages (20 MB) to
> accommodate the nested MSHV hypervisor. This may be improved in the future.
>
> Signed-off-by: Stanislav Kinsburskii <[email protected]>
> ---
> drivers/hv/mshv_root.h | 1 +
> drivers/hv/mshv_root_hv_call.c | 6 ------
> drivers/hv/mshv_root_main.c | 23 +++++++++++++++++++++--
> 3 files changed, 22 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
> index 947dfb76bb19..40cf7bdbd62f 100644
> --- a/drivers/hv/mshv_root.h
> +++ b/drivers/hv/mshv_root.h
> @@ -106,6 +106,7 @@ struct mshv_partition {
>
> struct hlist_node pt_hnode;
> u64 pt_id;
> + u64 pt_flags;
> refcount_t pt_ref_count;
> struct mutex pt_mutex;
>
> diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
> index bdcb8de7fb47..b8d199f95299 100644
> --- a/drivers/hv/mshv_root_hv_call.c
> +++ b/drivers/hv/mshv_root_hv_call.c
> @@ -15,7 +15,6 @@
> #include "mshv_root.h"
>
> /* Determined empirically */
I think the above comment applies to HV_INIT_PARTITION_DEPOSIT_PAGES
(not to HV_UMAP_GPA_PAGES) and should be removed.
> -#define HV_INIT_PARTITION_DEPOSIT_PAGES 208
> #define HV_UMAP_GPA_PAGES 512
>
> #define HV_PAGE_COUNT_2M_ALIGNED(pg_count) (!((pg_count) & (0x200 - 1)))
> @@ -139,11 +138,6 @@ int hv_call_initialize_partition(u64 partition_id)
>
> input.partition_id = partition_id;
>
> - ret = hv_call_deposit_pages(NUMA_NO_NODE, partition_id,
> - HV_INIT_PARTITION_DEPOSIT_PAGES);
> - if (ret)
> - return ret;
> -
> do {
> status = hv_do_fast_hypercall8(HVCALL_INITIALIZE_PARTITION,
> *(u64 *)&input);
> diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
> index d753f41d3b57..fbfc50de332c 100644
> --- a/drivers/hv/mshv_root_main.c
> +++ b/drivers/hv/mshv_root_main.c
> @@ -35,6 +35,10 @@
> #include "mshv.h"
> #include "mshv_root.h"
>
> +/* The deposit values below are empirical and may need to be adjusted. */
> +#define MSHV_PARTITION_DEPOSIT_PAGES (SZ_512K >> PAGE_SHIFT)
> +#define MSHV_PARTITION_DEPOSIT_PAGES_NESTED (20 * SZ_1M >> PAGE_SHIFT)
Nit: The placement of these #defines *above* the MODULE_* notations seems
a bit odd to me.
> +
> MODULE_AUTHOR("Microsoft");
> MODULE_LICENSE("GPL");
> MODULE_DESCRIPTION("Microsoft Hyper-V root partition VMM interface
> /dev/mshv");
> @@ -1587,6 +1591,15 @@ mshv_partition_ioctl_set_msi_routing(struct
> mshv_partition *partition,
> return ret;
> }
>
> +static u64
> +mshv_partition_deposit_pages(struct mshv_partition *partition)
Nit: This function name makes it seem like it will "deposit pages". Maybe
mshv_partition_get_deposit_cnt(), or something similar, would be better?
> +{
> + if (partition->pt_flags &
> + HV_PARTITION_CREATION_FLAG_NESTED_VIRTUALIZATION_CAPABLE)
> + return MSHV_PARTITION_DEPOSIT_PAGES_NESTED;
> + return MSHV_PARTITION_DEPOSIT_PAGES;
> +}
> +
> static long
> mshv_partition_ioctl_initialize(struct mshv_partition *partition)
> {
> @@ -1595,6 +1608,11 @@ mshv_partition_ioctl_initialize(struct mshv_partition
> *partition)
> if (partition->pt_initialized)
> return 0;
>
> + ret = hv_call_deposit_pages(NUMA_NO_NODE, partition->pt_id,
> + mshv_partition_deposit_pages(partition));
> + if (ret)
> + goto withdraw_mem;
> +
> ret = hv_call_initialize_partition(partition->pt_id);
> if (ret)
> goto withdraw_mem;
> @@ -1610,8 +1628,8 @@ mshv_partition_ioctl_initialize(struct mshv_partition
> *partition)
> finalize_partition:
> hv_call_finalize_partition(partition->pt_id);
> withdraw_mem:
> - hv_call_withdraw_memory(U64_MAX, NUMA_NO_NODE, partition->pt_id);
> -
> + hv_call_withdraw_memory(MSHV_PARTITION_DEPOSIT_PAGES,
> + NUMA_NO_NODE, partition->pt_id);
What's the strategy here for withdrawing memory after a failure? As I noted in
Patch 1 of the series, there's no way to know how many pages were deposited.
Might have been zero, or significantly more than MSHV_PARTITION_DEPOSIT_PAGES.
And in Patches 3 and 4 of the series, there's no attempt to withdraw pages if
hv_call_deposit_pages() fails, which seems inconsistent.
> return ret;
> }
>
> @@ -2032,6 +2050,7 @@ mshv_ioctl_create_partition(void __user *user_arg,
> struct device *module_dev)
> return -ENOMEM;
>
> partition->pt_module_dev = module_dev;
> + partition->pt_flags = creation_flags;
> partition->isolation_type = isolation_properties.isolation_type;
>
> refcount_set(&partition->pt_ref_count, 1);
>
>