Skip to content

Commit 563a1d1

Browse files
James MorseAlex Shi
authored andcommitted
arm64: KVM: Register CPU notifiers when the kernel runs at HYP
When the kernel is running at EL2, it doesn't need init_hyp_mode() to configure page tables for HYP. This function also registers the CPU hotplug and lower power notifiers that cause HYP to be re-initialised after the CPU has been reset. To avoid losing the register state that controls stage2 translation, move the registering of these notifiers into init_subsystems(), and add a is_kernel_in_hyp_mode() path to each callback. Acked-by: Marc Zyngier <marc.zyngier@arm.com> Acked-by: Christoffer Dall <christoffer.dall@linaro.org> Fixes: 1e947bad0b6 ("arm64: KVM: Skip HYP setup when already running in HYP") Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org> (cherry picked from commit 5f5560b1c5f3a80e91c6babb2da34a51943bbdec) Signed-off-by: Alex Shi <alex.shi@linaro.org>
1 parent 3fe3980 commit 563a1d1

1 file changed

Lines changed: 33 additions & 19 deletions

File tree

arch/arm/kvm/arm.c

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -992,15 +992,27 @@ static void cpu_init_hyp_mode(void *dummy)
992992
kvm_arm_init_debug();
993993
}
994994

995+
static void cpu_hyp_reinit(void)
996+
{
997+
if (is_kernel_in_hyp_mode()) {
998+
/*
999+
* cpu_init_stage2() is safe to call even if the PM
1000+
* event was cancelled before the CPU was reset.
1001+
*/
1002+
cpu_init_stage2(NULL);
1003+
} else {
1004+
if (__hyp_get_vectors() == hyp_default_vectors)
1005+
cpu_init_hyp_mode(NULL);
1006+
}
1007+
}
1008+
9951009
static int hyp_init_cpu_notify(struct notifier_block *self,
9961010
unsigned long action, void *cpu)
9971011
{
9981012
switch (action) {
9991013
case CPU_STARTING:
10001014
case CPU_STARTING_FROZEN:
1001-
if (__hyp_get_vectors() == hyp_default_vectors)
1002-
cpu_init_hyp_mode(NULL);
1003-
break;
1015+
cpu_hyp_reinit();
10041016
}
10051017

10061018
return NOTIFY_OK;
@@ -1015,9 +1027,8 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
10151027
unsigned long cmd,
10161028
void *v)
10171029
{
1018-
if (cmd == CPU_PM_EXIT &&
1019-
__hyp_get_vectors() == hyp_default_vectors) {
1020-
cpu_init_hyp_mode(NULL);
1030+
if (cmd == CPU_PM_EXIT) {
1031+
cpu_hyp_reinit();
10211032
return NOTIFY_OK;
10221033
}
10231034

@@ -1058,6 +1069,22 @@ static int init_subsystems(void)
10581069
{
10591070
int err;
10601071

1072+
/*
1073+
* Register CPU Hotplug notifier
1074+
*/
1075+
cpu_notifier_register_begin();
1076+
err = __register_cpu_notifier(&hyp_init_cpu_nb);
1077+
cpu_notifier_register_done();
1078+
if (err) {
1079+
kvm_err("Cannot register KVM init CPU notifier (%d)\n", err);
1080+
return err;
1081+
}
1082+
1083+
/*
1084+
* Register CPU lower-power notifier
1085+
*/
1086+
hyp_cpu_pm_init();
1087+
10611088
/*
10621089
* Init HYP view of VGIC
10631090
*/
@@ -1201,19 +1228,6 @@ static int init_hyp_mode(void)
12011228
free_boot_hyp_pgd();
12021229
#endif
12031230

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();
1216-
12171231
/* set size of VMID supported by CPU */
12181232
kvm_vmid_bits = kvm_get_vmid_bits();
12191233
kvm_info("%d-bit VMID\n", kvm_vmid_bits);

0 commit comments

Comments
 (0)