lkml.org 
[lkml]   [2022]   [Mar]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[RFC PATCH v5 099/104] KVM: TDX: Handle TDX PV map_gpa hypercall
Date
From: Isaku Yamahata <isaku.yamahata@intel.com>

Wire up TDX PV map_gpa hypercall to the kvm/mmu backend.

Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
---
arch/x86/kvm/vmx/tdx.c | 59 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)

diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 4d668a6c7dc9..e5eccec0e24d 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -1166,6 +1166,63 @@ static int tdx_report_fatal_error(struct kvm_vcpu *vcpu)
return 0;
}

+static int tdx_map_gpa(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = vcpu->kvm;
+ gpa_t gpa = tdvmcall_p1_read(vcpu);
+ gpa_t size = tdvmcall_p2_read(vcpu);
+ gpa_t end = gpa + size;
+
+ tdvmcall_set_return_code(vcpu, TDG_VP_VMCALL_INVALID_OPERAND);
+ if (!IS_ALIGNED(gpa, 4096) || !IS_ALIGNED(size, 4096) ||
+ end < gpa ||
+ end > kvm_gfn_stolen_mask(kvm) << (PAGE_SHIFT + 1) ||
+ kvm_is_private_gpa(kvm, gpa) != kvm_is_private_gpa(kvm, end))
+ return 1;
+
+ tdvmcall_set_return_code(vcpu, TDG_VP_VMCALL_SUCCESS);
+
+#define TDX_MAP_GPA_SIZE_MAX (16 * 1024 * 1024)
+ while (gpa < end) {
+ gfn_t s = gpa_to_gfn(gpa);
+ gfn_t e = gpa_to_gfn(
+ min(roundup(gpa + 1, TDX_MAP_GPA_SIZE_MAX), end));
+ int ret = kvm_mmu_map_gpa(vcpu, &s, e);
+
+ if (ret == -EAGAIN)
+ e = s;
+ else if (ret) {
+ tdvmcall_set_return_code(vcpu,
+ TDG_VP_VMCALL_INVALID_OPERAND);
+ break;
+ }
+
+ gpa = gfn_to_gpa(e);
+
+ /*
+ * TODO:
+ * Interrupt this hypercall invocation to return remaining
+ * region to the guest and let the guest to resume the
+ * hypercall.
+ *
+ * The TDX Guest-Hypervisor Communication Interface(GHCI)
+ * specification and guest implementation need to be updated.
+ *
+ * if (gpa < end && need_resched()) {
+ * size = end - gpa;
+ * kvm_r12_write(vcpu, gpa);
+ * kvm_r13_write(vcpu, size);
+ * tdvmcall_set_return_code(vcpu, TDG_VP_VMCALL_INTERRUPTED_RESUME);
+ * break;
+ * }
+ */
+ if (gpa < end && need_resched())
+ cond_resched();
+ }
+
+ return 1;
+}
+
static int handle_tdvmcall(struct kvm_vcpu *vcpu)
{
struct vcpu_tdx *tdx = to_tdx(vcpu);
@@ -1191,6 +1248,8 @@ static int handle_tdvmcall(struct kvm_vcpu *vcpu)
return tdx_emulate_wrmsr(vcpu);
case TDG_VP_VMCALL_REPORT_FATAL_ERROR:
return tdx_report_fatal_error(vcpu);
+ case TDG_VP_VMCALL_MAP_GPA:
+ return tdx_map_gpa(vcpu);
default:
break;
}
--
2.25.1
\
 
 \ /
  Last update: 2022-03-04 20:59    [W:1.498 / U:0.144 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site