summaryrefslogtreecommitdiff
path: root/arch/arm/kvm/psci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kvm/psci.c')
-rw-r--r--arch/arm/kvm/psci.c30
1 files changed, 8 insertions, 22 deletions
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 448f60e8d23c..86a693a02ba3 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -18,7 +18,6 @@
#include <linux/kvm_host.h>
#include <linux/wait.h>
-#include <asm/cputype.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_psci.h>
@@ -35,34 +34,26 @@ 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 = NULL, *tmp;
+ struct kvm_vcpu *vcpu;
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);
- 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;
- }
- }
-
- /*
- * Make sure the caller requested a valid CPU and that the CPU is
- * turned off.
- */
- if (!vcpu || !vcpu->arch.pause)
+ if (cpu_id >= atomic_read(&kvm->online_vcpus))
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;
+
kvm_reset_vcpu(vcpu);
/* Gracefully handle Thumb2 entry point */
@@ -71,15 +62,10 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
vcpu_set_thumb(vcpu);
}
- /* Propagate caller endianness */
- if (kvm_vcpu_is_be(source_vcpu))
- kvm_vcpu_set_be(vcpu);
-
*vcpu_pc(vcpu) = target_pc;
vcpu->arch.pause = false;
smp_mb(); /* Make sure the above is visible */
- wq = kvm_arch_vcpu_wq(vcpu);
wake_up_interruptible(wq);
return KVM_PSCI_RET_SUCCESS;