Merge git://git.linaro.org/people/cdall/linux-kvm-arm.git tags/kvm-arm-3.11 into queue

KVM/ARM pull request for 3.11 merge window

* tag 'kvm-arm-3.11' of git://git.linaro.org/people/cdall/linux-kvm-arm.git:
  ARM: kvm: don't include drivers/virtio/Kconfig
  Update MAINTAINERS: KVM/ARM work now funded by Linaro
  arm/kvm: Cleanup KVM_ARM_MAX_VCPUS logic
  ARM: KVM: clear exclusive monitor on all exception returns
  ARM: KVM: add missing dsb before invalidating Stage-2 TLBs
  ARM: KVM: perform save/restore of PAR
  ARM: KVM: get rid of S2_PGD_SIZE
  ARM: KVM: don't special case PC when doing an MMIO
  ARM: KVM: use phys_addr_t instead of unsigned long long for HYP PGDs
  ARM: KVM: remove dead prototype for __kvm_tlb_flush_vmid
  ARM: KVM: Don't handle PSCI calls via SMC
  ARM: KVM: Allow host virt timer irq to be different from guest timer virt irq
This commit is contained in:
Gleb Natapov 2013-06-27 09:50:33 +03:00
commit 96f7edf9a5
17 changed files with 92 additions and 56 deletions

View File

@ -4692,10 +4692,10 @@ F: arch/s390/kvm/
F: drivers/s390/kvm/ F: drivers/s390/kvm/
KERNEL VIRTUAL MACHINE (KVM) FOR ARM KERNEL VIRTUAL MACHINE (KVM) FOR ARM
M: Christoffer Dall <cdall@cs.columbia.edu> M: Christoffer Dall <christoffer.dall@linaro.org>
L: kvmarm@lists.cs.columbia.edu L: kvmarm@lists.cs.columbia.edu
W: http://systems.cs.columbia.edu/projects/kvm-arm W: http://systems.cs.columbia.edu/projects/kvm-arm
S: Maintained S: Supported
F: arch/arm/include/uapi/asm/kvm* F: arch/arm/include/uapi/asm/kvm*
F: arch/arm/include/asm/kvm* F: arch/arm/include/asm/kvm*
F: arch/arm/kvm/ F: arch/arm/kvm/

View File

@ -135,7 +135,6 @@
#define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1ULL) #define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1ULL)
#define PTRS_PER_S2_PGD (1ULL << (KVM_PHYS_SHIFT - 30)) #define PTRS_PER_S2_PGD (1ULL << (KVM_PHYS_SHIFT - 30))
#define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t)) #define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t))
#define S2_PGD_SIZE (1 << S2_PGD_ORDER)
/* Virtualization Translation Control Register (VTCR) bits */ /* Virtualization Translation Control Register (VTCR) bits */
#define VTCR_SH0 (3 << 12) #define VTCR_SH0 (3 << 12)

View File

@ -37,16 +37,18 @@
#define c5_AIFSR 15 /* Auxilary Instrunction Fault Status R */ #define c5_AIFSR 15 /* Auxilary Instrunction Fault Status R */
#define c6_DFAR 16 /* Data Fault Address Register */ #define c6_DFAR 16 /* Data Fault Address Register */
#define c6_IFAR 17 /* Instruction Fault Address Register */ #define c6_IFAR 17 /* Instruction Fault Address Register */
#define c9_L2CTLR 18 /* Cortex A15 L2 Control Register */ #define c7_PAR 18 /* Physical Address Register */
#define c10_PRRR 19 /* Primary Region Remap Register */ #define c7_PAR_high 19 /* PAR top 32 bits */
#define c10_NMRR 20 /* Normal Memory Remap Register */ #define c9_L2CTLR 20 /* Cortex A15 L2 Control Register */
#define c12_VBAR 21 /* Vector Base Address Register */ #define c10_PRRR 21 /* Primary Region Remap Register */
#define c13_CID 22 /* Context ID Register */ #define c10_NMRR 22 /* Normal Memory Remap Register */
#define c13_TID_URW 23 /* Thread ID, User R/W */ #define c12_VBAR 23 /* Vector Base Address Register */
#define c13_TID_URO 24 /* Thread ID, User R/O */ #define c13_CID 24 /* Context ID Register */
#define c13_TID_PRIV 25 /* Thread ID, Privileged */ #define c13_TID_URW 25 /* Thread ID, User R/W */
#define c14_CNTKCTL 26 /* Timer Control Register (PL1) */ #define c13_TID_URO 26 /* Thread ID, User R/O */
#define NR_CP15_REGS 27 /* Number of regs (incl. invalid) */ #define c13_TID_PRIV 27 /* Thread ID, Privileged */
#define c14_CNTKCTL 28 /* Timer Control Register (PL1) */
#define NR_CP15_REGS 29 /* Number of regs (incl. invalid) */
#define ARM_EXCEPTION_RESET 0 #define ARM_EXCEPTION_RESET 0
#define ARM_EXCEPTION_UNDEFINED 1 #define ARM_EXCEPTION_UNDEFINED 1
@ -72,8 +74,6 @@ extern char __kvm_hyp_vector[];
extern char __kvm_hyp_code_start[]; extern char __kvm_hyp_code_start[];
extern char __kvm_hyp_code_end[]; extern char __kvm_hyp_code_end[];
extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
extern void __kvm_flush_vm_context(void); extern void __kvm_flush_vm_context(void);
extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);

