diff options
Diffstat (limited to 'virt/kvm/arm/psci.c')
| -rw-r--r-- | virt/kvm/arm/psci.c | 36 | 
1 files changed, 16 insertions, 20 deletions
diff --git a/virt/kvm/arm/psci.c b/virt/kvm/arm/psci.c index 9b73d3ad918a..34d08ee63747 100644 --- a/virt/kvm/arm/psci.c +++ b/virt/kvm/arm/psci.c @@ -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;  }  |