mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 01:56:42 +07:00
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: 1e947bad0b
("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>
This commit is contained in:
parent
cb678d6016
commit
5f5560b1c5
@ -1061,15 +1061,27 @@ static void cpu_init_hyp_mode(void *dummy)
|
|||||||
kvm_arm_init_debug();
|
kvm_arm_init_debug();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cpu_hyp_reinit(void)
|
||||||
|
{
|
||||||
|
if (is_kernel_in_hyp_mode()) {
|
||||||
|
/*
|
||||||
|
* cpu_init_stage2() is safe to call even if the PM
|
||||||
|
* event was cancelled before the CPU was reset.
|
||||||
|
*/
|
||||||
|
cpu_init_stage2(NULL);
|
||||||
|
} else {
|
||||||
|
if (__hyp_get_vectors() == hyp_default_vectors)
|
||||||
|
cpu_init_hyp_mode(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int hyp_init_cpu_notify(struct notifier_block *self,
|
static int hyp_init_cpu_notify(struct notifier_block *self,
|
||||||
unsigned long action, void *cpu)
|
unsigned long action, void *cpu)
|
||||||
{
|
{
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case CPU_STARTING:
|
case CPU_STARTING:
|
||||||
case CPU_STARTING_FROZEN:
|
case CPU_STARTING_FROZEN:
|
||||||
if (__hyp_get_vectors() == hyp_default_vectors)
|
cpu_hyp_reinit();
|
||||||
cpu_init_hyp_mode(NULL);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
@ -1084,9 +1096,8 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
|
|||||||
unsigned long cmd,
|
unsigned long cmd,
|
||||||
void *v)
|
void *v)
|
||||||
{
|
{
|
||||||
if (cmd == CPU_PM_EXIT &&
|
if (cmd == CPU_PM_EXIT) {
|
||||||
__hyp_get_vectors() == hyp_default_vectors) {
|
cpu_hyp_reinit();
|
||||||
cpu_init_hyp_mode(NULL);
|
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,6 +1138,22 @@ static int init_subsystems(void)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register CPU Hotplug notifier
|
||||||
|
*/
|
||||||
|
cpu_notifier_register_begin();
|
||||||
|
err = __register_cpu_notifier(&hyp_init_cpu_nb);
|
||||||
|
cpu_notifier_register_done();
|
||||||
|
if (err) {
|
||||||
|
kvm_err("Cannot register KVM init CPU notifier (%d)\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register CPU lower-power notifier
|
||||||
|
*/
|
||||||
|
hyp_cpu_pm_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init HYP view of VGIC
|
* Init HYP view of VGIC
|
||||||
*/
|
*/
|
||||||
@ -1270,19 +1297,6 @@ static int init_hyp_mode(void)
|
|||||||
free_boot_hyp_pgd();
|
free_boot_hyp_pgd();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cpu_notifier_register_begin();
|
|
||||||
|
|
||||||
err = __register_cpu_notifier(&hyp_init_cpu_nb);
|
|
||||||
|
|
||||||
cpu_notifier_register_done();
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
kvm_err("Cannot register HYP init CPU notifier (%d)\n", err);
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
hyp_cpu_pm_init();
|
|
||||||
|
|
||||||
/* set size of VMID supported by CPU */
|
/* set size of VMID supported by CPU */
|
||||||
kvm_vmid_bits = kvm_get_vmid_bits();
|
kvm_vmid_bits = kvm_get_vmid_bits();
|
||||||
kvm_info("%d-bit VMID\n", kvm_vmid_bits);
|
kvm_info("%d-bit VMID\n", kvm_vmid_bits);
|
||||||
|
Loading…
Reference in New Issue
Block a user