aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kvm/arm.c30
-rw-r--r--arch/arm/kvm/psci.c11
2 files changed, 25 insertions, 16 deletions
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 2a700e00528d..151eb9160482 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -478,15 +478,6 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
478 return ret; 478 return ret;
479 } 479 }
480 480
481 /*
482 * Handle the "start in power-off" case by calling into the
483 * PSCI code.
484 */
485 if (test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) {
486 *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
487 kvm_psci_call(vcpu);
488 }
489
490 return 0; 481 return 0;
491} 482}
492 483
@@ -700,6 +691,24 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
700 return -EINVAL; 691 return -EINVAL;
701} 692}
702 693
694static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
695 struct kvm_vcpu_init *init)
696{
697 int ret;
698
699 ret = kvm_vcpu_set_target(vcpu, init);
700 if (ret)
701 return ret;
702
703 /*
704 * Handle the "start in power-off" case by marking the VCPU as paused.
705 */
706 if (__test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features))
707 vcpu->arch.pause = true;
708
709 return 0;
710}
711
703long kvm_arch_vcpu_ioctl(struct file *filp, 712long kvm_arch_vcpu_ioctl(struct file *filp,
704 unsigned int ioctl, unsigned long arg) 713 unsigned int ioctl, unsigned long arg)
705{ 714{
@@ -713,8 +722,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
713 if (copy_from_user(&init, argp, sizeof(init))) 722 if (copy_from_user(&init, argp, sizeof(init)))
714 return -EFAULT; 723 return -EFAULT;
715 724
716 return kvm_vcpu_set_target(vcpu, &init); 725 return kvm_arch_vcpu_ioctl_vcpu_init(vcpu, &init);
717
718 } 726 }
719 case KVM_SET_ONE_REG: 727 case KVM_SET_ONE_REG:
720 case KVM_GET_ONE_REG: { 728 case KVM_GET_ONE_REG: {
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 0881bf169fbc..448f60e8d23c 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -54,15 +54,15 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
54 } 54 }
55 } 55 }
56 56
57 if (!vcpu) 57 /*
58 * Make sure the caller requested a valid CPU and that the CPU is
59 * turned off.
60 */
61 if (!vcpu || !vcpu->arch.pause)
58 return KVM_PSCI_RET_INVAL; 62 return KVM_PSCI_RET_INVAL;
59 63
60 target_pc = *vcpu_reg(source_vcpu, 2); 64 target_pc = *vcpu_reg(source_vcpu, 2);
61 65
62 wq = kvm_arch_vcpu_wq(vcpu);
63 if (!waitqueue_active(wq))
64 return KVM_PSCI_RET_INVAL;
65
66 kvm_reset_vcpu(vcpu); 66 kvm_reset_vcpu(vcpu);
67 67
68 /* Gracefully handle Thumb2 entry point */ 68 /* Gracefully handle Thumb2 entry point */
@@ -79,6 +79,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
79 vcpu->arch.pause = false; 79 vcpu->arch.pause = false;
80 smp_mb(); /* Make sure the above is visible */ 80 smp_mb(); /* Make sure the above is visible */
81 81
82 wq = kvm_arch_vcpu_wq(vcpu);
82 wake_up_interruptible(wq); 83 wake_up_interruptible(wq);
83 84
84 return KVM_PSCI_RET_SUCCESS; 85 return KVM_PSCI_RET_SUCCESS;