aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/arm/hyp/timer-sr.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/arm/hyp/timer-sr.c')
-rw-r--r--virt/kvm/arm/hyp/timer-sr.c74
1 files changed, 32 insertions, 42 deletions
diff --git a/virt/kvm/arm/hyp/timer-sr.c b/virt/kvm/arm/hyp/timer-sr.c
index 4734915ab71f..f39861639f08 100644
--- a/virt/kvm/arm/hyp/timer-sr.c
+++ b/virt/kvm/arm/hyp/timer-sr.c
@@ -21,58 +21,48 @@
21 21
22#include <asm/kvm_hyp.h> 22#include <asm/kvm_hyp.h>
23 23
24/* vcpu is already in the HYP VA space */ 24void __hyp_text __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high)
25void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu) 25{
26 u64 cntvoff = (u64)cntvoff_high << 32 | cntvoff_low;
27 write_sysreg(cntvoff, cntvoff_el2);
28}
29
30void __hyp_text enable_el1_phys_timer_access(void)
26{ 31{
27 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
28 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
29 u64 val; 32 u64 val;
30 33
31 if (timer->enabled) { 34 /* Allow physical timer/counter access for the host */
32 vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl); 35 val = read_sysreg(cnthctl_el2);
33 vtimer->cnt_cval = read_sysreg_el0(cntv_cval); 36 val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
34 } 37 write_sysreg(val, cnthctl_el2);
38}
35 39
36 /* Disable the virtual timer */ 40void __hyp_text disable_el1_phys_timer_access(void)
37 write_sysreg_el0(0, cntv_ctl); 41{
42 u64 val;
38 43
39 /* 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)
55{
56 /*
40 * We don't need to do this for VHE since the host kernel runs in EL2 57 * We don't need to do this for VHE since the host kernel runs in EL2
41 * with HCR_EL2.TGE ==1, which makes those bits have no impact. 58 * with HCR_EL2.TGE ==1, which makes those bits have no impact.
42 */ 59 */
43 if (!has_vhe()) { 60 if (!has_vhe())
44 /* Allow physical timer/counter access for the host */ 61 enable_el1_phys_timer_access();
45 val = read_sysreg(cnthctl_el2);
46 val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
47 write_sysreg(val, cnthctl_el2);
48 }
49
50 /* Clear cntvoff for the host */
51 write_sysreg(0, cntvoff_el2);
52} 62}
53 63
54void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu) 64void __hyp_text __timer_enable_traps(struct kvm_vcpu *vcpu)
55{ 65{
56 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 66 if (!has_vhe())
57 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); 67 disable_el1_phys_timer_access();
58 u64 val;
59
60 /* Those bits are already configured at boot on VHE-system */
61 if (!has_vhe()) {
62 /*
63 * Disallow physical timer access for the guest
64 * Physical counter access is allowed
65 */
66 val = read_sysreg(cnthctl_el2);
67 val &= ~CNTHCTL_EL1PCEN;
68 val |= CNTHCTL_EL1PCTEN;
69 write_sysreg(val, cnthctl_el2);
70 }
71
72 if (timer->enabled) {
73 write_sysreg(vtimer->cntvoff, cntvoff_el2);
74 write_sysreg_el0(vtimer->cnt_cval, cntv_cval);
75 isb();
76 write_sysreg_el0(vtimer->cnt_ctl, cntv_ctl);
77 }
78} 68}