aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJintack Lim <jintack@cs.columbia.edu>2017-02-03 10:19:59 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2017-02-08 10:13:32 -0500
commitfbb4aeec5fc2ab47615b2a0cbabc503e1eef4c60 (patch)
treec4393d9305a159691d9af8ff6393fb8ed0753416
parent0bdbf3b071986ba80731203683cf623d5c0cacb1 (diff)
KVM: arm/arm64: Abstract virtual timer context into separate structure
Abstract virtual timer context into a separate structure and change all callers referring to timer registers, irq state and so on. No change in functionality. This is about to become very handy when adding the EL1 physical timer. Signed-off-by: Jintack Lim <jintack@cs.columbia.edu> Acked-by: Christoffer Dall <christoffer.dall@linaro.org> Acked-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-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}