On Tue, Feb 11, 2025, Binbin Wu wrote:Yea, GHCI doesn't enforce it to be ASCII byte stream.
+static int tdx_report_fatal_error(struct kvm_vcpu *vcpu)Based on past experience with conditionally filling kvm_run fields, I think KVM
+{
+ struct vcpu_tdx *tdx = to_tdx(vcpu);
+ u64 reg_mask = tdx->vp_enter_args.rcx;
+ u64 *opt_regs;
+
+ /*
+ * Skip sanity checks and let userspace decide what to do if sanity
+ * checks fail.
+ */
+ vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
+ vcpu->run->system_event.type = KVM_SYSTEM_EVENT_TDX_FATAL;
+ /* Error codes. */
+ vcpu->run->system_event.data[0] = tdx->vp_enter_args.r12;
+ /* GPA of additional information page. */
+ vcpu->run->system_event.data[1] = tdx->vp_enter_args.r13;
+ /* Information passed via registers (up to 64 bytes). */
+ opt_regs = &vcpu->run->system_event.data[2];
+
+#define COPY_REG(REG, MASK) \
+ do { \
+ if (reg_mask & MASK) { \
should copy all registers and let userspace sort out the reg_mask. Unless the
guest passes an ASCII byte stream exactly as the GHCI suggests,
the information
is quite useless because userspace doesn't have reg_mask and so can't know what's
in data[4], data[5], etc... And I won't be the least bit surprised if guests
deviate from the GHCI.
+ *opt_regs = tdx->vp_enter_args.REG; \Assuming I haven't missed something, to hell with the GCHI, just dump *all*
+ opt_regs++; \
+ } \
+ } while (0)
+
+ /* The order is defined in GHCI. */
registers, sorted by their index (ascending). Including RAX (TDCALL), RBP, and
RSP.