Skip to content

Commit

Permalink
Merge tag 'kvm-arm-for-3.13-3' of git://git.linaro.org/people/cdall/l…
Browse files Browse the repository at this point in the history
…inux-kvm-arm into kvm-next

Updates for KVM/ARM, take 3 supporting more than 4 CPUs.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Conflicts:
	arch/arm/kvm/reset.c [cpu_reset->reset_regs change; context only]
  • Loading branch information
Paolo Bonzini committed Nov 11, 2013
2 parents 1b2ca42 + 79c6488 commit 6da8ae5
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 12 deletions.
5 changes: 5 additions & 0 deletions arch/arm/include/asm/kvm_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,9 @@ static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu)
return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK;
}

static inline unsigned long kvm_vcpu_get_mpidr(struct kvm_vcpu *vcpu)
{
return vcpu->arch.cp15[c0_MPIDR];
}

#endif /* __ARM_KVM_EMULATE_H__ */
14 changes: 10 additions & 4 deletions arch/arm/kvm/coproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,13 @@ int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
{
/*
* Compute guest MPIDR. No need to mess around with different clusters
* but we read the 'U' bit from the underlying hardware directly.
* Compute guest MPIDR. We build a virtual cluster out of the
* vcpu_id, but we read the 'U' bit from the underlying
* hardware directly.
*/
vcpu->arch.cp15[c0_MPIDR] = (read_cpuid_mpidr() & MPIDR_SMP_BITMASK)
| vcpu->vcpu_id;
vcpu->arch.cp15[c0_MPIDR] = ((read_cpuid_mpidr() & MPIDR_SMP_BITMASK) |
((vcpu->vcpu_id >> 2) << MPIDR_LEVEL_BITS) |
(vcpu->vcpu_id & 3));
}

/* TRM entries A7:4.3.31 A15:4.3.28 - RO WI */
Expand Down Expand Up @@ -122,6 +124,10 @@ static void reset_l2ctlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
asm volatile("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
l2ctlr &= ~(3 << 24);
ncores = atomic_read(&vcpu->kvm->online_vcpus) - 1;
/* How many cores in the current cluster and the next ones */
ncores -= (vcpu->vcpu_id & ~3);
/* Cap it to the maximum number of cores in a single cluster */
ncores = min(ncores, 3U);
l2ctlr |= (ncores & 3) << 24;

vcpu->arch.cp15[c9_L2CTLR] = l2ctlr;
Expand Down
17 changes: 13 additions & 4 deletions arch/arm/kvm/psci.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/kvm_host.h>
#include <linux/wait.h>

#include <asm/cputype.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_psci.h>

Expand All @@ -34,22 +35,30 @@ static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu)
static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
{
struct kvm *kvm = source_vcpu->kvm;
struct kvm_vcpu *vcpu;
struct kvm_vcpu *vcpu = NULL, *tmp;
wait_queue_head_t *wq;
unsigned long cpu_id;
unsigned long mpidr;
phys_addr_t target_pc;
int i;

cpu_id = *vcpu_reg(source_vcpu, 1);
if (vcpu_mode_is_32bit(source_vcpu))
cpu_id &= ~((u32) 0);

if (cpu_id >= atomic_read(&kvm->online_vcpus))
kvm_for_each_vcpu(i, tmp, kvm) {
mpidr = kvm_vcpu_get_mpidr(tmp);
if ((mpidr & MPIDR_HWID_BITMASK) == (cpu_id & MPIDR_HWID_BITMASK)) {
vcpu = tmp;
break;
}
}

if (!vcpu)
return KVM_PSCI_RET_INVAL;

target_pc = *vcpu_reg(source_vcpu, 2);

vcpu = kvm_get_vcpu(kvm, cpu_id);

wq = kvm_arch_vcpu_wq(vcpu);
if (!waitqueue_active(wq))
return KVM_PSCI_RET_INVAL;
Expand Down
4 changes: 0 additions & 4 deletions arch/arm/kvm/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
* Cortex-A15 and Cortex-A7 Reset Values
*/

static const int cortexa_max_cpu_idx = 3;

static struct kvm_regs cortexa_regs_reset = {
.usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT,
};
Expand Down Expand Up @@ -64,8 +62,6 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
switch (vcpu->arch.target) {
case KVM_ARM_TARGET_CORTEX_A7:
case KVM_ARM_TARGET_CORTEX_A15:
if (vcpu->vcpu_id > cortexa_max_cpu_idx)
return -EINVAL;
reset_regs = &cortexa_regs_reset;
vcpu->arch.midr = read_cpuid_id();
cpu_vtimer_irq = &cortexa_vtimer_irq;
Expand Down
5 changes: 5 additions & 0 deletions arch/arm64/include/asm/kvm_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,9 @@ static inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu)
return kvm_vcpu_get_hsr(vcpu) & ESR_EL2_FSC_TYPE;
}

static inline unsigned long kvm_vcpu_get_mpidr(struct kvm_vcpu *vcpu)
{
return vcpu_sys_reg(vcpu, MPIDR_EL1);
}

#endif /* __ARM64_KVM_EMULATE_H__ */

0 comments on commit 6da8ae5

Please sign in to comment.