|
|
@@ -104,12 +104,10 @@ static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu)
|
|
|
|
|
|
static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
|
|
|
{
|
|
|
+ struct vcpu_reset_state *reset_state;
|
|
|
struct kvm *kvm = source_vcpu->kvm;
|
|
|
struct kvm_vcpu *vcpu = NULL;
|
|
|
- struct swait_queue_head *wq;
|
|
|
unsigned long cpu_id;
|
|
|
- unsigned long context_id;
|
|
|
- phys_addr_t target_pc;
|
|
|
|
|
|
cpu_id = smccc_get_arg1(source_vcpu) & MPIDR_HWID_BITMASK;
|
|
|
if (vcpu_mode_is_32bit(source_vcpu))
|
|
|
@@ -130,32 +128,30 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
|
|
|
return PSCI_RET_INVALID_PARAMS;
|
|
|
}
|
|
|
|
|
|
- target_pc = smccc_get_arg2(source_vcpu);
|
|
|
- context_id = smccc_get_arg3(source_vcpu);
|
|
|
+ reset_state = &vcpu->arch.reset_state;
|
|
|
|
|
|
- kvm_reset_vcpu(vcpu);
|
|
|
-
|
|
|
- /* Gracefully handle Thumb2 entry point */
|
|
|
- if (vcpu_mode_is_32bit(vcpu) && (target_pc & 1)) {
|
|
|
- target_pc &= ~((phys_addr_t) 1);
|
|
|
- vcpu_set_thumb(vcpu);
|
|
|
- }
|
|
|
+ reset_state->pc = smccc_get_arg2(source_vcpu);
|
|
|
|
|
|
/* Propagate caller endianness */
|
|
|
- if (kvm_vcpu_is_be(source_vcpu))
|
|
|
- kvm_vcpu_set_be(vcpu);
|
|
|
+ reset_state->be = kvm_vcpu_is_be(source_vcpu);
|
|
|
|
|
|
- *vcpu_pc(vcpu) = target_pc;
|
|
|
/*
|
|
|
* NOTE: We always update r0 (or x0) because for PSCI v0.1
|
|
|
* the general puspose registers are undefined upon CPU_ON.
|
|
|
*/
|
|
|
- smccc_set_retval(vcpu, context_id, 0, 0, 0);
|
|
|
- vcpu->arch.power_off = false;
|
|
|
- smp_mb(); /* Make sure the above is visible */
|
|
|
+ reset_state->r0 = smccc_get_arg3(source_vcpu);
|
|
|
+
|
|
|
+ WRITE_ONCE(reset_state->reset, true);
|
|
|
+ kvm_make_request(KVM_REQ_VCPU_RESET, vcpu);
|
|
|
|
|
|
- wq = kvm_arch_vcpu_wq(vcpu);
|
|
|
- swake_up_one(wq);
|
|
|
+ /*
|
|
|
+ * Make sure the reset request is observed if the change to
|
|
|
+ * power_state is observed.
|
|
|
+ */
|
|
|
+ smp_wmb();
|
|
|
+
|
|
|
+ vcpu->arch.power_off = false;
|
|
|
+ kvm_vcpu_wake_up(vcpu);
|
|
|
|
|
|
return PSCI_RET_SUCCESS;
|
|
|
}
|