@@ -967,6 +967,11 @@ long kvm_arch_vm_ioctl(struct file *filp,
967
967
}
968
968
}
969
969
970
+ static void cpu_init_stage2 (void * dummy )
971
+ {
972
+ __cpu_init_stage2 ();
973
+ }
974
+
970
975
static void cpu_init_hyp_mode (void * dummy )
971
976
{
972
977
phys_addr_t boot_pgd_ptr ;
@@ -1036,6 +1041,82 @@ static inline void hyp_cpu_pm_init(void)
1036
1041
}
1037
1042
#endif
1038
1043
1044
+ static void teardown_common_resources (void )
1045
+ {
1046
+ free_percpu (kvm_host_cpu_state );
1047
+ }
1048
+
1049
+ static int init_common_resources (void )
1050
+ {
1051
+ kvm_host_cpu_state = alloc_percpu (kvm_cpu_context_t );
1052
+ if (!kvm_host_cpu_state ) {
1053
+ kvm_err ("Cannot allocate host CPU state\n" );
1054
+ return - ENOMEM ;
1055
+ }
1056
+
1057
+ return 0 ;
1058
+ }
1059
+
1060
+ static int init_subsystems (void )
1061
+ {
1062
+ int err ;
1063
+
1064
+ /*
1065
+ * Init HYP view of VGIC
1066
+ */
1067
+ err = kvm_vgic_hyp_init ();
1068
+ switch (err ) {
1069
+ case 0 :
1070
+ vgic_present = true;
1071
+ break ;
1072
+ case - ENODEV :
1073
+ case - ENXIO :
1074
+ vgic_present = false;
1075
+ break ;
1076
+ default :
1077
+ return err ;
1078
+ }
1079
+
1080
+ /*
1081
+ * Init HYP architected timer support
1082
+ */
1083
+ err = kvm_timer_hyp_init ();
1084
+ if (err )
1085
+ return err ;
1086
+
1087
+ kvm_perf_init ();
1088
+ kvm_coproc_table_init ();
1089
+
1090
+ return 0 ;
1091
+ }
1092
+
1093
+ static void teardown_hyp_mode (void )
1094
+ {
1095
+ int cpu ;
1096
+
1097
+ if (is_kernel_in_hyp_mode ())
1098
+ return ;
1099
+
1100
+ free_hyp_pgds ();
1101
+ for_each_possible_cpu (cpu )
1102
+ free_page (per_cpu (kvm_arm_hyp_stack_page , cpu ));
1103
+ }
1104
+
1105
+ static int init_vhe_mode (void )
1106
+ {
1107
+ /*
1108
+ * Execute the init code on each CPU.
1109
+ */
1110
+ on_each_cpu (cpu_init_stage2 , NULL , 1 );
1111
+
1112
+ /* set size of VMID supported by CPU */
1113
+ kvm_vmid_bits = kvm_get_vmid_bits ();
1114
+ kvm_info ("%d-bit VMID\n" , kvm_vmid_bits );
1115
+
1116
+ kvm_info ("VHE mode initialized successfully\n" );
1117
+ return 0 ;
1118
+ }
1119
+
1039
1120
/**
1040
1121
* Inits Hyp-mode on all online CPUs
1041
1122
*/
@@ -1066,7 +1147,7 @@ static int init_hyp_mode(void)
1066
1147
stack_page = __get_free_page (GFP_KERNEL );
1067
1148
if (!stack_page ) {
1068
1149
err = - ENOMEM ;
1069
- goto out_free_stack_pages ;
1150
+ goto out_err ;
1070
1151
}
1071
1152
1072
1153
per_cpu (kvm_arm_hyp_stack_page , cpu ) = stack_page ;
@@ -1078,13 +1159,13 @@ static int init_hyp_mode(void)
1078
1159
err = create_hyp_mappings (__hyp_text_start , __hyp_text_end );
1079
1160
if (err ) {
1080
1161
kvm_err ("Cannot map world-switch code\n" );
1081
- goto out_free_mappings ;
1162
+ goto out_err ;
1082
1163
}
1083
1164
1084
1165
err = create_hyp_mappings (__start_rodata , __end_rodata );
1085
1166
if (err ) {
1086
1167
kvm_err ("Cannot map rodata section\n" );
1087
- goto out_free_mappings ;
1168
+ goto out_err ;
1088
1169
}
1089
1170
1090
1171
/*
@@ -1096,20 +1177,10 @@ static int init_hyp_mode(void)
1096
1177
1097
1178
if (err ) {
1098
1179
kvm_err ("Cannot map hyp stack\n" );
1099
- goto out_free_mappings ;
1180
+ goto out_err ;
1100
1181
}
1101
1182
}
1102
1183
1103
- /*
1104
- * Map the host CPU structures
1105
- */
1106
- kvm_host_cpu_state = alloc_percpu (kvm_cpu_context_t );
1107
- if (!kvm_host_cpu_state ) {
1108
- err = - ENOMEM ;
1109
- kvm_err ("Cannot allocate host CPU state\n" );
1110
- goto out_free_mappings ;
1111
- }
1112
-
1113
1184
for_each_possible_cpu (cpu ) {
1114
1185
kvm_cpu_context_t * cpu_ctxt ;
1115
1186
@@ -1118,7 +1189,7 @@ static int init_hyp_mode(void)
1118
1189
1119
1190
if (err ) {
1120
1191
kvm_err ("Cannot map host CPU state: %d\n" , err );
1121
- goto out_free_context ;
1192
+ goto out_err ;
1122
1193
}
1123
1194
}
1124
1195
@@ -1127,34 +1198,22 @@ static int init_hyp_mode(void)
1127
1198
*/
1128
1199
on_each_cpu (cpu_init_hyp_mode , NULL , 1 );
1129
1200
1130
- /*
1131
- * Init HYP view of VGIC
1132
- */
1133
- err = kvm_vgic_hyp_init ();
1134
- switch (err ) {
1135
- case 0 :
1136
- vgic_present = true;
1137
- break ;
1138
- case - ENODEV :
1139
- case - ENXIO :
1140
- vgic_present = false;
1141
- break ;
1142
- default :
1143
- goto out_free_context ;
1144
- }
1145
-
1146
- /*
1147
- * Init HYP architected timer support
1148
- */
1149
- err = kvm_timer_hyp_init ();
1150
- if (err )
1151
- goto out_free_context ;
1152
-
1153
1201
#ifndef CONFIG_HOTPLUG_CPU
1154
1202
free_boot_hyp_pgd ();
1155
1203
#endif
1156
1204
1157
- kvm_perf_init ();
1205
+ cpu_notifier_register_begin ();
1206
+
1207
+ err = __register_cpu_notifier (& hyp_init_cpu_nb );
1208
+
1209
+ cpu_notifier_register_done ();
1210
+
1211
+ if (err ) {
1212
+ kvm_err ("Cannot register HYP init CPU notifier (%d)\n" , err );
1213
+ goto out_err ;
1214
+ }
1215
+
1216
+ hyp_cpu_pm_init ();
1158
1217
1159
1218
/* set size of VMID supported by CPU */
1160
1219
kvm_vmid_bits = kvm_get_vmid_bits ();
@@ -1163,14 +1222,9 @@ static int init_hyp_mode(void)
1163
1222
kvm_info ("Hyp mode initialized successfully\n" );
1164
1223
1165
1224
return 0 ;
1166
- out_free_context :
1167
- free_percpu (kvm_host_cpu_state );
1168
- out_free_mappings :
1169
- free_hyp_pgds ();
1170
- out_free_stack_pages :
1171
- for_each_possible_cpu (cpu )
1172
- free_page (per_cpu (kvm_arm_hyp_stack_page , cpu ));
1225
+
1173
1226
out_err :
1227
+ teardown_hyp_mode ();
1174
1228
kvm_err ("error initializing Hyp mode: %d\n" , err );
1175
1229
return err ;
1176
1230
}
@@ -1214,26 +1268,27 @@ int kvm_arch_init(void *opaque)
1214
1268
}
1215
1269
}
1216
1270
1217
- cpu_notifier_register_begin ();
1218
-
1219
- err = init_hyp_mode ();
1271
+ err = init_common_resources ();
1220
1272
if (err )
1221
- goto out_err ;
1273
+ return err ;
1222
1274
1223
- err = __register_cpu_notifier (& hyp_init_cpu_nb );
1224
- if (err ) {
1225
- kvm_err ("Cannot register HYP init CPU notifier (%d)\n" , err );
1275
+ if (is_kernel_in_hyp_mode ())
1276
+ err = init_vhe_mode ();
1277
+ else
1278
+ err = init_hyp_mode ();
1279
+ if (err )
1226
1280
goto out_err ;
1227
- }
1228
-
1229
- cpu_notifier_register_done ();
1230
1281
1231
- hyp_cpu_pm_init ();
1282
+ err = init_subsystems ();
1283
+ if (err )
1284
+ goto out_hyp ;
1232
1285
1233
- kvm_coproc_table_init ();
1234
1286
return 0 ;
1287
+
1288
+ out_hyp :
1289
+ teardown_hyp_mode ();
1235
1290
out_err :
1236
- cpu_notifier_register_done ();
1291
+ teardown_common_resources ();
1237
1292
return err ;
1238
1293
}
1239
1294
0 commit comments