diff options
Diffstat (limited to 'arch/arm64/kvm/hyp/switch.c')
| -rw-r--r-- | arch/arm64/kvm/hyp/switch.c | 39 | 
1 files changed, 37 insertions, 2 deletions
| diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index dfe8dd172512..925086b46136 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c @@ -625,7 +625,7 @@ static void __hyp_text __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)  }  /* Switch to the guest for VHE systems running in EL2 */ -int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) +static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)  {  	struct kvm_cpu_context *host_ctxt;  	struct kvm_cpu_context *guest_ctxt; @@ -678,7 +678,42 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)  	return exit_code;  } -NOKPROBE_SYMBOL(kvm_vcpu_run_vhe); +NOKPROBE_SYMBOL(__kvm_vcpu_run_vhe); + +int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) +{ +	int ret; + +	local_daif_mask(); + +	/* +	 * Having IRQs masked via PMR when entering the guest means the GIC +	 * will not signal the CPU of interrupts of lower priority, and the +	 * only way to get out will be via guest exceptions. +	 * Naturally, we want to avoid this. +	 * +	 * local_daif_mask() already sets GIC_PRIO_PSR_I_SET, we just need a +	 * dsb to ensure the redistributor is forwards EL2 IRQs to the CPU. +	 */ +	pmr_sync(); + +	ret = __kvm_vcpu_run_vhe(vcpu); + +	/* +	 * local_daif_restore() takes care to properly restore PSTATE.DAIF +	 * and the GIC PMR if the host is using IRQ priorities. +	 */ +	local_daif_restore(DAIF_PROCCTX_NOIRQ); + +	/* +	 * When we exit from the guest we change a number of CPU configuration +	 * parameters, such as traps.  Make sure these changes take effect +	 * before running the host or additional guests. +	 */ +	isb(); + +	return ret; +}  /* Switch to the guest for legacy non-VHE systems */  int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu) |