@@ -1092,6 +1092,43 @@ static int tdx_handle_get_quote(X86CPU *cpu, struct kvm_tdx_vmcall *vmcall)
return 0;
}
+static int tdx_handle_report_fatal_error(X86CPU *cpu,
+ struct kvm_tdx_vmcall *vmcall)
+{
+ uint64_t error_code = vmcall->in_r12;
+ char *message = NULL;
+
+ if (error_code & 0xffff) {
+ error_report("TDX: REPORT_FATAL_ERROR: invalid error code: "
+ "0x%lx\n", error_code);
+ return -1;
+ }
+
+ /* it has optional message */
+ if (vmcall->in_r14) {
+ uint64_t * tmp;
+
+#define GUEST_PANIC_INFO_TDX_MESSAGE_MAX 64
+ message = g_malloc0(GUEST_PANIC_INFO_TDX_MESSAGE_MAX + 1);
+
+ tmp = (uint64_t *)message;
+ /* The order is defined in TDX GHCI spec */
+ *(tmp++) = cpu_to_le64(vmcall->in_r14);
+ *(tmp++) = cpu_to_le64(vmcall->in_r15);
+ *(tmp++) = cpu_to_le64(vmcall->in_rbx);
+ *(tmp++) = cpu_to_le64(vmcall->in_rdi);
+ *(tmp++) = cpu_to_le64(vmcall->in_rsi);
+ *(tmp++) = cpu_to_le64(vmcall->in_r8);
+ *(tmp++) = cpu_to_le64(vmcall->in_r9);
+ *(tmp++) = cpu_to_le64(vmcall->in_rdx);
+ message[GUEST_PANIC_INFO_TDX_MESSAGE_MAX] = '\0';
+ assert((char *)tmp == message + GUEST_PANIC_INFO_TDX_MESSAGE_MAX);
+ }
+
+ error_report("TD guest reports fatal error. %s\n", message ? : "");
+ return -1;
+}
+
static int tdx_handle_setup_event_notify_interrupt(X86CPU *cpu,
struct kvm_tdx_vmcall *vmcall)
{
@@ -1126,6 +1163,8 @@ static int tdx_handle_vmcall(X86CPU *cpu, struct kvm_tdx_vmcall *vmcall)
return tdx_handle_map_gpa(cpu, vmcall);
case TDG_VP_VMCALL_GET_QUOTE:
return tdx_handle_get_quote(cpu, vmcall);
+ case TDG_VP_VMCALL_REPORT_FATAL_ERROR:
+ return tdx_handle_report_fatal_error(cpu, vmcall);
case TDG_VP_VMCALL_SETUP_EVENT_NOTIFY_INTERRUPT:
return tdx_handle_setup_event_notify_interrupt(cpu, vmcall);
default:
@@ -20,6 +20,7 @@ typedef struct TdxGuestClass {
#define TDG_VP_VMCALL_MAP_GPA 0x10001ULL
#define TDG_VP_VMCALL_GET_QUOTE 0x10002ULL
+#define TDG_VP_VMCALL_REPORT_FATAL_ERROR 0x10003ULL
#define TDG_VP_VMCALL_SETUP_EVENT_NOTIFY_INTERRUPT 0x10004ULL
#define TDG_VP_VMCALL_SUCCESS 0x0000000000000000ULL
TD guest can use TDG.VP.VMCALL<REPORT_FATAL_ERROR> to request termination with error message encoded in GPRs. Parse and print the error message, and terminate the TD guest in the handler. Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com> --- target/i386/kvm/tdx.c | 39 +++++++++++++++++++++++++++++++++++++++ target/i386/kvm/tdx.h | 1 + 2 files changed, 40 insertions(+)