[RFC PATCH 08/73] KVM: x86: Allow hypercall handling to not skip the instruction

From: Lai Jiangshan
Date: Mon Feb 26 2024 - 09:38:35 EST


From: Hou Wenlong <houwenlong.hwl@xxxxxxxxxxxx>

In PVM, the syscall instruction is used as the hypercall instruction.
Since the syscall instruction is a trap that indicates the instruction
has been executed, there is no need to skip the hypercall instruction.

Suggested-by: Lai Jiangshan <jiangshan.ljs@xxxxxxxxxxxx>
Signed-off-by: Hou Wenlong <houwenlong.hwl@xxxxxxxxxxxx>
Signed-off-by: Lai Jiangshan <jiangshan.ljs@xxxxxxxxxxxx>
---
arch/x86/include/asm/kvm_host.h | 12 +++++++++++-
arch/x86/kvm/x86.c | 10 +++++++---
2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index c76bafe9c7e2..d17d85106d6f 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -2077,7 +2077,17 @@ static inline void kvm_clear_apicv_inhibit(struct kvm *kvm,
kvm_set_or_clear_apicv_inhibit(kvm, reason, false);
}

-int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
+int kvm_handle_hypercall(struct kvm_vcpu *vcpu, bool skip);
+
+static inline int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
+{
+ return kvm_handle_hypercall(vcpu, true);
+}
+
+static inline int kvm_emulate_hypercall_noskip(struct kvm_vcpu *vcpu)
+{
+ return kvm_handle_hypercall(vcpu, false);
+}

int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 error_code,
void *insn, int insn_len);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 96f3913f7fc5..8ec7a36cdf3e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -9933,7 +9933,7 @@ static int complete_hypercall_exit(struct kvm_vcpu *vcpu)
return kvm_skip_emulated_instruction(vcpu);
}

-int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
+int kvm_handle_hypercall(struct kvm_vcpu *vcpu, bool skip)
{
unsigned long nr, a0, a1, a2, a3, ret;
int op_64_bit;
@@ -10034,9 +10034,13 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
kvm_rax_write(vcpu, ret);

++vcpu->stat.hypercalls;
- return kvm_skip_emulated_instruction(vcpu);
+
+ if (skip)
+ return kvm_skip_emulated_instruction(vcpu);
+
+ return 1;
}
-EXPORT_SYMBOL_GPL(kvm_emulate_hypercall);
+EXPORT_SYMBOL_GPL(kvm_handle_hypercall);

static int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt)
{
--
2.19.1.6.gb485710b