diff options
-rw-r--r-- | arch/arm/kvm/arm.c | 30 | ||||
-rw-r--r-- | arch/arm/kvm/psci.c | 11 |
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 | ||
694 | static 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 | |||
703 | long kvm_arch_vcpu_ioctl(struct file *filp, | 712 | long 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; |