Skip to content

Commit 25e8b1d

Browse files
Binbin Wubonzini
authored andcommitted
KVM: TDX: Exit to userspace for GetTdVmCallInfo
Exit to userspace for TDG.VP.VMCALL<GetTdVmCallInfo> via KVM_EXIT_TDX, to allow userspace to provide information about the support of TDVMCALLs when r12 is 1 for the TDVMCALLs beyond the GHCI base API. GHCI spec defines the GHCI base TDVMCALLs: <GetTdVmCallInfo>, <MapGPA>, <ReportFatalError>, <Instruction.CPUID>, <#VE.RequestMMIO>, <Instruction.HLT>, <Instruction.IO>, <Instruction.RDMSR> and <Instruction.WRMSR>. They must be supported by VMM to support TDX guests. For GetTdVmCallInfo - When leaf (r12) to enumerate TDVMCALL functionality is set to 0, successful execution indicates all GHCI base TDVMCALLs listed above are supported. Update the KVM TDX document with the set of the GHCI base APIs. - When leaf (r12) to enumerate TDVMCALL functionality is set to 1, it indicates the TDX guest is querying the supported TDVMCALLs beyond the GHCI base TDVMCALLs. Exit to userspace to let userspace set the TDVMCALL sub-function bit(s) accordingly to the leaf outputs. KVM could set the TDVMCALL bit(s) supported by itself when the TDVMCALLs don't need support from userspace after returning from userspace and before entering guest. Currently, no such TDVMCALLs implemented, KVM just sets the values returned from userspace. Suggested-by: Paolo Bonzini <[email protected]> Signed-off-by: Binbin Wu <[email protected]> [Adjust userspace API. - Paolo] Signed-off-by: Paolo Bonzini <[email protected]>
1 parent cf207ea commit 25e8b1d

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7191,6 +7191,11 @@ The valid value for 'flags' is:
71917191
u64 gpa;
71927192
u64 size;
71937193
} get_quote;
7194+
struct {
7195+
u64 ret;
7196+
u64 leaf;
7197+
u64 r11, r12, r13, r14;
7198+
} get_tdvmcall_info;
71947199
};
71957200
} tdx;
71967201

@@ -7216,6 +7221,11 @@ queued successfully, the TDX guest can poll the status field in the
72167221
shared-memory area to check whether the Quote generation is completed or
72177222
not. When completed, the generated Quote is returned via the same buffer.
72187223

7224+
* ``TDVMCALL_GET_TD_VM_CALL_INFO``: the guest has requested the support
7225+
status of TDVMCALLs. The output values for the given leaf should be
7226+
placed in fields from ``r11`` to ``r14`` of the ``get_tdvmcall_info``
7227+
field of the union.
7228+
72197229
KVM may add support for more values in the future that may cause a userspace
72207230
exit, even without calls to ``KVM_ENABLE_CAP`` or similar. In this case,
72217231
it will enter with output fields already valid; in the common case, the

arch/x86/kvm/vmx/tdx.c

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,18 +1451,53 @@ static int tdx_emulate_mmio(struct kvm_vcpu *vcpu)
14511451
return 1;
14521452
}
14531453

1454+
static int tdx_complete_get_td_vm_call_info(struct kvm_vcpu *vcpu)
1455+
{
1456+
struct vcpu_tdx *tdx = to_tdx(vcpu);
1457+
1458+
tdvmcall_set_return_code(vcpu, vcpu->run->tdx.get_tdvmcall_info.ret);
1459+
1460+
/*
1461+
* For now, there is no TDVMCALL beyond GHCI base API supported by KVM
1462+
* directly without the support from userspace, just set the value
1463+
* returned from userspace.
1464+
*/
1465+
tdx->vp_enter_args.r11 = vcpu->run->tdx.get_tdvmcall_info.r11;
1466+
tdx->vp_enter_args.r12 = vcpu->run->tdx.get_tdvmcall_info.r12;
1467+
tdx->vp_enter_args.r13 = vcpu->run->tdx.get_tdvmcall_info.r13;
1468+
tdx->vp_enter_args.r14 = vcpu->run->tdx.get_tdvmcall_info.r14;
1469+
1470+
return 1;
1471+
}
1472+
14541473
static int tdx_get_td_vm_call_info(struct kvm_vcpu *vcpu)
14551474
{
14561475
struct vcpu_tdx *tdx = to_tdx(vcpu);
14571476

1458-
if (tdx->vp_enter_args.r12)
1459-
tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
1460-
else {
1477+
switch (tdx->vp_enter_args.r12) {
1478+
case 0:
14611479
tdx->vp_enter_args.r11 = 0;
1480+
tdx->vp_enter_args.r12 = 0;
14621481
tdx->vp_enter_args.r13 = 0;
14631482
tdx->vp_enter_args.r14 = 0;
1483+
tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_SUCCESS);
1484+
return 1;
1485+
case 1:
1486+
vcpu->run->tdx.get_tdvmcall_info.leaf = tdx->vp_enter_args.r12;
1487+
vcpu->run->exit_reason = KVM_EXIT_TDX;
1488+
vcpu->run->tdx.flags = 0;
1489+
vcpu->run->tdx.nr = TDVMCALL_GET_TD_VM_CALL_INFO;
1490+
vcpu->run->tdx.get_tdvmcall_info.ret = TDVMCALL_STATUS_SUCCESS;
1491+
vcpu->run->tdx.get_tdvmcall_info.r11 = 0;
1492+
vcpu->run->tdx.get_tdvmcall_info.r12 = 0;
1493+
vcpu->run->tdx.get_tdvmcall_info.r13 = 0;
1494+
vcpu->run->tdx.get_tdvmcall_info.r14 = 0;
1495+
vcpu->arch.complete_userspace_io = tdx_complete_get_td_vm_call_info;
1496+
return 0;
1497+
default:
1498+
tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
1499+
return 1;
14641500
}
1465-
return 1;
14661501
}
14671502

14681503
static int tdx_complete_simple(struct kvm_vcpu *vcpu)

include/uapi/linux/kvm.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,11 @@ struct kvm_run {
462462
__u64 gpa;
463463
__u64 size;
464464
} get_quote;
465+
struct {
466+
__u64 ret;
467+
__u64 leaf;
468+
__u64 r11, r12, r13, r14;
469+
} get_tdvmcall_info;
465470
};
466471
} tdx;
467472
/* Fix the size of the union. */

0 commit comments

Comments
 (0)