]> www.infradead.org Git - nvme.git/commitdiff
LoongArch: KVM: Add hypercall instruction emulation
authorBibo Mao <maobibo@loongson.cn>
Mon, 6 May 2024 14:00:46 +0000 (22:00 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Mon, 6 May 2024 14:00:46 +0000 (22:00 +0800)
On LoongArch system, there is a hypercall instruction special for
virtualization. When system executes this instruction on host side,
there is an illegal instruction exception reported, however it will
trap into host when it is executed in VM mode.

When hypercall is emulated, A0 register is set with value
KVM_HCALL_INVALID_CODE, rather than inject EXCCODE_INE invalid
instruction exception. So VM can continue to executing the next code.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/include/asm/Kbuild
arch/loongarch/include/asm/kvm_para.h [new file with mode: 0644]
arch/loongarch/kvm/exit.c

index 2dbec7853ae864868fd4fe0ff7b73b957a3d0462..c862672ed953fd92dd998def34a2e016e06db364 100644 (file)
@@ -26,4 +26,3 @@ generic-y += poll.h
 generic-y += param.h
 generic-y += posix_types.h
 generic-y += resource.h
-generic-y += kvm_para.h
diff --git a/arch/loongarch/include/asm/kvm_para.h b/arch/loongarch/include/asm/kvm_para.h
new file mode 100644 (file)
index 0000000..7f21de5
--- /dev/null
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LOONGARCH_KVM_PARA_H
+#define _ASM_LOONGARCH_KVM_PARA_H
+
+/*
+ * LoongArch hypercall return code
+ */
+#define KVM_HCALL_SUCCESS              0
+#define KVM_HCALL_INVALID_CODE         -1UL
+#define KVM_HCALL_INVALID_PARAMETER    -2UL
+
+static inline unsigned int kvm_arch_para_features(void)
+{
+       return 0;
+}
+
+static inline unsigned int kvm_arch_para_hints(void)
+{
+       return 0;
+}
+
+static inline bool kvm_check_and_clear_guest_paused(void)
+{
+       return false;
+}
+
+#endif /* _ASM_LOONGARCH_KVM_PARA_H */
index ed1d89d53e2e6da0c8b73ed17d97146721347d16..f368673db395d262763052ce0ecea6f66cc77fde 100644 (file)
@@ -685,6 +685,16 @@ static int kvm_handle_lasx_disabled(struct kvm_vcpu *vcpu)
        return RESUME_GUEST;
 }
 
+static int kvm_handle_hypercall(struct kvm_vcpu *vcpu)
+{
+       update_pc(&vcpu->arch);
+
+       /* Treat it as noop intruction, only set return value */
+       vcpu->arch.gprs[LOONGARCH_GPR_A0] = KVM_HCALL_INVALID_CODE;
+
+       return RESUME_GUEST;
+}
+
 /*
  * LoongArch KVM callback handling for unimplemented guest exiting
  */
@@ -716,6 +726,7 @@ static exit_handle_fn kvm_fault_tables[EXCCODE_INT_START] = {
        [EXCCODE_LSXDIS]                = kvm_handle_lsx_disabled,
        [EXCCODE_LASXDIS]               = kvm_handle_lasx_disabled,
        [EXCCODE_GSPR]                  = kvm_handle_gspr,
+       [EXCCODE_HVC]                   = kvm_handle_hypercall,
 };
 
 int kvm_handle_fault(struct kvm_vcpu *vcpu, int fault)