x86: Handle buggy user_contexts (XCC)
[akaros.git] / kern / arch / x86 / ros / trapframe64.h
index d86e79a..b16c6d1 100644 (file)
-#ifndef ROS_INC_ARCH_TRAPFRAME64_H
-#define ROS_INC_ARCH_TRAPFRAME64_H
+#pragma once
 
 #ifndef ROS_INC_ARCH_TRAPFRAME_H
 #error "Do not include include ros/arch/trapframe64.h directly"
 #endif
 
-typedef struct pushregs {
-       /* registers as pushed by pusha */
-       uint32_t reg_edi;
-       uint32_t reg_esi;
-       uint32_t reg_ebp; uint32_t reg_oesp;            /* Useless */
-       uint32_t reg_ebx;
-       uint32_t reg_edx;
-       uint32_t reg_ecx;
-       uint32_t reg_eax;
-} push_regs_t;
-
 struct hw_trapframe {
-       push_regs_t tf_regs;
-       uint16_t tf_gs;
-       uint16_t tf_padding1;
-       uint16_t tf_fs;
-       uint16_t tf_padding2;
-       uint16_t tf_es;
-       uint16_t tf_padding3;
-       uint16_t tf_ds;
-       uint16_t tf_padding4;
+       uint64_t tf_gsbase;
+       uint64_t tf_fsbase;
+       uint64_t tf_rax;
+       uint64_t tf_rbx;
+       uint64_t tf_rcx;
+       uint64_t tf_rdx;
+       uint64_t tf_rbp;
+       uint64_t tf_rsi;
+       uint64_t tf_rdi;
+       uint64_t tf_r8;
+       uint64_t tf_r9;
+       uint64_t tf_r10;
+       uint64_t tf_r11;
+       uint64_t tf_r12;
+       uint64_t tf_r13;
+       uint64_t tf_r14;
+       uint64_t tf_r15;
        uint32_t tf_trapno;
-       /* below here defined by x86 hardware */
+       uint32_t tf_padding5;           /* used in trap reflection */
+       /* below here defined by x86 hardware (error code optional) */
        uint32_t tf_err;
-       uintptr_t tf_eip;
+       uint32_t tf_padding4;           /* used in trap reflection */
+       uint64_t tf_rip;
        uint16_t tf_cs;
-       uint16_t tf_padding5;
-       uint32_t tf_eflags;
-       /* below here only when crossing rings, such as from user to kernel */
-       uintptr_t tf_esp;
+       uint16_t tf_padding3;           /* used in trap reflection */
+       uint32_t tf_padding2;
+       uint64_t tf_rflags;
+       /* unlike 32 bit, SS:RSP is always pushed, even when not changing rings */
+       uint64_t tf_rsp;
        uint16_t tf_ss;
-       uint16_t tf_padding6;
+       uint16_t tf_padding1;
+       uint32_t tf_padding0;           /* used for partial contexts */
 };
 
 struct sw_trapframe {
-       uint32_t tf_ebp;
-       uint32_t tf_ebx;
-       uint32_t tf_esi;
-       uint32_t tf_edi;
-       uint32_t tf_esp;
-       uint32_t tf_eip;
+       uint64_t tf_gsbase;
+       uint64_t tf_fsbase;
+       uint64_t tf_rbx;
+       uint64_t tf_rbp;
+       uint64_t tf_r12;
+       uint64_t tf_r13;
+       uint64_t tf_r14;
+       uint64_t tf_r15;
+       uint64_t tf_rip;
+       uint64_t tf_rsp;
        uint32_t tf_mxcsr;
        uint16_t tf_fpucw;
-       uint16_t tf_gs;         /* something to track TLS is callee-saved (sort of) */
+       uint16_t tf_padding0;           /* used for partial contexts */
 };
 
-#endif /* ROS_INC_ARCH_TRAPFRAME64_H */
+#define MXCSR_RSVD_0   0xffff  // These 0s must be 0, mxcsr &= this
+
+/* The context is both what we want to run and its current state.  For VMs, that
+ * includes status bits from the VMCS for reflected vmexits/hypercalls.  This is
+ * not particularly different than how hardware contexts contain info on
+ * reflected traps.
+ *
+ * The VM context also consists of a mountain of state in the VMCS, referenced
+ * only in here by guest pcoreid.  Those bits are set once by Akaros to sensible
+ * defaults and then are changed during execution of the VM.  The parts of that
+ * state that are exposed to the user-VMM are the contents of the trapframe.
+ *
+ * Before adding any new flags, consider whether or not they need to be checked
+ * in proc_secure_vmtf(). */
+
+#define VMCTX_FL_PARTIAL               (1 << 0)
+#define VMCTX_FL_HAS_FAULT             (1 << 1)
+#define VMCTX_FL_VMRESUME              (1 << 2)
+#define VMCTX_FL_EPT_VMR_BACKED        (1 << 3)
+
+struct vm_trapframe {
+       /* Actual processor state */
+       uint64_t tf_rax;
+       uint64_t tf_rbx;
+       uint64_t tf_rcx;
+       uint64_t tf_rdx;
+       uint64_t tf_rbp;
+       uint64_t tf_rsi;
+       uint64_t tf_rdi;
+       uint64_t tf_r8;
+       uint64_t tf_r9;
+       uint64_t tf_r10;
+       uint64_t tf_r11;
+       uint64_t tf_r12;
+       uint64_t tf_r13;
+       uint64_t tf_r14;
+       uint64_t tf_r15;
+       uint64_t tf_rip;
+       uint64_t tf_rflags;
+       uint64_t tf_rsp;
+       uint64_t tf_cr2;
+       uint64_t tf_cr3;
+       /* Admin bits */
+       uint32_t tf_guest_pcoreid;
+       uint32_t tf_flags;
+       uint32_t tf_trap_inject;
+       uint16_t tf_guest_intr_status;
+       uint16_t tf_padding0;
+       uint32_t tf_exit_reason;
+       uint32_t tf_exit_qual;
+       uint32_t tf_intrinfo1;
+       uint32_t tf_intrinfo2;
+       uint64_t tf_guest_va;
+       uint64_t tf_guest_pa;
+};