On Mon, May 14, 2012 at 9:07 AM, Marc Zyngier <marc.zyngier at arm.com> wrote: > 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 deletions(-) > ?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 ffef12b..44ce5b5 100644 > --- a/arch/arm/include/asm/kvm_host.h > +++ b/arch/arm/include/asm/kvm_host.h > @@ -23,6 +23,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 > @@ -45,6 +46,9 @@ struct kvm_arch { > > ? ? ? ?/* Interrupt controller */ > ? ? ? ?struct vgic_dist ? ? ? ?vgic; > + > + ? ? ? /* Timer */ > + ? ? ? struct arch_timer_kvm ? timer; > ?}; > > ?#define EXCEPTION_NONE ? ? ?0 > @@ -111,6 +115,7 @@ struct kvm_vcpu_arch { > ? ? ? ?u32 irq_lines; ? ? ? ? ?/* IRQ and FIQ levels */ > ? ? ? ?u32 wait_for_interrupts; > ? ? ? ?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 541532b..56a65c4 100644 > --- a/arch/arm/kvm/interrupts.S > +++ b/arch/arm/kvm/interrupts.S > @@ -311,7 +311,26 @@ ENTRY(__kvm_flush_vm_context) > ?2: > ?#endif > ?.endm > - > + > +#define PL1P_ENABLE ? ?3 > +#define PL1P_DISABLE ? 3 nit: this is weird, I think it should be PL1P_MASK and just have a comment below > + > +.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 nit: consider using the commenting format from the corresponding vgic macros with a @vcpup parameter description for consistency. > + > ?/* Configures the HSTR (Hyp System Trap Register) on entry/return > ?* (hardware reset value is 0) */ > ?.macro set_hstr entry > @@ -357,6 +376,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 > @@ -443,6 +463,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.7.1 > looks ok to me. -Christoffer