[RFC PATCH 36/73] KVM: x86/PVM: Handle KVM hypercall

Lai Jiangshan
2024-02-26T14:36:36Z

PVM uses the syscall instruction as the hypercall instruction, so r10 is
used as a replacement for rcx since rcx is clobbered by the syscall.
Additionally, the syscall is a trap and does not need to skip the
hypercall instruction for PVM.

Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
Signed-off-by: Hou Wenlong <houwenlong.hwl@antgroup.com>
---
arch/x86/kvm/pvm/pvm.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/pvm/pvm.c b/arch/x86/kvm/pvm/pvm.c
index a2602d9828a5..242c355fda8f 100644
--- a/arch/x86/kvm/pvm/pvm.c
+++ b/arch/x86/kvm/pvm/pvm.c
@@ -1221,6 +1221,18 @@ static int handle_synthetic_instruction_return_supervisor(struct kvm_vcpu *vcpu)
return 1;
}

+static int handle_kvm_hypercall(struct kvm_vcpu *vcpu)
+{
+ int r;
+
+ // In PVM, r10 is the replacement for rcx in hypercall
+ kvm_rcx_write(vcpu, kvm_r10_read(vcpu));
+ r = kvm_emulate_hypercall_noskip(vcpu);
+ kvm_r10_write(vcpu, kvm_rcx_read(vcpu));
+
+ return r;
+}
+
static int handle_exit_syscall(struct kvm_vcpu *vcpu)
{
struct vcpu_pvm *pvm = to_pvm(vcpu);
@@ -1233,7 +1245,8 @@ static int handle_exit_syscall(struct kvm_vcpu *vcpu)
return handle_synthetic_instruction_return_user(vcpu);
if (rip == pvm->msr_rets_rip_plus2)
return handle_synthetic_instruction_return_supervisor(vcpu);
- return 1;
+
+ return handle_kvm_hypercall(vcpu);
}

static int handle_exit_debug(struct kvm_vcpu *vcpu)
--
2.19.1.6.gb485710b