aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/kvm/arm_arch_timer.h27
-rw-r--r--virt/kvm/arm/arch_timer.c69
-rw-r--r--virt/kvm/arm/hyp/timer-sr.c10
3 files changed, 56 insertions, 50 deletions
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 5c970ce67949..daad3c133b9f 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -28,15 +28,20 @@ struct arch_timer_kvm {
28 u64 cntvoff; 28 u64 cntvoff;
29}; 29};
30 30
31struct arch_timer_cpu { 31struct arch_timer_context {
32 /* Registers: control register, timer value */ 32 /* Registers: control register, timer value */
33 u32 cntv_ctl; /* Saved/restored */ 33 u32 cnt_ctl;
34 u64 cntv_cval; /* Saved/restored */ 34 u64 cnt_cval;
35
36 /* Timer IRQ */
37 struct kvm_irq_level irq;
38
39 /* Active IRQ state caching */
40 bool active_cleared_last;
41};
35 42
36 /* 43struct arch_timer_cpu {
37 * Anything that is not used directly from assembly code goes 44 struct arch_timer_context vtimer;
38 * here.
39 */
40 45
41 /* Background timer used when the guest is not running */ 46 /* Background timer used when the guest is not running */
42 struct hrtimer timer; 47 struct hrtimer timer;
@@ -47,12 +52,6 @@ struct arch_timer_cpu {
47 /* Background timer active */ 52 /* Background timer active */
48 bool armed; 53 bool armed;
49 54
50 /* Timer IRQ */
51 struct kvm_irq_level irq;
52
53 /* Active IRQ state caching */
54 bool active_cleared_last;
55
56 /* Is the timer enabled */ 55 /* Is the timer enabled */
57 bool enabled; 56 bool enabled;
58}; 57};
@@ -77,4 +76,6 @@ void kvm_timer_unschedule(struct kvm_vcpu *vcpu);
77void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu); 76void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu);
78 77
79void kvm_timer_init_vhe(void); 78void kvm_timer_init_vhe(void);
79
80#define vcpu_vtimer(v) (&(v)->arch.timer_cpu.vtimer)
80#endif 81#endif
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 91ecf48f7fe2..d3556b3ca694 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -37,7 +37,7 @@ static u32 host_vtimer_irq_flags;
37 37
38void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu) 38void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
39{ 39{
40 vcpu->arch.timer_cpu.active_cleared_last = false; 40 vcpu_vtimer(vcpu)->active_cleared_last = false;
41} 41}
42 42
43static u64 kvm_phys_timer_read(void) 43static u64 kvm_phys_timer_read(void)
@@ -102,7 +102,7 @@ static u64 kvm_timer_compute_delta(struct kvm_vcpu *vcpu)
102{ 102{
103 u64 cval, now; 103 u64 cval, now;
104 104
105 cval = vcpu->arch.timer_cpu.cntv_cval; 105 cval = vcpu_vtimer(vcpu)->cnt_cval;
106 now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; 106 now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff;
107 107
108 if (now < cval) { 108 if (now < cval) {
@@ -144,21 +144,21 @@ static enum hrtimer_restart kvm_timer_expire(struct hrtimer *hrt)
144 144
145static bool kvm_timer_irq_can_fire(struct kvm_vcpu *vcpu) 145static bool kvm_timer_irq_can_fire(struct kvm_vcpu *vcpu)
146{ 146{
147 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 147 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
148 148
149 return !(timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) && 149 return !(vtimer->cnt_ctl & ARCH_TIMER_CTRL_IT_MASK) &&
150 (timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE); 150 (vtimer->cnt_ctl & ARCH_TIMER_CTRL_ENABLE);
151} 151}
152 152
153bool kvm_timer_should_fire(struct kvm_vcpu *vcpu) 153bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
154{ 154{
155 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 155 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
156 u64 cval, now; 156 u64 cval, now;
157 157
158 if (!kvm_timer_irq_can_fire(vcpu)) 158 if (!kvm_timer_irq_can_fire(vcpu))
159 return false; 159 return false;
160 160
161 cval = timer->cntv_cval; 161 cval = vtimer->cnt_cval;
162 now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; 162 now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff;
163 163
164 return cval <= now; 164 return cval <= now;
@@ -167,18 +167,18 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
167static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level) 167static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
168{ 168{
169 int ret; 169 int ret;
170 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 170 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
171 171
172 BUG_ON(!vgic_initialized(vcpu->kvm)); 172 BUG_ON(!vgic_initialized(vcpu->kvm));
173 173
174 timer->active_cleared_last = false; 174 vtimer->active_cleared_last = false;
175 timer->irq.level = new_level; 175 vtimer->irq.level = new_level;
176 trace_kvm_timer_update_irq(vcpu->vcpu_id, timer->irq.irq, 176 trace_kvm_timer_update_irq(vcpu->vcpu_id, vtimer->irq.irq,
177 timer->irq.level); 177 vtimer->irq.level);
178 178
179 ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, 179 ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
180 timer->irq.irq, 180 vtimer->irq.irq,
181 timer->irq.level); 181 vtimer->irq.level);
182 WARN_ON(ret); 182 WARN_ON(ret);
183} 183}
184 184
@@ -189,18 +189,19 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
189static int kvm_timer_update_state(struct kvm_vcpu *vcpu) 189static int kvm_timer_update_state(struct kvm_vcpu *vcpu)
190{ 190{
191 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 191 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
192 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
192 193
193 /* 194 /*
194 * If userspace modified the timer registers via SET_ONE_REG before 195 * If userspace modified the timer registers via SET_ONE_REG before
195 * the vgic was initialized, we mustn't set the timer->irq.level value 196 * the vgic was initialized, we mustn't set the vtimer->irq.level value
196 * because the guest would never see the interrupt. Instead wait 197 * because the guest would never see the interrupt. Instead wait
197 * until we call this function from kvm_timer_flush_hwstate. 198 * until we call this function from kvm_timer_flush_hwstate.
198 */ 199 */
199 if (!vgic_initialized(vcpu->kvm) || !timer->enabled) 200 if (!vgic_initialized(vcpu->kvm) || !timer->enabled)
200 return -ENODEV; 201 return -ENODEV;
201 202
202 if (kvm_timer_should_fire(vcpu) != timer->irq.level) 203 if (kvm_timer_should_fire(vcpu) != vtimer->irq.level)
203 kvm_timer_update_irq(vcpu, !timer->irq.level); 204 kvm_timer_update_irq(vcpu, !vtimer->irq.level);
204 205
205 return 0; 206 return 0;
206} 207}
@@ -250,7 +251,7 @@ void kvm_timer_unschedule(struct kvm_vcpu *vcpu)
250 */ 251 */
251void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) 252void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
252{ 253{
253 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 254 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
254 bool phys_active; 255 bool phys_active;
255 int ret; 256 int ret;
256 257
@@ -274,8 +275,8 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
274 * to ensure that hardware interrupts from the timer triggers a guest 275 * to ensure that hardware interrupts from the timer triggers a guest
275 * exit. 276 * exit.
276 */ 277 */
277 phys_active = timer->irq.level || 278 phys_active = vtimer->irq.level ||
278 kvm_vgic_map_is_active(vcpu, timer->irq.irq); 279 kvm_vgic_map_is_active(vcpu, vtimer->irq.irq);
279 280
280 /* 281 /*
281 * We want to avoid hitting the (re)distributor as much as 282 * We want to avoid hitting the (re)distributor as much as
@@ -297,7 +298,7 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
297 * - cached value is "active clear" 298 * - cached value is "active clear"
298 * - value to be programmed is "active clear" 299 * - value to be programmed is "active clear"
299 */ 300 */
300 if (timer->active_cleared_last && !phys_active) 301 if (vtimer->active_cleared_last && !phys_active)
301 return; 302 return;
302 303
303 ret = irq_set_irqchip_state(host_vtimer_irq, 304 ret = irq_set_irqchip_state(host_vtimer_irq,
@@ -305,7 +306,7 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
305 phys_active); 306 phys_active);
306 WARN_ON(ret); 307 WARN_ON(ret);
307 308
308 timer->active_cleared_last = !phys_active; 309 vtimer->active_cleared_last = !phys_active;
309} 310}
310 311
311/** 312/**
@@ -331,7 +332,7 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
331int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, 332int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
332 const struct kvm_irq_level *irq) 333 const struct kvm_irq_level *irq)
333{ 334{
334 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 335 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
335 336
336 /* 337 /*
337 * The vcpu timer irq number cannot be determined in 338 * The vcpu timer irq number cannot be determined in
@@ -339,7 +340,7 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
339 * kvm_vcpu_set_target(). To handle this, we determine 340 * kvm_vcpu_set_target(). To handle this, we determine
340 * vcpu timer irq number when the vcpu is reset. 341 * vcpu timer irq number when the vcpu is reset.
341 */ 342 */
342 timer->irq.irq = irq->irq; 343 vtimer->irq.irq = irq->irq;
343 344
344 /* 345 /*
345 * 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
@@ -347,7 +348,7 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
347 * resets the timer to be disabled and unmasked and is compliant with 348 * resets the timer to be disabled and unmasked and is compliant with
348 * the ARMv7 architecture. 349 * the ARMv7 architecture.
349 */ 350 */
350 timer->cntv_ctl = 0; 351 vtimer->cnt_ctl = 0;
351 kvm_timer_update_state(vcpu); 352 kvm_timer_update_state(vcpu);
352 353
353 return 0; 354 return 0;
@@ -369,17 +370,17 @@ static void kvm_timer_init_interrupt(void *info)
369 370
370int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) 371int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
371{ 372{
372 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 373 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
373 374
374 switch (regid) { 375 switch (regid) {
375 case KVM_REG_ARM_TIMER_CTL: 376 case KVM_REG_ARM_TIMER_CTL:
376 timer->cntv_ctl = value; 377 vtimer->cnt_ctl = value;
377 break; 378 break;
378 case KVM_REG_ARM_TIMER_CNT: 379 case KVM_REG_ARM_TIMER_CNT:
379 vcpu->kvm->arch.timer.cntvoff = kvm_phys_timer_read() - value; 380 vcpu->kvm->arch.timer.cntvoff = kvm_phys_timer_read() - value;
380 break; 381 break;
381 case KVM_REG_ARM_TIMER_CVAL: 382 case KVM_REG_ARM_TIMER_CVAL:
382 timer->cntv_cval = value; 383 vtimer->cnt_cval = value;
383 break; 384 break;
384 default: 385 default:
385 return -1; 386 return -1;
@@ -391,15 +392,15 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
391 392
392u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid) 393u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
393{ 394{
394 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 395 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
395 396
396 switch (regid) { 397 switch (regid) {
397 case KVM_REG_ARM_TIMER_CTL: 398 case KVM_REG_ARM_TIMER_CTL:
398 return timer->cntv_ctl; 399 return vtimer->cnt_ctl;
399 case KVM_REG_ARM_TIMER_CNT: 400 case KVM_REG_ARM_TIMER_CNT:
400 return kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; 401 return kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff;
401 case KVM_REG_ARM_TIMER_CVAL: 402 case KVM_REG_ARM_TIMER_CVAL:
402 return timer->cntv_cval; 403 return vtimer->cnt_cval;
403 } 404 }
404 return (u64)-1; 405 return (u64)-1;
405} 406}
@@ -463,14 +464,16 @@ int kvm_timer_hyp_init(void)
463void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) 464void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
464{ 465{
465 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 466 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
467 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
466 468
467 timer_disarm(timer); 469 timer_disarm(timer);
468 kvm_vgic_unmap_phys_irq(vcpu, timer->irq.irq); 470 kvm_vgic_unmap_phys_irq(vcpu, vtimer->irq.irq);
469} 471}
470 472
471int kvm_timer_enable(struct kvm_vcpu *vcpu) 473int kvm_timer_enable(struct kvm_vcpu *vcpu)
472{ 474{
473 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 475 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
476 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
474 struct irq_desc *desc; 477 struct irq_desc *desc;
475 struct irq_data *data; 478 struct irq_data *data;
476 int phys_irq; 479 int phys_irq;
@@ -498,7 +501,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
498 * Tell the VGIC that the virtual interrupt is tied to a 501 * Tell the VGIC that the virtual interrupt is tied to a
499 * physical interrupt. We do that once per VCPU. 502 * physical interrupt. We do that once per VCPU.
500 */ 503 */
501 ret = kvm_vgic_map_phys_irq(vcpu, timer->irq.irq, phys_irq); 504 ret = kvm_vgic_map_phys_irq(vcpu, vtimer->irq.irq, phys_irq);
502 if (ret) 505 if (ret)
503 return ret; 506 return ret;
504 507
diff --git a/virt/kvm/arm/hyp/timer-sr.c b/virt/kvm/arm/hyp/timer-sr.c
index 63e28dd18bb0..0cf08953e81c 100644
--- a/virt/kvm/arm/hyp/timer-sr.c
+++ b/virt/kvm/arm/hyp/timer-sr.c
@@ -25,11 +25,12 @@
25void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu) 25void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu)
26{ 26{
27 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 27 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
28 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
28 u64 val; 29 u64 val;
29 30
30 if (timer->enabled) { 31 if (timer->enabled) {
31 timer->cntv_ctl = read_sysreg_el0(cntv_ctl); 32 vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl);
32 timer->cntv_cval = read_sysreg_el0(cntv_cval); 33 vtimer->cnt_cval = read_sysreg_el0(cntv_cval);
33 } 34 }
34 35
35 /* Disable the virtual timer */ 36 /* Disable the virtual timer */
@@ -54,6 +55,7 @@ void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu)
54{ 55{
55 struct kvm *kvm = kern_hyp_va(vcpu->kvm); 56 struct kvm *kvm = kern_hyp_va(vcpu->kvm);
56 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 57 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
58 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
57 u64 val; 59 u64 val;
58 60
59 /* Those bits are already configured at boot on VHE-system */ 61 /* Those bits are already configured at boot on VHE-system */
@@ -70,8 +72,8 @@ void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu)
70 72
71 if (timer->enabled) { 73 if (timer->enabled) {
72 write_sysreg(kvm->arch.timer.cntvoff, cntvoff_el2); 74 write_sysreg(kvm->arch.timer.cntvoff, cntvoff_el2);
73 write_sysreg_el0(timer->cntv_cval, cntv_cval); 75 write_sysreg_el0(vtimer->cnt_cval, cntv_cval);
74 isb(); 76 isb();
75 write_sysreg_el0(timer->cntv_ctl, cntv_ctl); 77 write_sysreg_el0(vtimer->cnt_ctl, cntv_ctl);
76 } 78 }
77} 79}