aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJintack Lim <jintack@cs.columbia.edu>2017-02-03 10:20:03 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2017-02-08 10:13:34 -0500
commita91d18551e7b35e34a04b6fd199ca8568e7e9315 (patch)
tree77f47ef83c6ce0d35fbaf25e993ad6f264330d5f
parent009a5701bb2d166073f75643bc9237fe014c6bf5 (diff)
KVM: arm/arm64: Initialize the emulated EL1 physical timer
Initialize the emulated EL1 physical timer with the default irq number. Signed-off-by: Jintack Lim <jintack@cs.columbia.edu> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r--arch/arm/kvm/reset.c9
-rw-r--r--arch/arm64/kvm/reset.c9
-rw-r--r--include/kvm/arm_arch_timer.h3
-rw-r--r--virt/kvm/arm/arch_timer.c9
4 files changed, 25 insertions, 5 deletions
diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c
index 4b5e802e57d1..1da8b2d14550 100644
--- a/arch/arm/kvm/reset.c
+++ b/arch/arm/kvm/reset.c
@@ -37,6 +37,11 @@ static struct kvm_regs cortexa_regs_reset = {
37 .usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT, 37 .usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT,
38}; 38};
39 39
40static const struct kvm_irq_level cortexa_ptimer_irq = {
41 { .irq = 30 },
42 .level = 1,
43};
44
40static const struct kvm_irq_level cortexa_vtimer_irq = { 45static const struct kvm_irq_level cortexa_vtimer_irq = {
41 { .irq = 27 }, 46 { .irq = 27 },
42 .level = 1, 47 .level = 1,
@@ -58,6 +63,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
58{ 63{
59 struct kvm_regs *reset_regs; 64 struct kvm_regs *reset_regs;
60 const struct kvm_irq_level *cpu_vtimer_irq; 65 const struct kvm_irq_level *cpu_vtimer_irq;
66 const struct kvm_irq_level *cpu_ptimer_irq;
61 67
62 switch (vcpu->arch.target) { 68 switch (vcpu->arch.target) {
63 case KVM_ARM_TARGET_CORTEX_A7: 69 case KVM_ARM_TARGET_CORTEX_A7:
@@ -65,6 +71,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
65 reset_regs = &cortexa_regs_reset; 71 reset_regs = &cortexa_regs_reset;
66 vcpu->arch.midr = read_cpuid_id(); 72 vcpu->arch.midr = read_cpuid_id();
67 cpu_vtimer_irq = &cortexa_vtimer_irq; 73 cpu_vtimer_irq = &cortexa_vtimer_irq;
74 cpu_ptimer_irq = &cortexa_ptimer_irq;
68 break; 75 break;
69 default: 76 default:
70 return -ENODEV; 77 return -ENODEV;
@@ -77,5 +84,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
77 kvm_reset_coprocs(vcpu); 84 kvm_reset_coprocs(vcpu);
78 85
79 /* Reset arch_timer context */ 86 /* Reset arch_timer context */
80 return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq); 87 return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq, cpu_ptimer_irq);
81} 88}
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index e95d4f68bf54..d9e9697de1b2 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -46,6 +46,11 @@ static const struct kvm_regs default_regs_reset32 = {
46 COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT), 46 COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT),
47}; 47};
48 48
49static const struct kvm_irq_level default_ptimer_irq = {
50 .irq = 30,
51 .level = 1,
52};
53
49static const struct kvm_irq_level default_vtimer_irq = { 54static const struct kvm_irq_level default_vtimer_irq = {
50 .irq = 27, 55 .irq = 27,
51 .level = 1, 56 .level = 1,
@@ -104,6 +109,7 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
104int kvm_reset_vcpu(struct kvm_vcpu *vcpu) 109int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
105{ 110{
106 const struct kvm_irq_level *cpu_vtimer_irq; 111 const struct kvm_irq_level *cpu_vtimer_irq;
112 const struct kvm_irq_level *cpu_ptimer_irq;
107 const struct kvm_regs *cpu_reset; 113 const struct kvm_regs *cpu_reset;
108 114
109 switch (vcpu->arch.target) { 115 switch (vcpu->arch.target) {
@@ -117,6 +123,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
117 } 123 }
118 124
119 cpu_vtimer_irq = &default_vtimer_irq; 125 cpu_vtimer_irq = &default_vtimer_irq;
126 cpu_ptimer_irq = &default_ptimer_irq;
120 break; 127 break;
121 } 128 }
122 129
@@ -130,5 +137,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
130 kvm_pmu_vcpu_reset(vcpu); 137 kvm_pmu_vcpu_reset(vcpu);
131 138
132 /* Reset timer */ 139 /* Reset timer */
133 return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq); 140 return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq, cpu_ptimer_irq);
134} 141}
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 6445a3d9a6e2..f1d2fba0b9c6 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -58,7 +58,8 @@ struct arch_timer_cpu {
58int kvm_timer_hyp_init(void); 58int kvm_timer_hyp_init(void);
59int kvm_timer_enable(struct kvm_vcpu *vcpu); 59int kvm_timer_enable(struct kvm_vcpu *vcpu);
60int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, 60int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
61 const struct kvm_irq_level *irq); 61 const struct kvm_irq_level *virt_irq,
62 const struct kvm_irq_level *phys_irq);
62void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); 63void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
63void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu); 64void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu);
64void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu); 65void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 5261f98ae686..dbd0af19d27e 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -327,9 +327,11 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
327} 327}
328 328
329int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, 329int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
330 const struct kvm_irq_level *irq) 330 const struct kvm_irq_level *virt_irq,
331 const struct kvm_irq_level *phys_irq)
331{ 332{
332 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); 333 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
334 struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
333 335
334 /* 336 /*
335 * The vcpu timer irq number cannot be determined in 337 * The vcpu timer irq number cannot be determined in
@@ -337,7 +339,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
337 * kvm_vcpu_set_target(). To handle this, we determine 339 * kvm_vcpu_set_target(). To handle this, we determine
338 * vcpu timer irq number when the vcpu is reset. 340 * vcpu timer irq number when the vcpu is reset.
339 */ 341 */
340 vtimer->irq.irq = irq->irq; 342 vtimer->irq.irq = virt_irq->irq;
343 ptimer->irq.irq = phys_irq->irq;
341 344
342 /* 345 /*
343 * The bits in CNTV_CTL are architecturally reset to UNKNOWN for ARMv8 346 * The bits in CNTV_CTL are architecturally reset to UNKNOWN for ARMv8
@@ -346,6 +349,7 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
346 * the ARMv7 architecture. 349 * the ARMv7 architecture.
347 */ 350 */
348 vtimer->cnt_ctl = 0; 351 vtimer->cnt_ctl = 0;
352 ptimer->cnt_ctl = 0;
349 kvm_timer_update_state(vcpu); 353 kvm_timer_update_state(vcpu);
350 354
351 return 0; 355 return 0;
@@ -376,6 +380,7 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
376 380
377 /* Synchronize cntvoff across all vtimers of a VM. */ 381 /* Synchronize cntvoff across all vtimers of a VM. */
378 update_vtimer_cntvoff(vcpu, kvm_phys_timer_read()); 382 update_vtimer_cntvoff(vcpu, kvm_phys_timer_read());
383 vcpu_ptimer(vcpu)->cntvoff = 0;
379 384
380 INIT_WORK(&timer->expired, kvm_timer_inject_irq_work); 385 INIT_WORK(&timer->expired, kvm_timer_inject_irq_work);
381 hrtimer_init(&timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 386 hrtimer_init(&timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);