Skip to content

Commit e59bff9

Browse files
author
Marc Zyngier
committed
ARM: KVM: Add timer save/restore
This patch shouldn't exist, as we should be able to reuse the arm64 version for free. I'll get there eventually, but in the meantime I need a timer ticking. Reviewed-by: Christoffer Dall <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent c7ce6c6 commit e59bff9

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

arch/arm/kvm/hyp/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44

55
obj-$(CONFIG_KVM_ARM_HOST) += tlb.o
66
obj-$(CONFIG_KVM_ARM_HOST) += cp15-sr.o
7+
obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o

arch/arm/kvm/hyp/hyp.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
#define TTBR1 __ACCESS_CP15_64(1, c2)
4747
#define VTTBR __ACCESS_CP15_64(6, c2)
4848
#define PAR __ACCESS_CP15_64(0, c7)
49+
#define CNTV_CVAL __ACCESS_CP15_64(3, c14)
50+
#define CNTVOFF __ACCESS_CP15_64(4, c14)
51+
4952
#define CSSELR __ACCESS_CP15(c0, 2, c0, 0)
5053
#define VMPIDR __ACCESS_CP15(c0, 4, c0, 5)
5154
#define SCTLR __ACCESS_CP15(c1, 0, c0, 0)
@@ -71,6 +74,11 @@
7174
#define TID_URO __ACCESS_CP15(c13, 0, c0, 3)
7275
#define TID_PRIV __ACCESS_CP15(c13, 0, c0, 4)
7376
#define CNTKCTL __ACCESS_CP15(c14, 0, c1, 0)
77+
#define CNTV_CTL __ACCESS_CP15(c14, 0, c3, 1)
78+
#define CNTHCTL __ACCESS_CP15(c14, 4, c1, 0)
79+
80+
void __timer_save_state(struct kvm_vcpu *vcpu);
81+
void __timer_restore_state(struct kvm_vcpu *vcpu);
7482

7583
void __sysreg_save_state(struct kvm_cpu_context *ctxt);
7684
void __sysreg_restore_state(struct kvm_cpu_context *ctxt);

arch/arm/kvm/hyp/timer-sr.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (C) 2012-2015 - ARM Ltd
3+
* Author: Marc Zyngier <[email protected]>
4+
*
5+
* This program is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License version 2 as
7+
* published by the Free Software Foundation.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include <clocksource/arm_arch_timer.h>
19+
#include <linux/compiler.h>
20+
#include <linux/kvm_host.h>
21+
22+
#include <asm/kvm_mmu.h>
23+
24+
#include "hyp.h"
25+
26+
/* vcpu is already in the HYP VA space */
27+
void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu)
28+
{
29+
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
30+
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
31+
u64 val;
32+
33+
if (kvm->arch.timer.enabled) {
34+
timer->cntv_ctl = read_sysreg(CNTV_CTL);
35+
timer->cntv_cval = read_sysreg(CNTV_CVAL);
36+
}
37+
38+
/* Disable the virtual timer */
39+
write_sysreg(0, CNTV_CTL);
40+
41+
/* Allow physical timer/counter access for the host */
42+
val = read_sysreg(CNTHCTL);
43+
val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
44+
write_sysreg(val, CNTHCTL);
45+
46+
/* Clear cntvoff for the host */
47+
write_sysreg(0, CNTVOFF);
48+
}
49+
50+
void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu)
51+
{
52+
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
53+
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
54+
u64 val;
55+
56+
/*
57+
* Disallow physical timer access for the guest
58+
* Physical counter access is allowed
59+
*/
60+
val = read_sysreg(CNTHCTL);
61+
val &= ~CNTHCTL_EL1PCEN;
62+
val |= CNTHCTL_EL1PCTEN;
63+
write_sysreg(val, CNTHCTL);
64+
65+
if (kvm->arch.timer.enabled) {
66+
write_sysreg(kvm->arch.timer.cntvoff, CNTVOFF);
67+
write_sysreg(timer->cntv_cval, CNTV_CVAL);
68+
isb();
69+
write_sysreg(timer->cntv_ctl, CNTV_CTL);
70+
}
71+
}

0 commit comments

Comments
 (0)