@@ -964,6 +964,11 @@ long kvm_arch_vm_ioctl(struct file *filp,
964964 }
965965}
966966
967+ static void cpu_init_stage2 (void * dummy )
968+ {
969+ __cpu_init_stage2 ();
970+ }
971+
967972static void cpu_init_hyp_mode (void * dummy )
968973{
969974 phys_addr_t boot_pgd_ptr ;
@@ -1033,6 +1038,82 @@ static inline void hyp_cpu_pm_init(void)
10331038}
10341039#endif
10351040
1041+ static void teardown_common_resources (void )
1042+ {
1043+ free_percpu (kvm_host_cpu_state );
1044+ }
1045+
1046+ static int init_common_resources (void )
1047+ {
1048+ kvm_host_cpu_state = alloc_percpu (kvm_cpu_context_t );
1049+ if (!kvm_host_cpu_state ) {
1050+ kvm_err ("Cannot allocate host CPU state\n" );
1051+ return - ENOMEM ;
1052+ }
1053+
1054+ return 0 ;
1055+ }
1056+
1057+ static int init_subsystems (void )
1058+ {
1059+ int err ;
1060+
1061+ /*
1062+ * Init HYP view of VGIC
1063+ */
1064+ err = kvm_vgic_hyp_init ();
1065+ switch (err ) {
1066+ case 0 :
1067+ vgic_present = true;
1068+ break ;
1069+ case - ENODEV :
1070+ case - ENXIO :
1071+ vgic_present = false;
1072+ break ;
1073+ default :
1074+ return err ;
1075+ }
1076+
1077+ /*
1078+ * Init HYP architected timer support
1079+ */
1080+ err = kvm_timer_hyp_init ();
1081+ if (err )
1082+ return err ;
1083+
1084+ kvm_perf_init ();
1085+ kvm_coproc_table_init ();
1086+
1087+ return 0 ;
1088+ }
1089+
1090+ static void teardown_hyp_mode (void )
1091+ {
1092+ int cpu ;
1093+
1094+ if (is_kernel_in_hyp_mode ())
1095+ return ;
1096+
1097+ free_hyp_pgds ();
1098+ for_each_possible_cpu (cpu )
1099+ free_page (per_cpu (kvm_arm_hyp_stack_page , cpu ));
1100+ }
1101+
1102+ static int init_vhe_mode (void )
1103+ {
1104+ /*
1105+ * Execute the init code on each CPU.
1106+ */
1107+ on_each_cpu (cpu_init_stage2 , NULL , 1 );
1108+
1109+ /* set size of VMID supported by CPU */
1110+ kvm_vmid_bits = kvm_get_vmid_bits ();
1111+ kvm_info ("%d-bit VMID\n" , kvm_vmid_bits );
1112+
1113+ kvm_info ("VHE mode initialized successfully\n" );
1114+ return 0 ;
1115+ }
1116+
10361117/**
10371118 * Inits Hyp-mode on all online CPUs
10381119 */
@@ -1063,7 +1144,7 @@ static int init_hyp_mode(void)
10631144 stack_page = __get_free_page (GFP_KERNEL );
10641145 if (!stack_page ) {
10651146 err = - ENOMEM ;
1066- goto out_free_stack_pages ;
1147+ goto out_err ;
10671148 }
10681149
10691150 per_cpu (kvm_arm_hyp_stack_page , cpu ) = stack_page ;
@@ -1076,14 +1157,14 @@ static int init_hyp_mode(void)
10761157 kvm_ksym_ref (__kvm_hyp_code_end ));
10771158 if (err ) {
10781159 kvm_err ("Cannot map world-switch code\n" );
1079- goto out_free_mappings ;
1160+ goto out_err ;
10801161 }
10811162
10821163 err = create_hyp_mappings (kvm_ksym_ref (__start_rodata ),
10831164 kvm_ksym_ref (__end_rodata ));
10841165 if (err ) {
10851166 kvm_err ("Cannot map rodata section\n" );
1086- goto out_free_mappings ;
1167+ goto out_err ;
10871168 }
10881169
10891170 /*
@@ -1095,20 +1176,10 @@ static int init_hyp_mode(void)
10951176
10961177 if (err ) {
10971178 kvm_err ("Cannot map hyp stack\n" );
1098- goto out_free_mappings ;
1179+ goto out_err ;
10991180 }
11001181 }
11011182
1102- /*
1103- * Map the host CPU structures
1104- */
1105- kvm_host_cpu_state = alloc_percpu (kvm_cpu_context_t );
1106- if (!kvm_host_cpu_state ) {
1107- err = - ENOMEM ;
1108- kvm_err ("Cannot allocate host CPU state\n" );
1109- goto out_free_mappings ;
1110- }
1111-
11121183 for_each_possible_cpu (cpu ) {
11131184 kvm_cpu_context_t * cpu_ctxt ;
11141185
@@ -1117,7 +1188,7 @@ static int init_hyp_mode(void)
11171188
11181189 if (err ) {
11191190 kvm_err ("Cannot map host CPU state: %d\n" , err );
1120- goto out_free_context ;
1191+ goto out_err ;
11211192 }
11221193 }
11231194
@@ -1126,34 +1197,22 @@ static int init_hyp_mode(void)
11261197 */
11271198 on_each_cpu (cpu_init_hyp_mode , NULL , 1 );
11281199
1129- /*
1130- * Init HYP view of VGIC
1131- */
1132- err = kvm_vgic_hyp_init ();
1133- switch (err ) {
1134- case 0 :
1135- vgic_present = true;
1136- break ;
1137- case - ENODEV :
1138- case - ENXIO :
1139- vgic_present = false;
1140- break ;
1141- default :
1142- goto out_free_context ;
1143- }
1144-
1145- /*
1146- * Init HYP architected timer support
1147- */
1148- err = kvm_timer_hyp_init ();
1149- if (err )
1150- goto out_free_context ;
1151-
11521200#ifndef CONFIG_HOTPLUG_CPU
11531201 free_boot_hyp_pgd ();
11541202#endif
11551203
1156- kvm_perf_init ();
1204+ cpu_notifier_register_begin ();
1205+
1206+ err = __register_cpu_notifier (& hyp_init_cpu_nb );
1207+
1208+ cpu_notifier_register_done ();
1209+
1210+ if (err ) {
1211+ kvm_err ("Cannot register HYP init CPU notifier (%d)\n" , err );
1212+ goto out_err ;
1213+ }
1214+
1215+ hyp_cpu_pm_init ();
11571216
11581217 /* set size of VMID supported by CPU */
11591218 kvm_vmid_bits = kvm_get_vmid_bits ();
@@ -1162,14 +1221,9 @@ static int init_hyp_mode(void)
11621221 kvm_info ("Hyp mode initialized successfully\n" );
11631222
11641223 return 0 ;
1165- out_free_context :
1166- free_percpu (kvm_host_cpu_state );
1167- out_free_mappings :
1168- free_hyp_pgds ();
1169- out_free_stack_pages :
1170- for_each_possible_cpu (cpu )
1171- free_page (per_cpu (kvm_arm_hyp_stack_page , cpu ));
1224+
11721225out_err :
1226+ teardown_hyp_mode ();
11731227 kvm_err ("error initializing Hyp mode: %d\n" , err );
11741228 return err ;
11751229}
@@ -1213,26 +1267,27 @@ int kvm_arch_init(void *opaque)
12131267 }
12141268 }
12151269
1216- cpu_notifier_register_begin ();
1217-
1218- err = init_hyp_mode ();
1270+ err = init_common_resources ();
12191271 if (err )
1220- goto out_err ;
1272+ return err ;
12211273
1222- err = __register_cpu_notifier (& hyp_init_cpu_nb );
1223- if (err ) {
1224- kvm_err ("Cannot register HYP init CPU notifier (%d)\n" , err );
1274+ if (is_kernel_in_hyp_mode ())
1275+ err = init_vhe_mode ();
1276+ else
1277+ err = init_hyp_mode ();
1278+ if (err )
12251279 goto out_err ;
1226- }
1227-
1228- cpu_notifier_register_done ();
12291280
1230- hyp_cpu_pm_init ();
1281+ err = init_subsystems ();
1282+ if (err )
1283+ goto out_hyp ;
12311284
1232- kvm_coproc_table_init ();
12331285 return 0 ;
1286+
1287+ out_hyp :
1288+ teardown_hyp_mode ();
12341289out_err :
1235- cpu_notifier_register_done ();
1290+ teardown_common_resources ();
12361291 return err ;
12371292}
12381293
0 commit comments