Add some very minimal architected timer related infrastructure. For the moment, we just provide empty structures, and enable/disable access to the physical timer across world switch. Signed-off-by: Marc Zyngier <marc.zyngier at arm.com> --- arch/arm/include/asm/kvm_arch_timer.h | 27 +++++++++++++++++++++++++++ arch/arm/include/asm/kvm_host.h | 5 +++++ arch/arm/kvm/interrupts.S | 23 ++++++++++++++++++++++- 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/kvm_arch_timer.h diff --git a/arch/arm/include/asm/kvm_arch_timer.h b/arch/arm/include/asm/kvm_arch_timer.h new file mode 100644 index 0000000..491e336 --- /dev/null +++ b/arch/arm/include/asm/kvm_arch_timer.h @@ -0,0 +1,27 @@ +#ifndef __ASM_ARM_KVM_ARCH_TIMER_H +#define __ASM_ARM_KVM_ARCH_TIMER_H + +struct arch_timer_kvm { +}; + +struct arch_timer_cpu { +}; + +#ifndef CONFIG_KVM_ARM_TIMER +static inline int kvm_timer_hyp_init(void) +{ + return 0; +}; + +static inline int kvm_timer_init(struct kvm *kvm) +{ + return 0; +} + +static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {} +static inline void kvm_timer_sync_to_cpu(struct kvm_vcpu *vcpu) {} +static inline void kvm_timer_sync_from_cpu(struct kvm_vcpu *vcpu) {} +static inline void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) {} +#endif + +#endif diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 3b289b8..2e7364c 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -25,6 +25,7 @@ #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 #include <asm/kvm_vgic.h> +#include <asm/kvm_arch_timer.h> /* We don't currently support large pages. */ #define KVM_HPAGE_GFN_SHIFT(x) 0 @@ -50,6 +51,9 @@ struct kvm_arch { /* Interrupt controller */ struct vgic_dist vgic; + + /* Timer */ + struct arch_timer_kvm timer; }; #define EXCEPTION_NONE 0 @@ -133,6 +137,7 @@ struct kvm_vcpu_arch { /* VGIC state */ struct vgic_cpu vgic_cpu; + struct arch_timer_cpu timer_cpu; }; struct kvm_vm_stat { diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index 40c3c9f..1b03b79 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S @@ -342,7 +342,26 @@ ENDPROC(__kvm_flush_vm_context) 2: #endif .endm - + +#define PL1P_ENABLE 3 +#define PL1P_DISABLE 3 + +.macro save_timer_state vcpup + @ Allow physical timer access for the host + mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL + orr r2, r2, #PL1P_ENABLE + mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL +.endm + +.macro restore_timer_state vcpup + @ Disallow physical timer access for the guest + mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL + bic r2, r2, #PL1P_DISABLE + mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL + + isb +.endm + /* Configures the HSTR (Hyp System Trap Register) on entry/return * (hardware reset value is 0) */ .macro set_hstr entry @@ -401,6 +420,7 @@ ENTRY(__kvm_vcpu_run) store_mode_state sp, fiq restore_vgic_state r0 + restore_timer_state r0 @ Store hardware CP15 state and load guest state read_cp15_state @@ -490,6 +510,7 @@ __kvm_vcpu_return: read_cp15_state 1, r1 write_cp15_state + save_timer_state r1 save_vgic_state r1 load_mode_state sp, fiq -- 1.7.10.3