aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kvm
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2012-12-07 12:52:03 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2013-06-12 11:40:32 -0400
commit003300de6c3e51934fb52eb2677f6f4fb4996cbd (patch)
tree1d214ebdd5cdcc9f86a0a44c6670a55c4da7f53f /arch/arm64/kvm
parentf61701e0a24a09aa4a44baf24e57dcc5e706afa8 (diff)
arm64: KVM: Plug the arch timer
Add support for the in-kernel timer emulation. Reviewed-by: Christopher Covington <cov@codeaurora.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm64/kvm')
-rw-r--r--arch/arm64/kvm/hyp.S56
-rw-r--r--arch/arm64/kvm/reset.c12
2 files changed, 68 insertions, 0 deletions
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 8dc27a367d77..8b510835b440 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -390,6 +390,60 @@ __kvm_hyp_code_start:
3902: 3902:
391.endm 391.endm
392 392
393.macro save_timer_state
394 // x0: vcpu pointer
395 ldr x2, [x0, #VCPU_KVM]
396 kern_hyp_va x2
397 ldr w3, [x2, #KVM_TIMER_ENABLED]
398 cbz w3, 1f
399
400 mrs x3, cntv_ctl_el0
401 and x3, x3, #3
402 str w3, [x0, #VCPU_TIMER_CNTV_CTL]
403 bic x3, x3, #1 // Clear Enable
404 msr cntv_ctl_el0, x3
405
406 isb
407
408 mrs x3, cntv_cval_el0
409 str x3, [x0, #VCPU_TIMER_CNTV_CVAL]
410
4111:
412 // Allow physical timer/counter access for the host
413 mrs x2, cnthctl_el2
414 orr x2, x2, #3
415 msr cnthctl_el2, x2
416
417 // Clear cntvoff for the host
418 msr cntvoff_el2, xzr
419.endm
420
421.macro restore_timer_state
422 // x0: vcpu pointer
423 // Disallow physical timer access for the guest
424 // Physical counter access is allowed
425 mrs x2, cnthctl_el2
426 orr x2, x2, #1
427 bic x2, x2, #2
428 msr cnthctl_el2, x2
429
430 ldr x2, [x0, #VCPU_KVM]
431 kern_hyp_va x2
432 ldr w3, [x2, #KVM_TIMER_ENABLED]
433 cbz w3, 1f
434
435 ldr x3, [x2, #KVM_TIMER_CNTVOFF]
436 msr cntvoff_el2, x3
437 ldr x2, [x0, #VCPU_TIMER_CNTV_CVAL]
438 msr cntv_cval_el0, x2
439 isb
440
441 ldr w2, [x0, #VCPU_TIMER_CNTV_CTL]
442 and x2, x2, #3
443 msr cntv_ctl_el0, x2
4441:
445.endm
446
393__save_sysregs: 447__save_sysregs:
394 save_sysregs 448 save_sysregs
395 ret 449 ret
@@ -433,6 +487,7 @@ ENTRY(__kvm_vcpu_run)
433 activate_vm 487 activate_vm
434 488
435 restore_vgic_state 489 restore_vgic_state
490 restore_timer_state
436 491
437 // Guest context 492 // Guest context
438 add x2, x0, #VCPU_CONTEXT 493 add x2, x0, #VCPU_CONTEXT
@@ -455,6 +510,7 @@ __kvm_vcpu_return:
455 bl __save_fpsimd 510 bl __save_fpsimd
456 bl __save_sysregs 511 bl __save_sysregs
457 512
513 save_timer_state
458 save_vgic_state 514 save_vgic_state
459 515
460 deactivate_traps 516 deactivate_traps
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index f6536a06231a..766150ac76ed 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -23,6 +23,8 @@
23#include <linux/kvm_host.h> 23#include <linux/kvm_host.h>
24#include <linux/kvm.h> 24#include <linux/kvm.h>
25 25
26#include <kvm/arm_arch_timer.h>
27
26#include <asm/cputype.h> 28#include <asm/cputype.h>
27#include <asm/ptrace.h> 29#include <asm/ptrace.h>
28#include <asm/kvm_arm.h> 30#include <asm/kvm_arm.h>
@@ -36,6 +38,11 @@ static const struct kvm_regs default_regs_reset = {
36 PSR_F_BIT | PSR_D_BIT), 38 PSR_F_BIT | PSR_D_BIT),
37}; 39};
38 40
41static const struct kvm_irq_level default_vtimer_irq = {
42 .irq = 27,
43 .level = 1,
44};
45
39int kvm_arch_dev_ioctl_check_extension(long ext) 46int kvm_arch_dev_ioctl_check_extension(long ext)
40{ 47{
41 int r; 48 int r;
@@ -58,11 +65,13 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
58 */ 65 */
59int kvm_reset_vcpu(struct kvm_vcpu *vcpu) 66int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
60{ 67{
68 const struct kvm_irq_level *cpu_vtimer_irq;
61 const struct kvm_regs *cpu_reset; 69 const struct kvm_regs *cpu_reset;
62 70
63 switch (vcpu->arch.target) { 71 switch (vcpu->arch.target) {
64 default: 72 default:
65 cpu_reset = &default_regs_reset; 73 cpu_reset = &default_regs_reset;
74 cpu_vtimer_irq = &default_vtimer_irq;
66 break; 75 break;
67 } 76 }
68 77
@@ -72,5 +81,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
72 /* Reset system registers */ 81 /* Reset system registers */
73 kvm_reset_sys_regs(vcpu); 82 kvm_reset_sys_regs(vcpu);
74 83
84 /* Reset timer */
85 kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
86
75 return 0; 87 return 0;
76} 88}