[v4,08/15] Drivers: hv: Introduce per-cpu event ring tail
Commit Message
Add a pointer hv_synic_eventring_tail to track the tail pointer for the
SynIC event ring buffer for each SINT.
This will be used by the mshv driver, but must be tracked independently
since the driver module could be removed and re-inserted.
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Wei Liu <wei.liu@kernel.org>
---
drivers/hv/hv_common.c | 28 ++++++++++++++++++++++++++--
include/asm-generic/mshyperv.h | 2 ++
2 files changed, 28 insertions(+), 2 deletions(-)
Comments
Hi Nuno,
kernel test robot noticed the following build warnings:
[auto build test WARNING on arnd-asm-generic/master]
[also build test WARNING on arm64/for-next/core linus/master v6.6-rc3 next-20230929]
[cannot apply to tip/x86/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Nuno-Das-Neves/hyperv-tlfs-Change-shared-HV_REGISTER_-defines-to-HV_MSR_/20230930-041305
base: https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master
patch link: https://lore.kernel.org/r/1696010501-24584-9-git-send-email-nunodasneves%40linux.microsoft.com
patch subject: [PATCH v4 08/15] Drivers: hv: Introduce per-cpu event ring tail
config: x86_64-randconfig-123-20230930 (https://download.01.org/0day-ci/archive/20230930/202309301948.CyCE3Y0P-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230930/202309301948.CyCE3Y0P-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309301948.CyCE3Y0P-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> drivers/hv/hv_common.c:98:21: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void [noderef] __percpu *__pdata @@ got unsigned char [noderef] [usertype] __percpu **extern [addressable] [toplevel] hv_synic_eventring_tail @@
drivers/hv/hv_common.c:98:21: sparse: expected void [noderef] __percpu *__pdata
drivers/hv/hv_common.c:98:21: sparse: got unsigned char [noderef] [usertype] __percpu **extern [addressable] [toplevel] hv_synic_eventring_tail
>> drivers/hv/hv_common.c:349:41: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected unsigned char [noderef] [usertype] __percpu **extern [addressable] [assigned] [toplevel] hv_synic_eventring_tail @@ got unsigned char [usertype] *[noderef] __percpu * @@
drivers/hv/hv_common.c:349:41: sparse: expected unsigned char [noderef] [usertype] __percpu **extern [addressable] [assigned] [toplevel] hv_synic_eventring_tail
drivers/hv/hv_common.c:349:41: sparse: got unsigned char [usertype] *[noderef] __percpu *
>> drivers/hv/hv_common.c:399:55: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void const [noderef] __percpu *__vpp_verify @@ got unsigned char [noderef] [usertype] __percpu ** @@
drivers/hv/hv_common.c:399:55: sparse: expected void const [noderef] __percpu *__vpp_verify
drivers/hv/hv_common.c:399:55: sparse: got unsigned char [noderef] [usertype] __percpu **
vim +98 drivers/hv/hv_common.c
74
75 /*
76 * Hyper-V specific initialization and shutdown code that is
77 * common across all architectures. Called from architecture
78 * specific initialization functions.
79 */
80
81 void __init hv_common_free(void)
82 {
83 unregister_sysctl_table(hv_ctl_table_hdr);
84 hv_ctl_table_hdr = NULL;
85
86 if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)
87 hv_kmsg_dump_unregister();
88
89 kfree(hv_vp_index);
90 hv_vp_index = NULL;
91
92 free_percpu(hyperv_pcpu_output_arg);
93 hyperv_pcpu_output_arg = NULL;
94
95 free_percpu(hyperv_pcpu_input_arg);
96 hyperv_pcpu_input_arg = NULL;
97
> 98 free_percpu(hv_synic_eventring_tail);
99 hv_synic_eventring_tail = NULL;
100 }
101
@@ -62,6 +62,16 @@ static void hv_kmsg_dump_unregister(void);
static struct ctl_table_header *hv_ctl_table_hdr;
+/*
+ * Per-cpu array holding the tail pointer for the SynIC event ring buffer
+ * for each SINT.
+ *
+ * We cannot maintain this in mshv driver because the tail pointer should
+ * persist even if the mshv driver is unloaded.
+ */
+u8 __percpu **hv_synic_eventring_tail;
+EXPORT_SYMBOL_GPL(hv_synic_eventring_tail);
+
/*
* Hyper-V specific initialization and shutdown code that is
* common across all architectures. Called from architecture
@@ -84,6 +94,9 @@ void __init hv_common_free(void)
free_percpu(hyperv_pcpu_input_arg);
hyperv_pcpu_input_arg = NULL;
+
+ free_percpu(hv_synic_eventring_tail);
+ hv_synic_eventring_tail = NULL;
}
/*
@@ -333,6 +346,8 @@ int __init hv_common_init(void)
if (hv_root_partition) {
hyperv_pcpu_output_arg = alloc_percpu(void *);
BUG_ON(!hyperv_pcpu_output_arg);
+ hv_synic_eventring_tail = alloc_percpu(u8 *);
+ BUG_ON(hv_synic_eventring_tail == NULL);
}
hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index),
@@ -357,6 +372,7 @@ int __init hv_common_init(void)
int hv_common_cpu_init(unsigned int cpu)
{
void **inputarg, **outputarg;
+ u8 **synic_eventring_tail;
u64 msr_vp_index;
gfp_t flags;
int pgcount = hv_root_partition ? 2 : 1;
@@ -369,8 +385,8 @@ int hv_common_cpu_init(unsigned int cpu)
inputarg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
/*
- * hyperv_pcpu_input_arg and hyperv_pcpu_output_arg memory is already
- * allocated if this CPU was previously online and then taken offline
+ * The per-cpu memory is already allocated if this CPU was previously
+ * online and then taken offline
*/
if (!*inputarg) {
mem = kmalloc(pgcount * HV_HYP_PAGE_SIZE, flags);
@@ -380,6 +396,14 @@ int hv_common_cpu_init(unsigned int cpu)
if (hv_root_partition) {
outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg);
*outputarg = (char *)mem + HV_HYP_PAGE_SIZE;
+ synic_eventring_tail = (u8 **)this_cpu_ptr(hv_synic_eventring_tail);
+ *synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT, sizeof(u8),
+ flags);
+
+ if (unlikely(!*synic_eventring_tail)) {
+ kfree(mem);
+ return -ENOMEM;
+ }
}
if (!ms_hyperv.paravisor_present &&
@@ -77,6 +77,8 @@ extern bool hv_nested;
extern void * __percpu *hyperv_pcpu_input_arg;
extern void * __percpu *hyperv_pcpu_output_arg;
+extern u8 __percpu **hv_synic_eventring_tail;
+
extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr);
extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);
bool hv_isolation_type_snp(void);