diff options
author | Jintack Lim <jintack@cs.columbia.edu> | 2017-02-03 10:20:03 -0500 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2017-02-08 10:13:34 -0500 |
commit | a91d18551e7b35e34a04b6fd199ca8568e7e9315 (patch) | |
tree | 77f47ef83c6ce0d35fbaf25e993ad6f264330d5f | |
parent | 009a5701bb2d166073f75643bc9237fe014c6bf5 (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.c | 9 | ||||
-rw-r--r-- | arch/arm64/kvm/reset.c | 9 | ||||
-rw-r--r-- | include/kvm/arm_arch_timer.h | 3 | ||||
-rw-r--r-- | virt/kvm/arm/arch_timer.c | 9 |
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 | ||
40 | static const struct kvm_irq_level cortexa_ptimer_irq = { | ||
41 | { .irq = 30 }, | ||
42 | .level = 1, | ||
43 | }; | ||
44 | |||
40 | static const struct kvm_irq_level cortexa_vtimer_irq = { | 45 | static 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 | ||
49 | static const struct kvm_irq_level default_ptimer_irq = { | ||
50 | .irq = 30, | ||
51 | .level = 1, | ||
52 | }; | ||
53 | |||
49 | static const struct kvm_irq_level default_vtimer_irq = { | 54 | static 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) | |||
104 | int kvm_reset_vcpu(struct kvm_vcpu *vcpu) | 109 | int 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 { | |||
58 | int kvm_timer_hyp_init(void); | 58 | int kvm_timer_hyp_init(void); |
59 | int kvm_timer_enable(struct kvm_vcpu *vcpu); | 59 | int kvm_timer_enable(struct kvm_vcpu *vcpu); |
60 | int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, | 60 | int 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); | ||
62 | void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); | 63 | void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); |
63 | void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu); | 64 | void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu); |
64 | void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu); | 65 | void 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 | ||
329 | int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, | 329 | int 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); |