Commit ec6449a9 authored by Christoffer Dall's avatar Christoffer Dall

KVM: arm/arm64: Don't enable/disable physical timer access on VHE

After the timer optimization rework we accidentally end up calling
physical timer enable/disable functions on VHE systems, which is neither
needed nor correct, since the CNTHCTL_EL2 register format is
different when HCR_EL2.E2H is set.

The CNTHCTL_EL2 is initialized when CPUs become online in
kvm_timer_init_vhe() and we don't have to call these functions on VHE
systems, which also allows us to inline the non-VHE functionality.
Reported-by: default avatarJintack Lim <jintack@cs.columbia.edu>
Signed-off-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
parent 4fbd8d19
...@@ -93,7 +93,4 @@ void kvm_timer_init_vhe(void); ...@@ -93,7 +93,4 @@ void kvm_timer_init_vhe(void);
#define vcpu_vtimer(v) (&(v)->arch.timer_cpu.vtimer) #define vcpu_vtimer(v) (&(v)->arch.timer_cpu.vtimer)
#define vcpu_ptimer(v) (&(v)->arch.timer_cpu.ptimer) #define vcpu_ptimer(v) (&(v)->arch.timer_cpu.ptimer)
void enable_el1_phys_timer_access(void);
void disable_el1_phys_timer_access(void);
#endif #endif
...@@ -479,9 +479,6 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu) ...@@ -479,9 +479,6 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
vtimer_restore_state(vcpu); vtimer_restore_state(vcpu);
if (has_vhe())
disable_el1_phys_timer_access();
/* Set the background timer for the physical timer emulation. */ /* Set the background timer for the physical timer emulation. */
phys_timer_emulate(vcpu); phys_timer_emulate(vcpu);
} }
...@@ -510,9 +507,6 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu) ...@@ -510,9 +507,6 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
if (unlikely(!timer->enabled)) if (unlikely(!timer->enabled))
return; return;
if (has_vhe())
enable_el1_phys_timer_access();
vtimer_save_state(vcpu); vtimer_save_state(vcpu);
/* /*
......
...@@ -27,42 +27,34 @@ void __hyp_text __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high) ...@@ -27,42 +27,34 @@ void __hyp_text __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high)
write_sysreg(cntvoff, cntvoff_el2); write_sysreg(cntvoff, cntvoff_el2);
} }
void __hyp_text enable_el1_phys_timer_access(void)
{
u64 val;
/* Allow physical timer/counter access for the host */
val = read_sysreg(cnthctl_el2);
val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
write_sysreg(val, cnthctl_el2);
}
void __hyp_text disable_el1_phys_timer_access(void)
{
u64 val;
/*
* Disallow physical timer access for the guest
* Physical counter access is allowed
*/
val = read_sysreg(cnthctl_el2);
val &= ~CNTHCTL_EL1PCEN;
val |= CNTHCTL_EL1PCTEN;
write_sysreg(val, cnthctl_el2);
}
void __hyp_text __timer_disable_traps(struct kvm_vcpu *vcpu) void __hyp_text __timer_disable_traps(struct kvm_vcpu *vcpu)
{ {
/* /*
* We don't need to do this for VHE since the host kernel runs in EL2 * We don't need to do this for VHE since the host kernel runs in EL2
* with HCR_EL2.TGE ==1, which makes those bits have no impact. * with HCR_EL2.TGE ==1, which makes those bits have no impact.
*/ */
if (!has_vhe()) if (!has_vhe()) {
enable_el1_phys_timer_access(); u64 val;
/* Allow physical timer/counter access for the host */
val = read_sysreg(cnthctl_el2);
val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
write_sysreg(val, cnthctl_el2);
}
} }
void __hyp_text __timer_enable_traps(struct kvm_vcpu *vcpu) void __hyp_text __timer_enable_traps(struct kvm_vcpu *vcpu)
{ {
if (!has_vhe()) if (!has_vhe()) {
disable_el1_phys_timer_access(); u64 val;
/*
* Disallow physical timer access for the guest
* Physical counter access is allowed
*/
val = read_sysreg(cnthctl_el2);
val &= ~CNTHCTL_EL1PCEN;
val |= CNTHCTL_EL1PCTEN;
write_sysreg(val, cnthctl_el2);
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment