@@ -186,3 +186,57 @@ const char *tdx_seamcall_error_name(u64 error_code)
return "Unknown SEAMCALL status code";
}
EXPORT_SYMBOL_GPL(tdx_seamcall_error_name);
+
+static const char * const TDX_SEPT_ENTRY_STATES[] = {
+ "SEPT_FREE",
+ "SEPT_BLOCKED",
+ "SEPT_PENDING",
+ "SEPT_PENDING_BLOCKED",
+ "SEPT_PRESENT"
+};
+
+void pr_seamcall_ex_ret_info(u64 op, u64 error_code, struct tdx_ex_ret *ex_ret)
+{
+ if (!ex_ret)
+ return;
+
+ switch (error_code & TDX_SEAMCALL_STATUS_MASK) {
+ case TDX_INCORRECT_CPUID_VALUE:
+ pr_err("Expected CPUID [leaf 0x%x subleaf 0x%x]: "
+ "eax 0x%x check_mask 0x%x, ebx 0x%x check_mask 0x%x, "
+ "ecx 0x%x check_mask 0x%x, edx 0x%x check_mask 0x%x\n",
+ ex_ret->leaf, ex_ret->subleaf,
+ ex_ret->eax_val, ex_ret->eax_mask,
+ ex_ret->ebx_val, ex_ret->ebx_mask,
+ ex_ret->ecx_val, ex_ret->ecx_mask,
+ ex_ret->edx_val, ex_ret->edx_mask);
+ break;
+ case TDX_INCONSISTENT_CPUID_FIELD:
+ pr_err("Inconsistent CPUID [leaf 0x%x subleaf 0x%x]: "
+ "eax_mask 0x%x, ebx_mask 0x%x, ecx_mask %x, edx_mask 0x%x\n",
+ ex_ret->leaf, ex_ret->subleaf,
+ ex_ret->eax_mask, ex_ret->ebx_mask,
+ ex_ret->ecx_mask, ex_ret->edx_mask);
+ break;
+ case TDX_EPT_WALK_FAILED: {
+ const char *state;
+
+ if (ex_ret->state >= ARRAY_SIZE(TDX_SEPT_ENTRY_STATES))
+ state = "Invalid";
+ else
+ state = TDX_SEPT_ENTRY_STATES[ex_ret->state];
+
+ pr_err("Secure EPT walk error: SEPTE 0x%llx, level %d, %s\n",
+ ex_ret->septe, ex_ret->level, state);
+ break;
+ }
+ default:
+ /* TODO: print only meaningful registers depending on op */
+ pr_err("RCX 0x%llx, RDX 0x%llx, R8 0x%llx, R9 0x%llx, "
+ "R10 0x%llx, R11 0x%llx\n",
+ ex_ret->rcx, ex_ret->rdx, ex_ret->r8, ex_ret->r9,
+ ex_ret->r10, ex_ret->r11);
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(pr_seamcall_ex_ret_info);
@@ -38,6 +38,7 @@ static inline u64 _seamcall(u64 op, u64 rcx, u64 rdx, u64 r8, u64 r9, u64 r10,
#endif
const char *tdx_seamcall_error_name(u64 error_code);
+void pr_seamcall_ex_ret_info(u64 op, u64 error_code, struct tdx_ex_ret *ex_ret);
static inline void __pr_seamcall_error(u64 op, const char *op_str,
u64 err, struct tdx_ex_ret *ex)
@@ -46,10 +47,7 @@ static inline void __pr_seamcall_error(u64 op, const char *op_str,
op_str, smp_processor_id(),
tdx_seamcall_error_name(err), err);
if (ex)
- pr_err_ratelimited(
- "RCX 0x%llx, RDX 0x%llx, R8 0x%llx, R9 0x%llx, R10 0x%llx, R11 0x%llx\n",
- (ex)->rcx, (ex)->rdx, (ex)->r8, (ex)->r9, (ex)->r10,
- (ex)->r11);
+ pr_seamcall_ex_ret_info(op, err, ex);
}
#define pr_seamcall_error(op, err, ex) \