History

KVM: TDX: Handle TDG.VP.VMCALL<ReportFatalError>

Convert TDG.VP.VMCALL<ReportFatalError> to KVM_EXIT_SYSTEM_EVENT with a new type KVM_SYSTEM_EVENT_TDX_FATAL and forward it to userspace for handling. TD guest can use TDG.VP.VMCALL<ReportFatalError> to report the fatal error it has experienced. This hypercall is special because TD guest is requesting a termination with the error information, KVM needs to forward the hypercall to userspace anyway, KVM doesn't do parsing or conversion, it just dumps the 16 general-purpose registers to userspace and let userspace decide what to do.

Binbin Wu committed 1 year ago

Commit 79462fa1 parent 2c304883 files · +35 −0Browse files

Unified · Split

3 files
  1. Documentation/virt/kvm/api.rst +6 −0
  2. arch/x86/kvm/vmx/tdx.c +28 −0
  3. include/uapi/linux/kvm.h +1 −0
Documentation/virt/kvm/api.rst+6−0
@@ -6823,6 +6823,7 @@ should put the acknowledged interrupt vector into the 'epr' field. · 6822 unmodified lines
68236823 #define KVM_SYSTEM_EVENT_WAKEUP 4
68246824 #define KVM_SYSTEM_EVENT_SUSPEND 5
68256825 #define KVM_SYSTEM_EVENT_SEV_TERM 6
6826+ #define KVM_SYSTEM_EVENT_TDX_FATAL 7
68266827 __u32 type;
68276828 __u32 ndata;
68286829 __u64 data[16];
@@ -6849,6 +6850,11 @@ Valid values for 'type' are: · 20 unmodified lines
68496850 reset/shutdown of the VM.
68506851 - KVM_SYSTEM_EVENT_SEV_TERM -- an AMD SEV guest requested termination.
68516852 The guest physical address of the guest's GHCB is stored in `data[0]`.
6853+ - KVM_SYSTEM_EVENT_TDX_FATAL -- a TDX guest reported a fatal error state.
6854+ KVM doesn't do any parsing or conversion, it just dumps 16 general-purpose
6855+ registers to userspace, in ascending order of the 4-bit indices for x86-64
6856+ general-purpose registers in instruction encoding, as defined in the Intel
6857+ SDM.
68526858 - KVM_SYSTEM_EVENT_WAKEUP -- the exiting vCPU is in a suspended state and
68536859 KVM has recognized a wakeup event. Userspace may honor this event by
68546860 marking the exiting vCPU as runnable, or deny it and call KVM_RUN again.
arch/x86/kvm/vmx/tdx.c+28−0
@@ -1104,11 +1104,39 @@ error: · 1103 unmodified lines
11041104 return 1;
11051105 }
11061106
1107+static int tdx_report_fatal_error(struct kvm_vcpu *vcpu)
1108+{
1109+ struct vcpu_tdx *tdx = to_tdx(vcpu);
1110+ u64 *regs = vcpu->run->system_event.data;
1111+ u64 *module_regs = &tdx->vp_enter_args.r8;
1112+ int index = VCPU_REGS_RAX;
1113+
1114+ vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
1115+ vcpu->run->system_event.type = KVM_SYSTEM_EVENT_TDX_FATAL;
1116+ vcpu->run->system_event.ndata = 16;
1117+
1118+ /* Dump 16 general-purpose registers to userspace in ascending order. */
1119+ regs[index++] = tdx->vp_enter_ret;
1120+ regs[index++] = tdx->vp_enter_args.rcx;
1121+ regs[index++] = tdx->vp_enter_args.rdx;
1122+ regs[index++] = tdx->vp_enter_args.rbx;
1123+ regs[index++] = 0;
1124+ regs[index++] = 0;
1125+ regs[index++] = tdx->vp_enter_args.rsi;
1126+ regs[index] = tdx->vp_enter_args.rdi;
1127+ for (index = 0; index < 8; index++)
1128+ regs[VCPU_REGS_R8 + index] = module_regs[index];
1129+
1130+ return 0;
1131+}
1132+
11071133 static int handle_tdvmcall(struct kvm_vcpu *vcpu)
11081134 {
11091135 switch (tdvmcall_leaf(vcpu)) {
11101136 case TDVMCALL_MAP_GPA:
11111137 return tdx_map_gpa(vcpu);
1138+ case TDVMCALL_REPORT_FATAL_ERROR:
1139+ return tdx_report_fatal_error(vcpu);
11121140 default:
11131141 break;
11141142 }
include/uapi/linux/kvm.h+1−0
@@ -375,6 +375,7 @@ struct kvm_run { · 374 unmodified lines
375375 #define KVM_SYSTEM_EVENT_WAKEUP 4
376376 #define KVM_SYSTEM_EVENT_SUSPEND 5
377377 #define KVM_SYSTEM_EVENT_SEV_TERM 6
378+#define KVM_SYSTEM_EVENT_TDX_FATAL 7
378379 __u32 type;
379380 __u32 ndata;
380381 union {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t