View File

@ -65,11 +65,6 @@ static inline bool vcpu_mode_priv(struct kvm_vcpu *vcpu)
return cpsr_mode > USR_MODE;; return cpsr_mode > USR_MODE;;
} }
static inline bool kvm_vcpu_reg_is_pc(struct kvm_vcpu *vcpu, int reg)
{
return reg == 15;
}
static inline u32 kvm_vcpu_get_hsr(struct kvm_vcpu *vcpu) static inline u32 kvm_vcpu_get_hsr(struct kvm_vcpu *vcpu)
{ {
return vcpu->arch.fault.hsr; return vcpu->arch.fault.hsr;

View File

@ -25,7 +25,12 @@
#include <asm/fpstate.h> #include <asm/fpstate.h>
#include <kvm/arm_arch_timer.h> #include <kvm/arm_arch_timer.h>
#if defined(CONFIG_KVM_ARM_MAX_VCPUS)
#define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS
#else
#define KVM_MAX_VCPUS 0
#endif
#define KVM_USER_MEM_SLOTS 32 #define KVM_USER_MEM_SLOTS 32
#define KVM_PRIVATE_MEM_SLOTS 4 #define KVM_PRIVATE_MEM_SLOTS 4
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
@ -190,8 +195,8 @@ int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *);
int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
int exception_index); int exception_index);
static inline void __cpu_init_hyp_mode(unsigned long long boot_pgd_ptr, static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
unsigned long long pgd_ptr, phys_addr_t pgd_ptr,
unsigned long hyp_stack_ptr, unsigned long hyp_stack_ptr,
unsigned long vector_ptr) unsigned long vector_ptr)
{ {

View File

@ -41,9 +41,9 @@ config KVM_ARM_HOST
Provides host support for ARM processors. Provides host support for ARM processors.
config KVM_ARM_MAX_VCPUS config KVM_ARM_MAX_VCPUS
int "Number maximum supported virtual CPUs per VM" if KVM_ARM_HOST int "Number maximum supported virtual CPUs per VM"
default 4 if KVM_ARM_HOST depends on KVM_ARM_HOST
default 0 default 4
help help
Static number of max supported virtual CPUs per VM. Static number of max supported virtual CPUs per VM.
@ -67,6 +67,4 @@ config KVM_ARM_TIMER
---help--- ---help---
Adds support for the Architected Timers in virtual machines Adds support for the Architected Timers in virtual machines
source drivers/virtio/Kconfig
endif # VIRTUALIZATION endif # VIRTUALIZATION

View File

@ -789,8 +789,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
static void cpu_init_hyp_mode(void *dummy) static void cpu_init_hyp_mode(void *dummy)
{ {
unsigned long long boot_pgd_ptr; phys_addr_t boot_pgd_ptr;
unsigned long long pgd_ptr; phys_addr_t pgd_ptr;
unsigned long hyp_stack_ptr; unsigned long hyp_stack_ptr;
unsigned long stack_page; unsigned long stack_page;
unsigned long vector_ptr; unsigned long vector_ptr;
@ -798,8 +798,8 @@ static void cpu_init_hyp_mode(void *dummy)
/* Switch from the HYP stub to our own HYP init vector */ /* Switch from the HYP stub to our own HYP init vector */
__hyp_set_vectors(kvm_get_idmap_vector()); __hyp_set_vectors(kvm_get_idmap_vector());
boot_pgd_ptr = (unsigned long long)kvm_mmu_get_boot_httbr(); boot_pgd_ptr = kvm_mmu_get_boot_httbr();
pgd_ptr = (unsigned long long)kvm_mmu_get_httbr(); pgd_ptr = kvm_mmu_get_httbr();
stack_page = __get_cpu_var(kvm_arm_hyp_stack_page); stack_page = __get_cpu_var(kvm_arm_hyp_stack_page);
hyp_stack_ptr = stack_page + PAGE_SIZE; hyp_stack_ptr = stack_page + PAGE_SIZE;
vector_ptr = (unsigned long)__kvm_hyp_vector; vector_ptr = (unsigned long)__kvm_hyp_vector;

View File

@ -180,6 +180,10 @@ static const struct coproc_reg cp15_regs[] = {
NULL, reset_unknown, c6_DFAR }, NULL, reset_unknown, c6_DFAR },
{ CRn( 6), CRm( 0), Op1( 0), Op2( 2), is32, { CRn( 6), CRm( 0), Op1( 0), Op2( 2), is32,
NULL, reset_unknown, c6_IFAR }, NULL, reset_unknown, c6_IFAR },
/* PAR swapped by interrupt.S */
{ CRn( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR },
/* /*
* DC{C,I,CI}SW operations: * DC{C,I,CI}SW operations:
*/ */

View File

@ -52,9 +52,6 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run) static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
{ {
if (kvm_psci_call(vcpu))
return 1;
kvm_inject_undefined(vcpu); kvm_inject_undefined(vcpu);
return 1; return 1;
} }

View File

@ -49,6 +49,7 @@ __kvm_hyp_code_start:
ENTRY(__kvm_tlb_flush_vmid_ipa) ENTRY(__kvm_tlb_flush_vmid_ipa)
push {r2, r3} push {r2, r3}
dsb ishst
add r0, r0, #KVM_VTTBR add r0, r0, #KVM_VTTBR
ldrd r2, r3, [r0] ldrd r2, r3, [r0]
mcrr p15, 6, r2, r3, c2 @ Write VTTBR mcrr p15, 6, r2, r3, c2 @ Write VTTBR
@ -291,6 +292,7 @@ THUMB( orr r2, r2, #PSR_T_BIT )
ldr r2, =BSYM(panic) ldr r2, =BSYM(panic)
msr ELR_hyp, r2 msr ELR_hyp, r2
ldr r0, =\panic_str ldr r0, =\panic_str
clrex @ Clear exclusive monitor
eret eret
.endm .endm
@ -414,6 +416,10 @@ guest_trap:
mrcne p15, 4, r2, c6, c0, 4 @ HPFAR mrcne p15, 4, r2, c6, c0, 4 @ HPFAR
bne 3f bne 3f
/* Preserve PAR */
mrrc p15, 0, r0, r1, c7 @ PAR
push {r0, r1}
/* Resolve IPA using the xFAR */ /* Resolve IPA using the xFAR */
mcr p15, 0, r2, c7, c8, 0 @ ATS1CPR mcr p15, 0, r2, c7, c8, 0 @ ATS1CPR
isb isb
@ -424,13 +430,20 @@ guest_trap:
lsl r2, r2, #4 lsl r2, r2, #4
orr r2, r2, r1, lsl #24 orr r2, r2, r1, lsl #24
/* Restore PAR */
pop {r0, r1}
mcrr p15, 0, r0, r1, c7 @ PAR
3: load_vcpu @ Load VCPU pointer to r0 3: load_vcpu @ Load VCPU pointer to r0
str r2, [r0, #VCPU_HPFAR] str r2, [r0, #VCPU_HPFAR]
1: mov r1, #ARM_EXCEPTION_HVC 1: mov r1, #ARM_EXCEPTION_HVC
b __kvm_vcpu_return b __kvm_vcpu_return
4: pop {r0, r1, r2} @ Failed translation, return to guest 4: pop {r0, r1} @ Failed translation, return to guest
mcrr p15, 0, r0, r1, c7 @ PAR
clrex
pop {r0, r1, r2}
eret eret
/* /*
@ -456,6 +469,7 @@ switch_to_guest_vfp:
pop {r3-r7} pop {r3-r7}
pop {r0-r2} pop {r0-r2}
clrex
eret eret
#endif #endif

View File

@ -302,11 +302,14 @@ vcpu .req r0 @ vcpu pointer always in r0
.endif .endif
mrc p15, 0, r2, c14, c1, 0 @ CNTKCTL mrc p15, 0, r2, c14, c1, 0 @ CNTKCTL
mrrc p15, 0, r4, r5, c7 @ PAR
.if \store_to_vcpu == 0 .if \store_to_vcpu == 0
push {r2} push {r2,r4-r5}
.else .else
str r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)] str r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
add r12, vcpu, #CP15_OFFSET(c7_PAR)
strd r4, r5, [r12]
.endif .endif
.endm .endm
@ -319,12 +322,15 @@ vcpu .req r0 @ vcpu pointer always in r0
*/ */
.macro write_cp15_state read_from_vcpu .macro write_cp15_state read_from_vcpu
.if \read_from_vcpu == 0 .if \read_from_vcpu == 0
pop {r2} pop {r2,r4-r5}
.else .else
ldr r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)] ldr r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
add r12, vcpu, #CP15_OFFSET(c7_PAR)
ldrd r4, r5, [r12]
.endif .endif
mcr p15, 0, r2, c14, c1, 0 @ CNTKCTL mcr p15, 0, r2, c14, c1, 0 @ CNTKCTL
mcrr p15, 0, r4, r5, c7 @ PAR
.if \read_from_vcpu == 0 .if \read_from_vcpu == 0
pop {r2-r12} pop {r2-r12}

View File

@ -86,12 +86,6 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
sign_extend = kvm_vcpu_dabt_issext(vcpu); sign_extend = kvm_vcpu_dabt_issext(vcpu);
rt = kvm_vcpu_dabt_get_rd(vcpu); rt = kvm_vcpu_dabt_get_rd(vcpu);
if (kvm_vcpu_reg_is_pc(vcpu, rt)) {
/* IO memory trying to read/write pc */
kvm_inject_pabt(vcpu, kvm_vcpu_get_hfar(vcpu));
return 1;
}
mmio->is_write = is_write; mmio->is_write = is_write;
mmio->phys_addr = fault_ipa; mmio->phys_addr = fault_ipa;
mmio->len = len; mmio->len = len;

View File

@ -370,9 +370,6 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm)
if (!pgd) if (!pgd)
return -ENOMEM; return -ENOMEM;
/* stage-2 pgd must be aligned to its size */
VM_BUG_ON((unsigned long)pgd & (S2_PGD_SIZE - 1));
memset(pgd, 0, PTRS_PER_S2_PGD * sizeof(pgd_t)); memset(pgd, 0, PTRS_PER_S2_PGD * sizeof(pgd_t));
kvm_clean_pgd(pgd); kvm_clean_pgd(pgd);
kvm->arch.pgd = pgd; kvm->arch.pgd = pgd;

View File

@ -75,7 +75,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
* kvm_psci_call - handle PSCI call if r0 value is in range * kvm_psci_call - handle PSCI call if r0 value is in range
* @vcpu: Pointer to the VCPU struct * @vcpu: Pointer to the VCPU struct
* *
* Handle PSCI calls from guests through traps from HVC or SMC instructions. * Handle PSCI calls from guests through traps from HVC instructions.
* The calling convention is similar to SMC calls to the secure world where * The calling convention is similar to SMC calls to the secure world where
* the function number is placed in r0 and this function returns true if the * the function number is placed in r0 and this function returns true if the
* function number specified in r0 is withing the PSCI range, and false * function number specified in r0 is withing the PSCI range, and false

View File

@ -27,6 +27,8 @@
#include <asm/kvm_arm.h> #include <asm/kvm_arm.h>
#include <asm/kvm_coproc.h> #include <asm/kvm_coproc.h>
#include <kvm/arm_arch_timer.h>
/****************************************************************************** /******************************************************************************
* Cortex-A15 Reset Values * Cortex-A15 Reset Values
*/ */
@ -37,6 +39,11 @@ static struct kvm_regs a15_regs_reset = {
.usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT, .usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT,
}; };
static const struct kvm_irq_level a15_vtimer_irq = {
.irq = 27,
.level = 1,
};
/******************************************************************************* /*******************************************************************************
* Exported reset function * Exported reset function
@ -52,6 +59,7 @@ static struct kvm_regs a15_regs_reset = {
int kvm_reset_vcpu(struct kvm_vcpu *vcpu) int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
{ {
struct kvm_regs *cpu_reset; struct kvm_regs *cpu_reset;
const struct kvm_irq_level *cpu_vtimer_irq;
switch (vcpu->arch.target) { switch (vcpu->arch.target) {
case KVM_ARM_TARGET_CORTEX_A15: case KVM_ARM_TARGET_CORTEX_A15:
@ -59,6 +67,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
return -EINVAL; return -EINVAL;
cpu_reset = &a15_regs_reset; cpu_reset = &a15_regs_reset;
vcpu->arch.midr = read_cpuid_id(); vcpu->arch.midr = read_cpuid_id();
cpu_vtimer_irq = &a15_vtimer_irq;
break; break;
default: default:
return -ENODEV; return -ENODEV;
@ -70,5 +79,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
/* Reset CP15 registers */ /* Reset CP15 registers */
kvm_reset_coprocs(vcpu); kvm_reset_coprocs(vcpu);
/* Reset arch_timer context */
kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
return 0; return 0;
} }

