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
6823 #define KVM_SYSTEM_EVENT_WAKEUP 46823 #define KVM_SYSTEM_EVENT_WAKEUP 4
6824 #define KVM_SYSTEM_EVENT_SUSPEND 56824 #define KVM_SYSTEM_EVENT_SUSPEND 5
6825 #define KVM_SYSTEM_EVENT_SEV_TERM 66825 #define KVM_SYSTEM_EVENT_SEV_TERM 6
6826 #define KVM_SYSTEM_EVENT_TDX_FATAL 7
6826 __u32 type;6827 __u32 type;
6827 __u32 ndata;6828 __u32 ndata;
6828 __u64 data[16];6829 __u64 data[16];
@@ -6849,6 +6850,11 @@ Valid values for 'type' are: · 20 unmodified lines
6849 reset/shutdown of the VM.6850 reset/shutdown of the VM.
6850 - KVM_SYSTEM_EVENT_SEV_TERM -- an AMD SEV guest requested termination.6851 - KVM_SYSTEM_EVENT_SEV_TERM -- an AMD SEV guest requested termination.
6851 The guest physical address of the guest's GHCB is stored in `data[0]`.6852 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.
6852 - KVM_SYSTEM_EVENT_WAKEUP -- the exiting vCPU is in a suspended state and6858 - KVM_SYSTEM_EVENT_WAKEUP -- the exiting vCPU is in a suspended state and
6853 KVM has recognized a wakeup event. Userspace may honor this event by6859 KVM has recognized a wakeup event. Userspace may honor this event by
6854 marking the exiting vCPU as runnable, or deny it and call KVM_RUN again.6860 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
1104 return 1;1104 return 1;
1105}1105}
1106 1106
1107static 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
1107static int handle_tdvmcall(struct kvm_vcpu *vcpu)1133static int handle_tdvmcall(struct kvm_vcpu *vcpu)
1108{1134{
1109 switch (tdvmcall_leaf(vcpu)) {1135 switch (tdvmcall_leaf(vcpu)) {
1110 case TDVMCALL_MAP_GPA:1136 case TDVMCALL_MAP_GPA:
1111 return tdx_map_gpa(vcpu);1137 return tdx_map_gpa(vcpu);
1138 case TDVMCALL_REPORT_FATAL_ERROR:
1139 return tdx_report_fatal_error(vcpu);
1112 default:1140 default:
1113 break;1141 break;
1114 }1142 }
include/uapi/linux/kvm.h+1−0
@@ -375,6 +375,7 @@ struct kvm_run { · 374 unmodified lines
375#define KVM_SYSTEM_EVENT_WAKEUP 4375#define KVM_SYSTEM_EVENT_WAKEUP 4
376#define KVM_SYSTEM_EVENT_SUSPEND 5376#define KVM_SYSTEM_EVENT_SUSPEND 5
377#define KVM_SYSTEM_EVENT_SEV_TERM 6377#define KVM_SYSTEM_EVENT_SEV_TERM 6
378#define KVM_SYSTEM_EVENT_TDX_FATAL 7
378 __u32 type;379 __u32 type;
379 __u32 ndata;380 __u32 ndata;
380 union {381 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