@@ -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 ;
@@ -89,23 +114,35 @@ static int __init hyperv_init(void)
89114{
90115 int i ;
91116
117+ /*
118+ * Allocate the per-CPU state for the hypercall input arg.
119+ * If this allocation fails, we will not be able to setup
120+ * (per-CPU) hypercall input page and thus this failure is
121+ * fatal on Hyper-V.
122+ */
123+ hyperv_pcpu_input_arg = alloc_percpu (void * );
124+ if (unlikely (!hyperv_pcpu_input_arg ))
125+ return - ENOMEM ;
126+
92127 /* Allocate and initialize percpu VP index array */
93128 hv_max_vp_index = num_possible_cpus ();
94129 hv_vp_index = kmalloc_array (hv_max_vp_index , sizeof (* hv_vp_index ),
95130 GFP_KERNEL );
96131 if (!hv_vp_index ) {
97132 hv_max_vp_index = 0 ;
133+ free_percpu (hyperv_pcpu_input_arg );
98134 return - ENOMEM ;
99135 }
100136
101137 for (i = 0 ; i < hv_max_vp_index ; i ++ )
102138 hv_vp_index [i ] = VP_INVAL ;
103139
104140 if (cpuhp_setup_state (CPUHP_AP_ONLINE_DYN , "arm64/hyperv_init:online" ,
105- hv_cpu_init , NULL ) < 0 ) {
141+ hv_cpu_init , hv_cpu_die ) < 0 ) {
106142 hv_max_vp_index = 0 ;
107143 kfree (hv_vp_index );
108144 hv_vp_index = NULL ;
145+ free_percpu (hyperv_pcpu_input_arg );
109146 return - EINVAL ;
110147 }
111148
0 commit comments