Skip to content

Commit

Permalink
Merge git://git.linaro.org/people/cdall/linux-kvm-arm.git tags/kvm-ar…
Browse files Browse the repository at this point in the history
…m-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
  • Loading branch information
Gleb Natapov committed Jun 27, 2013
2 parents 24f7bb5 + 8bd4ffd commit 96f7edf
Show file tree
Hide file tree
Showing 17 changed files with 92 additions and 56 deletions.
4 changes: 2 additions & 2 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -4692,10 +4692,10 @@ F: arch/s390/kvm/
F: drivers/s390/kvm/

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
W: http://systems.cs.columbia.edu/projects/kvm-arm
S: Maintained
S: Supported
F: arch/arm/include/uapi/asm/kvm*
F: arch/arm/include/asm/kvm*
F: arch/arm/kvm/
Expand Down
1 change: 0 additions & 1 deletion arch/arm/include/asm/kvm_arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@
#define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1ULL)
#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_SIZE (1 << S2_PGD_ORDER)

/* Virtualization Translation Control Register (VTCR) bits */
#define VTCR_SH0 (3 << 12)
Expand Down
24 changes: 12 additions & 12 deletions arch/arm/include/asm/kvm_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,18 @@
#define c5_AIFSR 15 /* Auxilary Instrunction Fault Status R */
#define c6_DFAR 16 /* Data Fault Address Register */
#define c6_IFAR 17 /* Instruction Fault Address Register */
#define c9_L2CTLR 18 /* Cortex A15 L2 Control Register */
#define c10_PRRR 19 /* Primary Region Remap Register */
#define c10_NMRR 20 /* Normal Memory Remap Register */
#define c12_VBAR 21 /* Vector Base Address Register */
#define c13_CID 22 /* Context ID Register */
#define c13_TID_URW 23 /* Thread ID, User R/W */
#define c13_TID_URO 24 /* Thread ID, User R/O */
#define c13_TID_PRIV 25 /* Thread ID, Privileged */
#define c14_CNTKCTL 26 /* Timer Control Register (PL1) */
#define NR_CP15_REGS 27 /* Number of regs (incl. invalid) */
#define c7_PAR 18 /* Physical Address Register */
#define c7_PAR_high 19 /* PAR top 32 bits */
#define c9_L2CTLR 20 /* Cortex A15 L2 Control Register */
#define c10_PRRR 21 /* Primary Region Remap Register */
#define c10_NMRR 22 /* Normal Memory Remap Register */
#define c12_VBAR 23 /* Vector Base Address Register */
#define c13_CID 24 /* Context ID Register */
#define c13_TID_URW 25 /* Thread ID, User R/W */
#define c13_TID_URO 26 /* Thread ID, User R/O */
#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_UNDEFINED 1
Expand All @@ -72,8 +74,6 @@ extern char __kvm_hyp_vector[];
extern char __kvm_hyp_code_start[];
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_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);

Expand Down
5 changes: 0 additions & 5 deletions arch/arm/include/asm/kvm_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ static inline bool vcpu_mode_priv(struct kvm_vcpu *vcpu)
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)
{
return vcpu->arch.fault.hsr;
Expand Down
9 changes: 7 additions & 2 deletions arch/arm/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@
#include <asm/fpstate.h>
#include <kvm/arm_arch_timer.h>

#if defined(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_PRIVATE_MEM_SLOTS 4
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
Expand Down Expand Up @@ -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 exception_index);

