[PATCH 09/15] Drivers: hv: Introduce hv_output_arg_exists in hv_common

From: Nuno Das Neves
Date: Thu Jul 27 2023 - 15:55:38 EST


This is a more flexible approach for determining whether to allocate the
output page.
This will be used in both mshv_vtl and root partition.

Signed-off-by: Nuno Das Neves <nunodasneves@xxxxxxxxxxxxxxxxxxx>
---
drivers/hv/hv_common.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 99d9b262b8a7..16f069beda78 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -57,6 +57,18 @@ EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
void * __percpu *hyperv_pcpu_output_arg;
EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg);

+/*
+ * Determine whether output arg is in use, for allocation/deallocation
+ */
+static bool hv_output_arg_exists(void)
+{
+ bool ret = hv_root_partition ? true : false;
+#ifdef CONFIG_MSHV_VTL
+ ret = true;
+#endif
+ return ret;
+}
+
static void hv_kmsg_dump_unregister(void);

static struct ctl_table_header *hv_ctl_table_hdr;
@@ -338,10 +350,12 @@ int __init hv_common_init(void)
hyperv_pcpu_input_arg = alloc_percpu(void *);
BUG_ON(!hyperv_pcpu_input_arg);

- /* Allocate the per-CPU state for output arg for root */
- if (hv_root_partition) {
+ if (hv_output_arg_exists()) {
hyperv_pcpu_output_arg = alloc_percpu(void *);
BUG_ON(!hyperv_pcpu_output_arg);
+ }
+
+ if (hv_root_partition) {
hv_synic_eventring_tail = alloc_percpu(u8 *);
BUG_ON(hv_synic_eventring_tail == NULL);
}
@@ -371,7 +385,7 @@ int hv_common_cpu_init(unsigned int cpu)
u8 **synic_eventring_tail;
u64 msr_vp_index;
gfp_t flags;
- int pgcount = hv_root_partition ? 2 : 1;
+ int pgcount = hv_output_arg_exists() ? 2 : 1;

/* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
flags = irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL;
@@ -381,9 +395,12 @@ int hv_common_cpu_init(unsigned int cpu)
if (!(*inputarg))
return -ENOMEM;

- if (hv_root_partition) {
+ if (hv_output_arg_exists()) {
outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg);
*outputarg = (char *)(*inputarg) + HV_HYP_PAGE_SIZE;
+ }
+
+ if (hv_root_partition) {
synic_eventring_tail = (u8 **)this_cpu_ptr(hv_synic_eventring_tail);
*synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT, sizeof(u8),
flags);
@@ -417,9 +434,12 @@ int hv_common_cpu_die(unsigned int cpu)
mem = *inputarg;
*inputarg = NULL;

- if (hv_root_partition) {
+ if (hv_output_arg_exists()) {
outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg);
*outputarg = NULL;
+ }
+
+ if (hv_root_partition) {
synic_eventring_tail = (u8 **)this_cpu_ptr(hv_synic_eventring_tail);
kfree(*synic_eventring_tail);
*synic_eventring_tail = NULL;
--
2.25.1