Convert hv_call_deposit_pages() into a wrapper supporting arbitrary number of pages, and use it in the memory deposit code paths.
Signed-off-by: Stanislav Kinsburskii <[email protected]> --- drivers/hv/hv_proc.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/hv/hv_proc.c b/drivers/hv/hv_proc.c index 5f4fd9c3231c..0f84a70def30 100644 --- a/drivers/hv/hv_proc.c +++ b/drivers/hv/hv_proc.c @@ -16,7 +16,7 @@ #define HV_DEPOSIT_MAX (HV_HYP_PAGE_SIZE / sizeof(u64) - 1) /* Deposits exact number of pages. Must be called with interrupts enabled. */ -int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages) +static int __hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages) { struct page **pages, *page; int *counts; @@ -108,6 +108,54 @@ int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages) kfree(counts); return ret; } + +/** + * hv_call_deposit_pages - Deposit memory pages to a partition + * @node : NUMA node from which to allocate pages + * @partition_id: Target partition ID to deposit pages to + * @num_pages : Number of pages to deposit + * + * Deposits memory pages to the specified partition. The deposit is + * performed in chunks of HV_DEPOSIT_MAX pages to handle large requests + * efficiently. + * + * Return: 0 on success, negative error code on failure + */ +int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages) +{ + u32 done; + int ret = 0; + + /* + * Do a double deposit for L1VH. This reserves enough memory for + * Hypervisor Hot Restart (HHR). + * + * During HHR, every data structure must be recreated in the new + * ("proto") hypervisor. Memory is required by the proto hypervisor + * to do this work. + * + * For regular L1 partitions, more memory can be requested from the + * root during HHR by sending an asynchronous message. But this is + * not supported for L1VHs. A guest must not be allowed to block + * HHR by refusing to deposit more memory. + * + * So for L1VH a deposit is always required for both current needs + * and future HHR work. + */ + if (hv_l1vh_partition()) + num_pages *= 2; + + for (done = 0; done < num_pages; done += HV_DEPOSIT_MAX) { + u32 to_deposit = min(num_pages - done, HV_DEPOSIT_MAX); + + ret = __hv_call_deposit_pages(node, partition_id, + to_deposit); + if (ret) + break; + } + + return ret; +} EXPORT_SYMBOL_GPL(hv_call_deposit_pages); int hv_deposit_memory_node(int node, u64 partition_id,

