From: Nuno Das Neves <nudas...@microsoft.com>

These are not specific to x86_64 and will be needed by common code.

Signed-off-by: Nuno Das Neves <nudas...@microsoft.com>
---
 arch/x86/hyperv/hv_proc.c       | 144 -------------------------------
 arch/x86/include/asm/mshyperv.h |   2 -
 drivers/hv/hv_common.c          | 145 ++++++++++++++++++++++++++++++++
 include/asm-generic/mshyperv.h  |   2 +
 4 files changed, 147 insertions(+), 146 deletions(-)

diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 3fa1f2ee7b0d..119354d00637 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -10,109 +10,8 @@
 #include <asm/hypervisor.h>
 #include <asm/mshyperv.h>
 #include <asm/apic.h>
-
 #include <asm/trace/hyperv.h>
 
-/*
- * See struct hv_deposit_memory. The first u64 is partition ID, the rest
- * are GPAs.
- */
-#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)
-{
-       struct page **pages, *page;
-       int *counts;
-       int num_allocations;
-       int i, j, page_count;
-       int order;
-       u64 status;
-       int ret;
-       u64 base_pfn;
-       struct hv_deposit_memory *input_page;
-       unsigned long flags;
-
-       if (num_pages > HV_DEPOSIT_MAX)
-               return -E2BIG;
-       if (!num_pages)
-               return 0;
-
-       /* One buffer for page pointers and counts */
-       page = alloc_page(GFP_KERNEL);
-       if (!page)
-               return -ENOMEM;
-       pages = page_address(page);
-
-       counts = kcalloc(HV_DEPOSIT_MAX, sizeof(int), GFP_KERNEL);
-       if (!counts) {
-               free_page((unsigned long)pages);
-               return -ENOMEM;
-       }
-
-       /* Allocate all the pages before disabling interrupts */
-       i = 0;
-
-       while (num_pages) {
-               /* Find highest order we can actually allocate */
-               order = 31 - __builtin_clz(num_pages);
-
-               while (1) {
-                       pages[i] = alloc_pages_node(node, GFP_KERNEL, order);
-                       if (pages[i])
-                               break;
-                       if (!order) {
-                               ret = -ENOMEM;
-                               num_allocations = i;
-                               goto err_free_allocations;
-                       }
-                       --order;
-               }
-
-               split_page(pages[i], order);
-               counts[i] = 1 << order;
-               num_pages -= counts[i];
-               i++;
-       }
-       num_allocations = i;
-
-       local_irq_save(flags);
-
-       input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
-
-       input_page->partition_id = partition_id;
-
-       /* Populate gpa_page_list - these will fit on the input page */
-       for (i = 0, page_count = 0; i < num_allocations; ++i) {
-               base_pfn = page_to_pfn(pages[i]);
-               for (j = 0; j < counts[i]; ++j, ++page_count)
-                       input_page->gpa_page_list[page_count] = base_pfn + j;
-       }
-       status = hv_do_rep_hypercall(HVCALL_DEPOSIT_MEMORY,
-                                    page_count, 0, input_page, NULL);
-       local_irq_restore(flags);
-       if (!hv_result_success(status)) {
-               pr_err("Failed to deposit pages: %lld\n", status);
-               ret = hv_result(status);
-               goto err_free_allocations;
-       }
-
-       ret = 0;
-       goto free_buf;
-
-err_free_allocations:
-       for (i = 0; i < num_allocations; ++i) {
-               base_pfn = page_to_pfn(pages[i]);
-               for (j = 0; j < counts[i]; ++j)
-                       __free_page(pfn_to_page(base_pfn + j));
-       }
-
-free_buf:
-       free_page((unsigned long)pages);
-       kfree(counts);
-       return ret;
-}
-
 int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id)
 {
        struct hv_input_add_logical_processor *input;
@@ -154,46 +53,3 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
        return ret;
 }
 
-int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
-{
-       struct hv_create_vp *input;
-       u64 status;
-       unsigned long irq_flags;
-       int ret = HV_STATUS_SUCCESS;
-
-       /* Root VPs don't seem to need pages deposited */
-       if (partition_id != hv_current_partition_id) {
-               /* The value 90 is empirically determined. It may change. */
-               ret = hv_call_deposit_pages(node, partition_id, 90);
-               if (ret)
-                       return ret;
-       }
-
-       do {
-               local_irq_save(irq_flags);
-
-               input = *this_cpu_ptr(hyperv_pcpu_input_arg);
-
-               input->partition_id = partition_id;
-               input->vp_index = vp_index;
-               input->flags = flags;
-               input->subnode_type = HvSubnodeAny;
-               input->proximity_domain_info = hv_numa_node_to_pxm_info(node);
-               status = hv_do_hypercall(HVCALL_CREATE_VP, input, NULL);
-               local_irq_restore(irq_flags);
-
-               if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
-                       if (!hv_result_success(status)) {
-                               pr_err("%s: vcpu %u, lp %u, %lld\n", __func__,
-                                      vp_index, flags, status);
-                               ret = hv_result(status);
-                       }
-                       break;
-               }
-               ret = hv_call_deposit_pages(node, partition_id, 1);
-
-       } while (!ret);
-
-       return ret;
-}
-
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 9eeca2a6d047..5bad88cfccba 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -57,9 +57,7 @@ u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
 #define HV_AP_INIT_GPAT_DEFAULT                0x0007040600070406ULL
 #define HV_AP_SEGMENT_LIMIT            0xffffffff
 
