diff options
Diffstat (limited to 'arch/arm/kvm/arm.c')
-rw-r--r-- | arch/arm/kvm/arm.c | 52 |
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 | ||
1064 | static 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 | |||
1064 | static int hyp_init_cpu_notify(struct notifier_block *self, | 1078 | static 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); |