arm: KVM: Don't return PSCI_INVAL if waitqueue is inactive
[linux-2.6-block.git] / arch / arm / kvm / arm.c
index 2a700e00528d0a3cc9d78a58f7d38dddf2297611..151eb91604823e6de449f851ea3b3e4f07aad977 100644 (file)
@@ -478,15 +478,6 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
                        return ret;
        }
 
-       /*
-        * Handle the "start in power-off" case by calling into the
-        * PSCI code.
-        */
-       if (test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) {
-               *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
-               kvm_psci_call(vcpu);
-       }
-
        return 0;
 }
 
@@ -700,6 +691,24 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
        return -EINVAL;
 }
 
+static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
+                                        struct kvm_vcpu_init *init)
+{
+       int ret;
+
+       ret = kvm_vcpu_set_target(vcpu, init);
+       if (ret)
+               return ret;
+
+       /*
+        * Handle the "start in power-off" case by marking the VCPU as paused.
+        */
+       if (__test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features))
+               vcpu->arch.pause = true;
+
+       return 0;
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
                         unsigned int ioctl, unsigned long arg)
 {
@@ -713,8 +722,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                if (copy_from_user(&init, argp, sizeof(init)))
                        return -EFAULT;
 
-               return kvm_vcpu_set_target(vcpu, &init);
-
+               return kvm_arch_vcpu_ioctl_vcpu_init(vcpu, &init);
        }
        case KVM_SET_ONE_REG:
        case KVM_GET_ONE_REG: {