@@ -32,12 +32,37 @@ EXPORT_SYMBOL_GPL(hv_vp_index);
3232u32 hv_max_vp_index ;
3333EXPORT_SYMBOL_GPL (hv_max_vp_index );
3434
35+ void __percpu * * hyperv_pcpu_input_arg ;
36+ EXPORT_SYMBOL_GPL (hyperv_pcpu_input_arg );
37+
3538static int hv_cpu_init (unsigned int cpu )
3639{
40+ void * * input_arg ;
41+
42+ input_arg = (void * * )this_cpu_ptr (hyperv_pcpu_input_arg );
43+ * input_arg = kmalloc (HV_HYP_PAGE_SIZE , GFP_KERNEL );
44+ if (unlikely (!* input_arg ))
45+ return - ENOMEM ;
3746 hv_vp_index [cpu ] = hv_get_vpreg (HV_REGISTER_VP_INDEX );
3847 return 0 ;
3948}
4049
50+ static int hv_cpu_die (unsigned int cpu )
51+ {
52+ void * * input_arg ;
53+ void * input ;
54+ unsigned long flags ;
55+
56+ local_irq_save (flags );
57+ input_arg = (void * * )this_cpu_ptr (hyperv_pcpu_input_arg );
58+ input = * input_arg ;
59+ * input_arg = NULL ;
60+ local_irq_restore (flags );
61+ kfree (input );
62+
63+ return 0 ;
64+ }
65+
4166void __init hyperv_early_init (void )
4267{
4368 struct hv_get_vp_registers_output result ;
@@ -95,23 +120,35 @@ static int __init hyperv_init(void)
95120 if (!hyperv_initialized )
96121 return 0 ;
97122
123+ /*
124+ * Allocate the per-CPU state for the hypercall input arg.
125+ * If this allocation fails, we will not be able to setup
126+ * (per-CPU) hypercall input page and thus this failure is
127+ * fatal on Hyper-V.
128+ */
129+ hyperv_pcpu_input_arg = alloc_percpu (void * );
130+ if (unlikely (!hyperv_pcpu_input_arg ))
131+ return - ENOMEM ;
132+
98133 /* Allocate and initialize percpu VP index array */
99134 hv_max_vp_index = num_possible_cpus ();
100135 hv_vp_index = kmalloc_array (hv_max_vp_index , sizeof (* hv_vp_index ),
101136 GFP_KERNEL );
102137 if (!hv_vp_index ) {
103138 hv_max_vp_index = 0 ;
139+ free_percpu (hyperv_pcpu_input_arg );
104140 return - ENOMEM ;
105141 }
106142
107143 for (i = 0 ; i < hv_max_vp_index ; i ++ )
108144 hv_vp_index [i ] = VP_INVAL ;
109145
110146 if (cpuhp_setup_state (CPUHP_AP_ONLINE_DYN , "arm64/hyperv_init:online" ,
111- hv_cpu_init , NULL ) < 0 ) {
147+ hv_cpu_init , hv_cpu_die ) < 0 ) {
112148 hv_max_vp_index = 0 ;
113149 kfree (hv_vp_index );
114150 hv_vp_index = NULL ;
151+ free_percpu (hyperv_pcpu_input_arg );
115152 return - EINVAL ;
116153 }
117154
0 commit comments