View File

@ -61,6 +61,8 @@ struct arch_timer_cpu {
#ifdef CONFIG_KVM_ARM_TIMER #ifdef CONFIG_KVM_ARM_TIMER
int kvm_timer_hyp_init(void); int kvm_timer_hyp_init(void);
int kvm_timer_init(struct kvm *kvm); int kvm_timer_init(struct kvm *kvm);
void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
const struct kvm_irq_level *irq);
void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu); void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu);
void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu); void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu);
@ -76,6 +78,8 @@ static inline int kvm_timer_init(struct kvm *kvm)
return 0; return 0;
} }
static inline void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
const struct kvm_irq_level *irq) {}
static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {} static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {}
static inline void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) {} static inline void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) {}
static inline void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) {} static inline void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) {}

View File

@ -30,9 +30,7 @@
static struct timecounter *timecounter; static struct timecounter *timecounter;
static struct workqueue_struct *wqueue; static struct workqueue_struct *wqueue;
static struct kvm_irq_level timer_irq = { static unsigned int host_vtimer_irq;
.level = 1,
};
static cycle_t kvm_phys_timer_read(void) static cycle_t kvm_phys_timer_read(void)
{ {
@ -67,8 +65,8 @@ static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu)
timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK; timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK;
kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
vcpu->arch.timer_cpu.irq->irq, timer->irq->irq,
vcpu->arch.timer_cpu.irq->level); timer->irq->level);
} }
static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
@ -156,6 +154,20 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
timer_arm(timer, ns); timer_arm(timer, ns);
} }
void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
const struct kvm_irq_level *irq)
{
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
/*
* The vcpu timer irq number cannot be determined in
* kvm_timer_vcpu_init() because it is called much before
* kvm_vcpu_set_target(). To handle this, we determine
* vcpu timer irq number when the vcpu is reset.
*/
timer->irq = irq;
}
void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
{ {
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
@ -163,12 +175,11 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
INIT_WORK(&timer->expired, kvm_timer_inject_irq_work); INIT_WORK(&timer->expired, kvm_timer_inject_irq_work);
hrtimer_init(&timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); hrtimer_init(&timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
timer->timer.function = kvm_timer_expire; timer->timer.function = kvm_timer_expire;
timer->irq = &timer_irq;
} }
static void kvm_timer_init_interrupt(void *info) static void kvm_timer_init_interrupt(void *info)
{ {
enable_percpu_irq(timer_irq.irq, 0); enable_percpu_irq(host_vtimer_irq, 0);
} }
@ -182,7 +193,7 @@ static int kvm_timer_cpu_notify(struct notifier_block *self,
break; break;
case CPU_DYING: case CPU_DYING:
case CPU_DYING_FROZEN: case CPU_DYING_FROZEN:
disable_percpu_irq(timer_irq.irq); disable_percpu_irq(host_vtimer_irq);
break; break;
} }
@ -229,7 +240,7 @@ int kvm_timer_hyp_init(void)
goto out; goto out;
} }
timer_irq.irq = ppi; host_vtimer_irq = ppi;
err = register_cpu_notifier(&kvm_timer_cpu_nb); err = register_cpu_notifier(&kvm_timer_cpu_nb);
if (err) { if (err) {