[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200914112802.80611-7-wei.liu@kernel.org>
Date: Mon, 14 Sep 2020 11:27:50 +0000
From: Wei Liu <wei.liu@...nel.org>
To: Linux on Hyper-V List <linux-hyperv@...r.kernel.org>
Cc: virtualization@...ts.linux-foundation.org,
Linux Kernel List <linux-kernel@...r.kernel.org>,
Michael Kelley <mikelley@...rosoft.com>,
Vineeth Pillai <viremana@...ux.microsoft.com>,
Sunil Muthuswamy <sunilmut@...rosoft.com>,
Nuno Das Neves <nudasnev@...rosoft.com>,
Wei Liu <wei.liu@...nel.org>,
Lillian Grassin-Drake <ligrassi@...rosoft.com>,
"K. Y. Srinivasan" <kys@...rosoft.com>,
Haiyang Zhang <haiyangz@...rosoft.com>,
Stephen Hemminger <sthemmin@...rosoft.com>,
Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
x86@...nel.org (maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)),
"H. Peter Anvin" <hpa@...or.com>
Subject: [PATCH RFC v1 06/18] x86/hyperv: allocate output arg pages if required
When Linux runs as the root partition, it will need to make hypercalls
which return data from the hypervisor.
Allocate pages for storing results when Linux runs as the root
partition.
Signed-off-by: Lillian Grassin-Drake <ligrassi@...rosoft.com>
Co-Developed-by: Lillian Grassin-Drake <ligrassi@...rosoft.com>
Signed-off-by: Wei Liu <wei.liu@...nel.org>
---
arch/x86/hyperv/hv_init.c | 45 +++++++++++++++++++++++++++++----
arch/x86/include/asm/mshyperv.h | 1 +
2 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index cac8e4c56261..ebba4be4185d 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -45,6 +45,9 @@ EXPORT_SYMBOL_GPL(hv_vp_assist_page);
void __percpu **hyperv_pcpu_input_arg;
EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
+void __percpu **hyperv_pcpu_output_arg;
+EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg);
+
u32 hv_max_vp_index;
EXPORT_SYMBOL_GPL(hv_max_vp_index);
@@ -75,14 +78,29 @@ static int hv_cpu_init(unsigned int cpu)
u64 msr_vp_index;
struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()];
void **input_arg;
- struct page *pg;
+ struct page *input_pg;
input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
/* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
- pg = alloc_page(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
- if (unlikely(!pg))
+ input_pg = alloc_page(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+ if (unlikely(!input_pg))
return -ENOMEM;
- *input_arg = page_address(pg);
+ *input_arg = page_address(input_pg);
+
+ if (hv_root_partition) {
+ struct page *output_pg;
+ void **output_arg;
+
+ output_pg = alloc_page(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+ if (unlikely(!output_pg)) {
+ free_page((unsigned long)*input_arg);
+ *input_arg = NULL;
+ return -ENOMEM;
+ }
+
+ output_arg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg);
+ *output_arg = page_address(output_pg);
+ }
hv_get_vp_index(msr_vp_index);
@@ -209,14 +227,25 @@ static int hv_cpu_die(unsigned int cpu)
unsigned int new_cpu;
unsigned long flags;
void **input_arg;
- void *input_pg = NULL;
+ void *input_pg = NULL, *output_pg = NULL;
local_irq_save(flags);
input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
input_pg = *input_arg;
*input_arg = NULL;
+
+ if (hv_root_partition) {
+ void **output_arg;
+
+ output_arg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg);
+ output_pg = *output_arg;
+ *output_arg = NULL;
+ }
+
local_irq_restore(flags);
+
free_page((unsigned long)input_pg);
+ free_page((unsigned long)output_pg);
if (hv_vp_assist_page && hv_vp_assist_page[cpu])
wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, 0);
@@ -350,6 +379,12 @@ void __init hyperv_init(void)
BUG_ON(hyperv_pcpu_input_arg == NULL);
+ /* Allocate the per-CPU state for output arg for root */
+ if (hv_root_partition) {
+ hyperv_pcpu_output_arg = alloc_percpu(void *);
+ BUG_ON(hyperv_pcpu_output_arg == NULL);
+ }
+
/* Allocate percpu VP index */
hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index),
GFP_KERNEL);
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 2a2cc81beac6..f5c62140f28d 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -63,6 +63,7 @@ static inline void hv_disable_stimer0_percpu_irq(int irq) {}
#if IS_ENABLED(CONFIG_HYPERV)
extern void *hv_hypercall_pg;
extern void __percpu **hyperv_pcpu_input_arg;
+extern void __percpu **hyperv_pcpu_output_arg;
static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
{
--
2.20.1
Powered by blists - more mailing lists