-int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
 int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);
-int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
 
 /*
  * If the hypercall involves no input or output parameters, the hypervisor
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 819bcfd2b149..591cc51e8817 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -679,3 +679,148 @@ u64 __weak hv_tdx_hypercall(u64 control, u64 param1, u64 
param2)
        return HV_STATUS_INVALID_PARAMETER;
 }
 EXPORT_SYMBOL_GPL(hv_tdx_hypercall);
+
+int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
+{
+       struct hv_create_vp *input;
+       u64 status;
+       unsigned long irq_flags;
+       int ret = HV_STATUS_SUCCESS;
+
+       /* Root VPs don't seem to need pages deposited */
+       if (partition_id != hv_current_partition_id) {
+               /* The value 90 is empirically determined. It may change. */
+               ret = hv_call_deposit_pages(node, partition_id, 90);
+               if (ret)
+                       return ret;
+       }
+
+       do {
+               local_irq_save(irq_flags);
+
+               input = *this_cpu_ptr(hyperv_pcpu_input_arg);
+
+               input->partition_id = partition_id;
+               input->vp_index = vp_index;
+               input->flags = flags;
+               input->subnode_type = HvSubnodeAny;
+               input->proximity_domain_info = hv_numa_node_to_pxm_info(node);
+               status = hv_do_hypercall(HVCALL_CREATE_VP, input, NULL);
+               local_irq_restore(irq_flags);
+
+               if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
+                       if (!hv_result_success(status)) {
+                               pr_err("%s: vcpu %u, lp %u, %lld\n", __func__,
+                                      vp_index, flags, status);
+                               ret = hv_result(status);
+                       }
+                       break;
+               }
+               ret = hv_call_deposit_pages(node, partition_id, 1);
+
+       } while (!ret);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(hv_call_create_vp);
+
+/*
+ * See struct hv_deposit_memory. The first u64 is partition ID, the rest
+ * are GPAs.
+ */
+#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)
+{
+       struct page **pages, *page;
+       int *counts;
+       int num_allocations;
+       int i, j, page_count;
+       int order;
+       u64 status;
+       int ret;
+       u64 base_pfn;
+       struct hv_deposit_memory *input_page;
+       unsigned long flags;
+
+       if (num_pages > HV_DEPOSIT_MAX)
+               return -E2BIG;
+       if (!num_pages)
+               return 0;
+
+       /* One buffer for page pointers and counts */
+       page = alloc_page(GFP_KERNEL);
+       if (!page)
+               return -ENOMEM;
+       pages = page_address(page);
+
+       counts = kcalloc(HV_DEPOSIT_MAX, sizeof(int), GFP_KERNEL);
+       if (!counts) {
+               free_page((unsigned long)pages);
+               return -ENOMEM;
+       }
+
+       /* Allocate all the pages before disabling interrupts */
+       i = 0;
+
+       while (num_pages) {
+               /* Find highest order we can actually allocate */
+               order = 31 - __builtin_clz(num_pages);
+
+               while (1) {
+                       pages[i] = alloc_pages_node(node, GFP_KERNEL, order);
+                       if (pages[i])
+                               break;
+                       if (!order) {
+                               ret = -ENOMEM;
+                               num_allocations = i;
+                               goto err_free_allocations;
+                       }
+                       --order;
+               }
+
+               split_page(pages[i], order);
+               counts[i] = 1 << order;
+               num_pages -= counts[i];
+               i++;
+       }
+       num_allocations = i;
+
+       local_irq_save(flags);
+
+       input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
+
+       input_page->partition_id = partition_id;
+
+       /* Populate gpa_page_list - these will fit on the input page */
+       for (i = 0, page_count = 0; i < num_allocations; ++i) {
+               base_pfn = page_to_pfn(pages[i]);
+               for (j = 0; j < counts[i]; ++j, ++page_count)
+                       input_page->gpa_page_list[page_count] = base_pfn + j;
+       }
+       status = hv_do_rep_hypercall(HVCALL_DEPOSIT_MEMORY,
+                                    page_count, 0, input_page, NULL);
+       local_irq_restore(flags);
+       if (!hv_result_success(status)) {
+               pr_err("Failed to deposit pages: %lld\n", status);
+               ret = hv_result(status);
+               goto err_free_allocations;
+       }
+
+       ret = 0;
+       goto free_buf;
+
+err_free_allocations:
+       for (i = 0; i < num_allocations; ++i) {
+               base_pfn = page_to_pfn(pages[i]);
+               for (j = 0; j < counts[i]; ++j)
+                       __free_page(pfn_to_page(base_pfn + j));
+       }
+
+free_buf:
+       free_page((unsigned long)pages);
+       kfree(counts);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(hv_call_deposit_pages);
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 8c4ff6e9aae7..46c0a6cae4e6 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -305,6 +305,8 @@ u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
 void hyperv_cleanup(void);
 bool hv_query_ext_cap(u64 cap_query);
 void hv_setup_dma_ops(struct device *dev, bool coherent);
+int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
+int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
 #else /* CONFIG_HYPERV */
 static inline bool hv_is_hyperv_initialized(void) { return false; }
 static inline bool hv_is_hibernation_supported(void) { return false; }
-- 
2.34.1


Reply via email to