summaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorChristoffer Dall <christoffer.dall@linaro.org>2017-11-20 06:10:15 -0500
committerChristoffer Dall <christoffer.dall@linaro.org>2017-11-29 10:46:09 -0500
commitec6449a9c2296b1c04f6219f7473e0c2fedecfed (patch)
tree2ee426e7d249629cb65c9c098ec2f4a924ee91fe /virt
parent4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323 (diff)
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: Jintack Lim <jintack@cs.columbia.edu> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/arch_timer.c6
-rw-r--r--virt/kvm/arm/hyp/timer-sr.c48
2 files changed, 20 insertions, 34 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 4151250ce8da..190c99ed1b73 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -479,9 +479,6 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
479 479
480 vtimer_restore_state(vcpu); 480 vtimer_restore_state(vcpu);
481 481
482 if (has_vhe())
483 disable_el1_phys_timer_access();
484
485 /* Set the background timer for the physical timer emulation. */ 482 /* Set the background timer for the physical timer emulation. */
486 phys_timer_emulate(vcpu); 483 phys_timer_emulate(vcpu);
487} 484}
@@ -510,9 +507,6 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
510 if (unlikely(!timer->enabled)) 507 if (unlikely(!timer->enabled))
511 return; 508 return;
512 509
513 if (has_vhe())
514 enable_el1_phys_timer_access();
515
516 vtimer_save_state(vcpu); 510 vtimer_save_state(vcpu);
517 511
518 /* 512 /*
diff --git a/virt/kvm/arm/hyp/timer-sr.c b/virt/kvm/arm/hyp/timer-sr.c
index f39861639f08..f24404b3c8df 100644
--- a/virt/kvm/arm/hyp/timer-sr.c
+++ b/virt/kvm/arm/hyp/timer-sr.c
@@ -27,42 +27,34 @@ void __hyp_text __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high)
27 write_sysreg(cntvoff, cntvoff_el2); 27 write_sysreg(cntvoff, cntvoff_el2);
28} 28}
29 29
30void __hyp_text enable_el1_phys_timer_access(void)
31{
32 u64 val;
33
34 /* Allow physical timer/counter access for the host */
35 val = read_sysreg(cnthctl_el2);
36 val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
37 write_sysreg(val, cnthctl_el2);
38}
39
40void __hyp_text disable_el1_phys_timer_access(void)
41{
42 u64 val;
43
44 /*
45 * Disallow physical timer access for the guest
46 * Physical counter access is allowed
47 */
48 val = read_sysreg(cnthctl_el2);
49 val &= ~CNTHCTL_EL1PCEN;
50 val |= CNTHCTL_EL1PCTEN;
51 write_sysreg(val, cnthctl_el2);
52}
53
54void __hyp_text __timer_disable_traps(struct kvm_vcpu *vcpu) 30void __hyp_text __timer_disable_traps(struct kvm_vcpu *vcpu)
55{ 31{
56 /* 32 /*
57 * We don't need to do this for VHE since the host kernel runs in EL2 33 * We don't need to do this for VHE since the host kernel runs in EL2
58 * with HCR_EL2.TGE ==1, which makes those bits have no impact. 34 * with HCR_EL2.TGE ==1, which makes those bits have no impact.
59 */ 35 */
60 if (!has_vhe()) 36 if (!has_vhe()) {
61 enable_el1_phys_timer_access(); 37 u64 val;
38
39 /* Allow physical timer/counter access for the host */
40 val = read_sysreg(cnthctl_el2);
41 val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
42 write_sysreg(val, cnthctl_el2);
43 }
62} 44}
63 45
64void __hyp_text __timer_enable_traps(struct kvm_vcpu *vcpu) 46void __hyp_text __timer_enable_traps(struct kvm_vcpu *vcpu)
65{ 47{
66 if (!has_vhe()) 48 if (!has_vhe()) {
67 disable_el1_phys_timer_access(); 49 u64 val;
50
51 /*
52 * Disallow physical timer access for the guest
53 * Physical counter access is allowed
54 */
55 val = read_sysreg(cnthctl_el2);
56 val &= ~CNTHCTL_EL1PCEN;
57 val |= CNTHCTL_EL1PCTEN;
58 write_sysreg(val, cnthctl_el2);
59 }
68} 60}