Message ID | 20220128121912.509006-22-maz@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: arm64: ARMv8.3/8.4 Nested Virtualization support | expand |
Hi Marc, The patch looks good to me. Checked kvm_hvc_call_handler(), it returns -1 only when kvm_psci_call() doesn't handle the function and PSCI_RET_NOT_SUPPORTED must be set by the caller (which is handle_smc). Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com> Thanks, Alex On Fri, Jan 28, 2022 at 12:18:29PM +0000, Marc Zyngier wrote: > From: Jintack Lim <jintack.lim@linaro.org> > > VMs used to execute hvc #0 for the psci call if EL3 is not implemented. > However, when we come to provide the virtual EL2 mode to the VM, the > host OS inside the VM calls kvm_call_hyp() which is also hvc #0. So, > it's hard to differentiate between them from the host hypervisor's point > of view. > > So, let the VM execute smc instruction for the psci call. On ARMv8.3, > even if EL3 is not implemented, a smc instruction executed at non-secure > EL1 is trapped to EL2 if HCR_EL2.TSC==1, rather than being treated as > UNDEFINED. So, the host hypervisor can handle this psci call without any > confusion. > > Signed-off-by: Jintack Lim <jintack.lim@linaro.org> > Signed-off-by: Marc Zyngier <maz@kernel.org> > --- > arch/arm64/kvm/handle_exit.c | 24 ++++++++++++++++++++++-- > 1 file changed, 22 insertions(+), 2 deletions(-) > > diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c > index 2bbeed8c9786..0cedef6e0d80 100644 > --- a/arch/arm64/kvm/handle_exit.c > +++ b/arch/arm64/kvm/handle_exit.c > @@ -62,6 +62,8 @@ static int handle_hvc(struct kvm_vcpu *vcpu) > > static int handle_smc(struct kvm_vcpu *vcpu) > { > + int ret; > + > /* > * "If an SMC instruction executed at Non-secure EL1 is > * trapped to EL2 because HCR_EL2.TSC is 1, the exception is a > @@ -69,10 +71,28 @@ static int handle_smc(struct kvm_vcpu *vcpu) > * > * We need to advance the PC after the trap, as it would > * otherwise return to the same address... > + * > + * If imm is non-zero, it's not defined, so just skip it. > + */ > + if (kvm_vcpu_hvc_get_imm(vcpu)) { > + vcpu_set_reg(vcpu, 0, ~0UL); > + kvm_incr_pc(vcpu); > + return 1; > + } > + > + /* > + * If imm is zero, it's a psci call. > + * Note that on ARMv8.3, even if EL3 is not implemented, SMC executed > + * at Non-secure EL1 is trapped to EL2 if HCR_EL2.TSC==1, rather than > + * being treated as UNDEFINED. > */ > - vcpu_set_reg(vcpu, 0, ~0UL); > + ret = kvm_hvc_call_handler(vcpu); > + if (ret < 0) > + vcpu_set_reg(vcpu, 0, ~0UL); > + > kvm_incr_pc(vcpu); > - return 1; > + > + return ret; > } > > /* > -- > 2.30.2 >
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 2bbeed8c9786..0cedef6e0d80 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -62,6 +62,8 @@ static int handle_hvc(struct kvm_vcpu *vcpu) static int handle_smc(struct kvm_vcpu *vcpu) { + int ret; + /* * "If an SMC instruction executed at Non-secure EL1 is * trapped to EL2 because HCR_EL2.TSC is 1, the exception is a @@ -69,10 +71,28 @@ static int handle_smc(struct kvm_vcpu *vcpu) * * We need to advance the PC after the trap, as it would * otherwise return to the same address... + * + * If imm is non-zero, it's not defined, so just skip it. + */ + if (kvm_vcpu_hvc_get_imm(vcpu)) { + vcpu_set_reg(vcpu, 0, ~0UL); + kvm_incr_pc(vcpu); + return 1; + } + + /* + * If imm is zero, it's a psci call. + * Note that on ARMv8.3, even if EL3 is not implemented, SMC executed + * at Non-secure EL1 is trapped to EL2 if HCR_EL2.TSC==1, rather than + * being treated as UNDEFINED. */ - vcpu_set_reg(vcpu, 0, ~0UL); + ret = kvm_hvc_call_handler(vcpu); + if (ret < 0) + vcpu_set_reg(vcpu, 0, ~0UL); + kvm_incr_pc(vcpu); - return 1; + + return ret; } /*