Skip to content

Commit b5aafcb

Browse files
Binbin Wubonzini
authored andcommitted
KVM: TDX: Add new TDVMCALL status code for unsupported subfuncs
Add the new TDVMCALL status code TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED and return it for unimplemented TDVMCALL subfunctions. Returning TDVMCALL_STATUS_INVALID_OPERAND when a subfunction is not implemented is vague because TDX guests can't tell the error is due to the subfunction is not supported or an invalid input of the subfunction. New GHCI spec adds TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED to avoid the ambiguity. Use it instead of TDVMCALL_STATUS_INVALID_OPERAND. Before the change, for common guest implementations, when a TDX guest receives TDVMCALL_STATUS_INVALID_OPERAND, it has two cases: 1. Some operand is invalid. It could change the operand to another value retry. 2. The subfunction is not supported. For case 1, an invalid operand usually means the guest implementation bug. Since the TDX guest can't tell which case is, the best practice for handling TDVMCALL_STATUS_INVALID_OPERAND is stopping calling such leaf, treating the failure as fatal if the TDVMCALL is essential or ignoring it if the TDVMCALL is optional. With this change, TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED could be sent to old TDX guest that do not know about it, but it is expected that the guest will make the same action as TDVMCALL_STATUS_INVALID_OPERAND. Currently, no known TDX guest checks TDVMCALL_STATUS_INVALID_OPERAND specifically; for example Linux just checks for success. Signed-off-by: Binbin Wu <[email protected]> [Return it for untrapped KVM_HC_MAP_GPA_RANGE. - Paolo] Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 2f3fc29 commit b5aafcb

File tree

2 files changed

+7
-4
lines changed

2 files changed

+7
-4
lines changed

arch/x86/include/asm/shared/tdx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#define TDVMCALL_STATUS_RETRY 0x0000000000000001ULL
8181
#define TDVMCALL_STATUS_INVALID_OPERAND 0x8000000000000000ULL
8282
#define TDVMCALL_STATUS_ALIGN_ERROR 0x8000000000000002ULL
83+
#define TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED 0x8000000000000003ULL
8384

8485
/*
8586
* Bitmasks of exposed registers (with VMM).

arch/x86/kvm/vmx/tdx.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,11 +1212,13 @@ static int tdx_map_gpa(struct kvm_vcpu *vcpu)
12121212
/*
12131213
* Converting TDVMCALL_MAP_GPA to KVM_HC_MAP_GPA_RANGE requires
12141214
* userspace to enable KVM_CAP_EXIT_HYPERCALL with KVM_HC_MAP_GPA_RANGE
1215-
* bit set. If not, the error code is not defined in GHCI for TDX, use
1216-
* TDVMCALL_STATUS_INVALID_OPERAND for this case.
1215+
* bit set. This is a base call so it should always be supported, but
1216+
* KVM has no way to ensure that userspace implements the GHCI correctly.
1217+
* So if KVM_HC_MAP_GPA_RANGE does not cause a VMEXIT, return an error
1218+
* to the guest.
12171219
*/
12181220
if (!user_exit_on_hypercall(vcpu->kvm, KVM_HC_MAP_GPA_RANGE)) {
1219-
ret = TDVMCALL_STATUS_INVALID_OPERAND;
1221+
ret = TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED;
12201222
goto error;
12211223
}
12221224

@@ -1476,7 +1478,7 @@ static int handle_tdvmcall(struct kvm_vcpu *vcpu)
14761478
break;
14771479
}
14781480

1479-
tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
1481+
tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED);
14801482
return 1;
14811483
}
14821484

0 commit comments

Comments
 (0)