aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kvm/arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kvm/arm.c')
-rw-r--r--arch/arm/kvm/arm.c52
1 files changed, 33 insertions, 19 deletions
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 6accd66d26f0..b5384311dec4 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -1061,15 +1061,27 @@ static void cpu_init_hyp_mode(void *dummy)
1061 kvm_arm_init_debug(); 1061 kvm_arm_init_debug();
1062} 1062}
1063 1063
1064static void cpu_hyp_reinit(void)
1065{
1066 if (is_kernel_in_hyp_mode()) {
1067 /*
1068 * cpu_init_stage2() is safe to call even if the PM
1069 * event was cancelled before the CPU was reset.
1070 */
1071 cpu_init_stage2(NULL);
1072 } else {
1073 if (__hyp_get_vectors() == hyp_default_vectors)
1074 cpu_init_hyp_mode(NULL);
1075 }
1076}
1077
1064static int hyp_init_cpu_notify(struct notifier_block *self, 1078static int hyp_init_cpu_notify(struct notifier_block *self,
1065 unsigned long action, void *cpu) 1079 unsigned long action, void *cpu)
1066{ 1080{
1067 switch (action) { 1081 switch (action) {
1068 case CPU_STARTING: 1082 case CPU_STARTING:
1069 case CPU_STARTING_FROZEN: 1083 case CPU_STARTING_FROZEN:
1070 if (__hyp_get_vectors() == hyp_default_vectors) 1084 cpu_hyp_reinit();
1071 cpu_init_hyp_mode(NULL);
1072 break;
1073 } 1085 }
1074 1086
1075 return NOTIFY_OK; 1087 return NOTIFY_OK;
@@ -1084,9 +1096,8 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
1084 unsigned long cmd, 1096 unsigned long cmd,
1085 void *v) 1097 void *v)
1086{ 1098{
1087 if (cmd == CPU_PM_EXIT && 1099 if (cmd == CPU_PM_EXIT) {
1088 __hyp_get_vectors() == hyp_default_vectors) { 1100 cpu_hyp_reinit();
1089 cpu_init_hyp_mode(NULL);
1090 return NOTIFY_OK; 1101 return NOTIFY_OK;
1091 } 1102 }
1092 1103
@@ -1128,6 +1139,22 @@ static int init_subsystems(void)
1128 int err; 1139 int err;
1129 1140
1130 /* 1141 /*
1142 * Register CPU Hotplug notifier
1143 */
1144 cpu_notifier_register_begin();
1145 err = __register_cpu_notifier(&hyp_init_cpu_nb);
1146 cpu_notifier_register_done();
1147 if (err) {
1148 kvm_err("Cannot register KVM init CPU notifier (%d)\n", err);
1149 return err;
1150 }
1151
1152 /*
1153 * Register CPU lower-power notifier
1154 */
1155 hyp_cpu_pm_init();
1156
1157 /*
1131 * Init HYP view of VGIC 1158 * Init HYP view of VGIC
1132 */ 1159 */
1133 err = kvm_vgic_hyp_init(); 1160 err = kvm_vgic_hyp_init();
@@ -1270,19 +1297,6 @@ static int init_hyp_mode(void)
1270 free_boot_hyp_pgd(); 1297 free_boot_hyp_pgd();
1271#endif 1298#endif
1272 1299
1273 cpu_notifier_register_begin();
1274
1275 err = __register_cpu_notifier(&hyp_init_cpu_nb);
1276
1277 cpu_notifier_register_done();
1278
1279 if (err) {
1280 kvm_err("Cannot register HYP init CPU notifier (%d)\n", err);
1281 goto out_err;
1282 }
1283
1284 hyp_cpu_pm_init();
1285
1286 /* set size of VMID supported by CPU */ 1300 /* set size of VMID supported by CPU */
1287 kvm_vmid_bits = kvm_get_vmid_bits(); 1301 kvm_vmid_bits = kvm_get_vmid_bits();
1288 kvm_info("%d-bit VMID\n", kvm_vmid_bits); 1302 kvm_info("%d-bit VMID\n", kvm_vmid_bits);