static inline void __cpu_init_hyp_mode(unsigned long long boot_pgd_ptr,
unsigned long long pgd_ptr,
static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
phys_addr_t pgd_ptr,
unsigned long hyp_stack_ptr,
unsigned long vector_ptr)
{
Expand Down
8 changes: 3 additions & 5 deletions arch/arm/kvm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ config KVM_ARM_HOST
Provides host support for ARM processors.

config KVM_ARM_MAX_VCPUS
int "Number maximum supported virtual CPUs per VM" if KVM_ARM_HOST
default 4 if KVM_ARM_HOST
default 0
int "Number maximum supported virtual CPUs per VM"
depends on KVM_ARM_HOST
default 4
help
Static number of max supported virtual CPUs per VM.

Expand All @@ -67,6 +67,4 @@ config KVM_ARM_TIMER
---help---
Adds support for the Architected Timers in virtual machines

source drivers/virtio/Kconfig

endif # VIRTUALIZATION
8 changes: 4 additions & 4 deletions arch/arm/kvm/arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -789,17 +789,17 @@ long kvm_arch_vm_ioctl(struct file *filp,

static void cpu_init_hyp_mode(void *dummy)
{
unsigned long long boot_pgd_ptr;
unsigned long long pgd_ptr;
phys_addr_t boot_pgd_ptr;
phys_addr_t pgd_ptr;
unsigned long hyp_stack_ptr;
unsigned long stack_page;
unsigned long vector_ptr;

/* Switch from the HYP stub to our own HYP init vector */
__hyp_set_vectors(kvm_get_idmap_vector());

boot_pgd_ptr = (unsigned long long)kvm_mmu_get_boot_httbr();
pgd_ptr = (unsigned long long)kvm_mmu_get_httbr();
boot_pgd_ptr = kvm_mmu_get_boot_httbr();
pgd_ptr = kvm_mmu_get_httbr();
stack_page = __get_cpu_var(kvm_arm_hyp_stack_page);
hyp_stack_ptr = stack_page + PAGE_SIZE;
vector_ptr = (unsigned long)__kvm_hyp_vector;
Expand Down
4 changes: 4 additions & 0 deletions arch/arm/kvm/coproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ static const struct coproc_reg cp15_regs[] = {
NULL, reset_unknown, c6_DFAR },
{ CRn( 6), CRm( 0), Op1( 0), Op2( 2), is32,
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:
*/
Expand Down
3 changes: 0 additions & 3 deletions arch/arm/kvm/handle_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
if (kvm_psci_call(vcpu))
return 1;

kvm_inject_undefined(vcpu);
return 1;
}
Expand Down
16 changes: 15 additions & 1 deletion arch/arm/kvm/interrupts.S
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ __kvm_hyp_code_start:
ENTRY(__kvm_tlb_flush_vmid_ipa)
push {r2, r3}

dsb ishst
add r0, r0, #KVM_VTTBR
ldrd r2, r3, [r0]
mcrr p15, 6, r2, r3, c2 @ Write VTTBR
Expand Down Expand Up @@ -291,6 +292,7 @@ THUMB( orr r2, r2, #PSR_T_BIT )
ldr r2, =BSYM(panic)
msr ELR_hyp, r2
ldr r0, =\panic_str
clrex @ Clear exclusive monitor
eret
.endm

Expand Down Expand Up @@ -414,6 +416,10 @@ guest_trap:
mrcne p15, 4, r2, c6, c0, 4 @ HPFAR
bne 3f

/* Preserve PAR */
mrrc p15, 0, r0, r1, c7 @ PAR
push {r0, r1}

/* Resolve IPA using the xFAR */
mcr p15, 0, r2, c7, c8, 0 @ ATS1CPR
isb
Expand All @@ -424,13 +430,20 @@ guest_trap:
lsl r2, r2, #4
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
str r2, [r0, #VCPU_HPFAR]

1: mov r1, #ARM_EXCEPTION_HVC
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

/*
Expand All @@ -456,6 +469,7 @@ switch_to_guest_vfp:

pop {r3-r7}
pop {r0-r2}
clrex
eret
#endif

Expand Down
10 changes: 8 additions & 2 deletions arch/arm/kvm/interrupts_head.S
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,14 @@ vcpu .req r0 @ vcpu pointer always in r0
.endif

mrc p15, 0, r2, c14, c1, 0 @ CNTKCTL
mrrc p15, 0, r4, r5, c7 @ PAR

.if \store_to_vcpu == 0
push {r2}
push {r2,r4-r5}
.else
str r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
add r12, vcpu, #CP15_OFFSET(c7_PAR)
strd r4, r5, [r12]
.endif
.endm

Expand All @@ -319,12 +322,15 @@ vcpu .req r0 @ vcpu pointer always in r0
*/
.macro write_cp15_state read_from_vcpu
.if \read_from_vcpu == 0
pop {r2}
pop {r2,r4-r5}
.else
ldr r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
add r12, vcpu, #CP15_OFFSET(c7_PAR)
ldrd r4, r5, [r12]
.endif

mcr p15, 0, r2, c14, c1, 0 @ CNTKCTL
mcrr p15, 0, r4, r5, c7 @ PAR

.if \read_from_vcpu == 0
pop {r2-r12}
Expand Down
6 changes: 0 additions & 6 deletions arch/arm/kvm/mmio.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,6 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
sign_extend = kvm_vcpu_dabt_issext(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->phys_addr = fault_ipa;
mmio->len = len;
Expand Down
3 changes: 0 additions & 3 deletions arch/arm/kvm/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,6 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm)
if (!pgd)
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));
kvm_clean_pgd(pgd);
kvm->arch.pgd = pgd;
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/kvm/psci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* @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 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
Expand Down
12 changes: 12 additions & 0 deletions arch/arm/kvm/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include <asm/kvm_arm.h>
#include <asm/kvm_coproc.h>

#include <kvm/arm_arch_timer.h>

/******************************************************************************
* Cortex-A15 Reset Values
*/
Expand All @@ -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,
};

static const struct kvm_irq_level a15_vtimer_irq = {
.irq = 27,
.level = 1,
};


/*******************************************************************************
* Exported reset function
Expand All @@ -52,13 +59,15 @@ static struct kvm_regs a15_regs_reset = {
int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
{
struct kvm_regs *cpu_reset;
const struct kvm_irq_level *cpu_vtimer_irq;

switch (vcpu->arch.target) {
case KVM_ARM_TARGET_CORTEX_A15:
if (vcpu->vcpu_id > a15_max_cpu_idx)
return -EINVAL;
cpu_reset = &a15_regs_reset;
vcpu->arch.midr = read_cpuid_id();
cpu_vtimer_irq = &a15_vtimer_irq;
break;
default:
return -ENODEV;
Expand All @@ -70,5 +79,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
/* Reset CP15 registers */
kvm_reset_coprocs(vcpu);

/* Reset arch_timer context */
kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);

return 0;
}
4 changes: 4 additions & 0 deletions include/kvm/arm_arch_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ struct arch_timer_cpu {
#ifdef CONFIG_KVM_ARM_TIMER
int kvm_timer_hyp_init(void);
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_flush_hwstate(struct kvm_vcpu *vcpu);
void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu);
Expand All @@ -76,6 +78,8 @@ static inline int kvm_timer_init(struct kvm *kvm)
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_flush_hwstate(struct kvm_vcpu *vcpu) {}
static inline void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) {}
Expand Down
Loading

0 comments on commit 96f7edf

Please sign in to comment.