KVM: arm64: nv: Inject HVC exceptions to the virtual EL2
authorJintack Lim <jintack.lim@linaro.org>
Thu, 9 Feb 2023 17:58:12 +0000 (17:58 +0000)
committerOliver Upton <oliver.upton@linux.dev>
Sat, 11 Feb 2023 09:16:11 +0000 (09:16 +0000)
As we expect all PSCI calls from the L1 hypervisor to be performed
using SMC when nested virtualization is enabled, it is clear that
all HVC instruction from the VM (including from the virtual EL2)
are supposed to handled in the virtual EL2.

Forward these to EL2 as required.

Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: Jintack Lim <jintack.lim@linaro.org>
[maz: add handling of HCR_EL2.HCD]
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230209175820.1939006-11-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/kvm/handle_exit.c

index e778eefcf214d8876f14eefd8bf8b881ddf96e09..2d8c09cf3e4999489b63140bf7ea651d73ae1676 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_mmu.h>
+#include <asm/kvm_nested.h>
 #include <asm/debug-monitors.h>
 #include <asm/stacktrace/nvhe.h>
 #include <asm/traps.h>
@@ -41,6 +42,16 @@ static int handle_hvc(struct kvm_vcpu *vcpu)
                            kvm_vcpu_hvc_get_imm(vcpu));
        vcpu->stat.hvc_exit_stat++;
 
+       /* Forward hvc instructions to the virtual EL2 if the guest has EL2. */
+       if (vcpu_has_nv(vcpu)) {
+               if (vcpu_read_sys_reg(vcpu, HCR_EL2) & HCR_HCD)
+                       kvm_inject_undefined(vcpu);
+               else
+                       kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+
+               return 1;
+       }
+
        ret = kvm_hvc_call_handler(vcpu);
        if (ret < 0) {
                vcpu_set_reg(vcpu, 0, ~0UL);