Loading arch/arm64/kvm/hyp.S +56 −0 Original line number Diff line number Diff line Loading @@ -390,6 +390,60 @@ __kvm_hyp_code_start: 2: .endm .macro save_timer_state // x0: vcpu pointer ldr x2, [x0, #VCPU_KVM] kern_hyp_va x2 ldr w3, [x2, #KVM_TIMER_ENABLED] cbz w3, 1f mrs x3, cntv_ctl_el0 and x3, x3, #3 str w3, [x0, #VCPU_TIMER_CNTV_CTL] bic x3, x3, #1 // Clear Enable msr cntv_ctl_el0, x3 isb mrs x3, cntv_cval_el0 str x3, [x0, #VCPU_TIMER_CNTV_CVAL] 1: // Allow physical timer/counter access for the host mrs x2, cnthctl_el2 orr x2, x2, #3 msr cnthctl_el2, x2 // Clear cntvoff for the host msr cntvoff_el2, xzr .endm .macro restore_timer_state // x0: vcpu pointer // Disallow physical timer access for the guest // Physical counter access is allowed mrs x2, cnthctl_el2 orr x2, x2, #1 bic x2, x2, #2 msr cnthctl_el2, x2 ldr x2, [x0, #VCPU_KVM] kern_hyp_va x2 ldr w3, [x2, #KVM_TIMER_ENABLED] cbz w3, 1f ldr x3, [x2, #KVM_TIMER_CNTVOFF] msr cntvoff_el2, x3 ldr x2, [x0, #VCPU_TIMER_CNTV_CVAL] msr cntv_cval_el0, x2 isb ldr w2, [x0, #VCPU_TIMER_CNTV_CTL] and x2, x2, #3 msr cntv_ctl_el0, x2 1: .endm __save_sysregs: save_sysregs ret Loading Loading @@ -433,6 +487,7 @@ ENTRY(__kvm_vcpu_run) activate_vm restore_vgic_state restore_timer_state // Guest context add x2, x0, #VCPU_CONTEXT Loading @@ -455,6 +510,7 @@ __kvm_vcpu_return: bl __save_fpsimd bl __save_sysregs save_timer_state save_vgic_state deactivate_traps Loading arch/arm64/kvm/reset.c +12 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include <linux/kvm_host.h> #include <linux/kvm.h> #include <kvm/arm_arch_timer.h> #include <asm/cputype.h> #include <asm/ptrace.h> #include <asm/kvm_arm.h> Loading @@ -36,6 +38,11 @@ static const struct kvm_regs default_regs_reset = { PSR_F_BIT | PSR_D_BIT), }; static const struct kvm_irq_level default_vtimer_irq = { .irq = 27, .level = 1, }; int kvm_arch_dev_ioctl_check_extension(long ext) { int r; Loading @@ -58,11 +65,13 @@ int kvm_arch_dev_ioctl_check_extension(long ext) */ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) { const struct kvm_irq_level *cpu_vtimer_irq; const struct kvm_regs *cpu_reset; switch (vcpu->arch.target) { default: cpu_reset = &default_regs_reset; cpu_vtimer_irq = &default_vtimer_irq; break; } Loading @@ -72,5 +81,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) /* Reset system registers */ kvm_reset_sys_regs(vcpu); /* Reset timer */ kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq); return 0; } Loading
arch/arm64/kvm/hyp.S +56 −0 Original line number Diff line number Diff line Loading @@ -390,6 +390,60 @@ __kvm_hyp_code_start: 2: .endm .macro save_timer_state // x0: vcpu pointer ldr x2, [x0, #VCPU_KVM] kern_hyp_va x2 ldr w3, [x2, #KVM_TIMER_ENABLED] cbz w3, 1f mrs x3, cntv_ctl_el0 and x3, x3, #3 str w3, [x0, #VCPU_TIMER_CNTV_CTL] bic x3, x3, #1 // Clear Enable msr cntv_ctl_el0, x3 isb mrs x3, cntv_cval_el0 str x3, [x0, #VCPU_TIMER_CNTV_CVAL] 1: // Allow physical timer/counter access for the host mrs x2, cnthctl_el2 orr x2, x2, #3 msr cnthctl_el2, x2 // Clear cntvoff for the host msr cntvoff_el2, xzr .endm .macro restore_timer_state // x0: vcpu pointer // Disallow physical timer access for the guest // Physical counter access is allowed mrs x2, cnthctl_el2 orr x2, x2, #1 bic x2, x2, #2 msr cnthctl_el2, x2 ldr x2, [x0, #VCPU_KVM] kern_hyp_va x2 ldr w3, [x2, #KVM_TIMER_ENABLED] cbz w3, 1f ldr x3, [x2, #KVM_TIMER_CNTVOFF] msr cntvoff_el2, x3 ldr x2, [x0, #VCPU_TIMER_CNTV_CVAL] msr cntv_cval_el0, x2 isb ldr w2, [x0, #VCPU_TIMER_CNTV_CTL] and x2, x2, #3 msr cntv_ctl_el0, x2 1: .endm __save_sysregs: save_sysregs ret Loading Loading @@ -433,6 +487,7 @@ ENTRY(__kvm_vcpu_run) activate_vm restore_vgic_state restore_timer_state // Guest context add x2, x0, #VCPU_CONTEXT Loading @@ -455,6 +510,7 @@ __kvm_vcpu_return: bl __save_fpsimd bl __save_sysregs save_timer_state save_vgic_state deactivate_traps Loading
arch/arm64/kvm/reset.c +12 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include <linux/kvm_host.h> #include <linux/kvm.h> #include <kvm/arm_arch_timer.h> #include <asm/cputype.h> #include <asm/ptrace.h> #include <asm/kvm_arm.h> Loading @@ -36,6 +38,11 @@ static const struct kvm_regs default_regs_reset = { PSR_F_BIT | PSR_D_BIT), }; static const struct kvm_irq_level default_vtimer_irq = { .irq = 27, .level = 1, }; int kvm_arch_dev_ioctl_check_extension(long ext) { int r; Loading @@ -58,11 +65,13 @@ int kvm_arch_dev_ioctl_check_extension(long ext) */ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) { const struct kvm_irq_level *cpu_vtimer_irq; const struct kvm_regs *cpu_reset; switch (vcpu->arch.target) { default: cpu_reset = &default_regs_reset; cpu_vtimer_irq = &default_vtimer_irq; break; } Loading @@ -72,5 +81,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) /* Reset system registers */ kvm_reset_sys_regs(vcpu); /* Reset timer */ kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq); return 0; }