Extended state data structures (XCC)
authorMichael Taufen <mtaufen@gmail.com>
Mon, 22 Feb 2016 22:11:37 +0000 (14:11 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 26 Feb 2016 16:28:20 +0000 (11:28 -0500)
Rebuild your kenrel headers and rebuild all user apps!

new ancillary_state state components
x86_default_xcr0
xcr0 in guest_pcore

Signed-off-by: Michael Taufen <mtaufen@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/init.c
kern/arch/x86/ros/trapframe.h
kern/arch/x86/trap.h
kern/arch/x86/vmm/vmm.c
kern/arch/x86/vmm/vmm.h

index a208048..6ab38cc 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <smp.h>
 
+#include <arch/x86.h>
 #include <arch/pci.h>
 #include <arch/console.h>
 #include <arch/perfmon.h>
@@ -9,7 +10,16 @@
 #include <console.h>
 #include <monitor.h>
 #include <arch/usb.h>
+#include <assert.h>
 
+/*
+ *     x86_default_xcr0 is the Akaros-wide
+ *     default value for the xcr0 register.
+ *
+ *     It is set on every processor during
+ *     per-cpu init.
+ */
+uint64_t x86_default_xcr0;
 struct ancillary_state x86_default_fpu;
 uint32_t kerndate;
 
index 87629fc..835e711 100644 (file)
@@ -74,13 +74,30 @@ typedef struct {
        unsigned int stor[4];
 } __128bits;
 
+/*
+ *  X86_MAX_XCR0 specifies the maximum set of processor extended state
+ *  feature components that Akaros supports saving through the
+ *  XSAVE instructions.
+ *  This may be a superset of available state components on a given
+ *  processor. We CPUID at boot and determine the intersection
+ *  of Akaros-supported and processor-supported features, and we
+ *  save this value to x86_default_xcr0 in arch/x86/init.c.
+ *  We guarantee that the set of feature components specified by
+ *  X86_MAX_XCR0 will fit in the ancillary_state struct.
+ *  If you add to the mask, make sure you also extend ancillary_state!
+ */
+
+#define X86_MAX_XCR0 0x2ff
+
 typedef struct ancillary_state {
+       /* Legacy region of the XSAVE area */
        union { /* whichever header used depends on the mode */
                struct fp_header_non_64bit                      fp_head_n64;
                struct fp_header_64bit_promoted         fp_head_64p;
                struct fp_header_64bit_default          fp_head_64d;
        };
-       __128bits               st0_mm0;        /* 128 bits: 80 for the st0, 48 rsv */
+       /* offset 32 bytes */
+       __128bits               st0_mm0;        /* 128 bits: 80 for the st0, 48 reserved */
        __128bits               st1_mm1;
        __128bits               st2_mm2;
        __128bits               st3_mm3;
@@ -88,6 +105,7 @@ typedef struct ancillary_state {
        __128bits               st5_mm5;
        __128bits               st6_mm6;
        __128bits               st7_mm7;
+       /* offset 160 bytes */
        __128bits               xmm0;
        __128bits               xmm1;
        __128bits               xmm2;
@@ -96,7 +114,8 @@ typedef struct ancillary_state {
        __128bits               xmm5;
        __128bits               xmm6;
        __128bits               xmm7;
-       __128bits               xmm8;           /* xmm8 and below only for 64-bit-mode */
+       /* xmm8-xmm15 are only available in 64-bit-mode */
+       __128bits               xmm8;
        __128bits               xmm9;
        __128bits               xmm10;
        __128bits               xmm11;
@@ -104,10 +123,41 @@ typedef struct ancillary_state {
        __128bits               xmm13;
        __128bits               xmm14;
        __128bits               xmm15;
+       /* offset 416 bytes */
        __128bits               reserv0;
        __128bits               reserv1;
        __128bits               reserv2;
        __128bits               reserv3;
        __128bits               reserv4;
        __128bits               reserv5;
-} __attribute__((aligned(16))) ancillary_state_t;
+       /* offset 512 bytes */
+
+       /*
+        * XSAVE header (64 bytes, starting at offset 512 from
+        * the XSAVE area's base address)
+        */
+
+       // xstate_bv identifies the state components in the XSAVE area
+       uint64_t                xstate_bv;
+       /*
+        *      xcomp_bv[bit 63] is 1 if the compacted format is used, else 0.
+        *      All bits in xcomp_bv should be 0 if the processor does not support the
+        *      compaction extensions to the XSAVE feature set.
+       */
+       uint64_t                xcomp_bv;
+       __128bits               reserv6;
+
+       /* offset 576 bytes */
+       /*
+        *      Extended region of the XSAVE area
+        *      We currently support an extended region of up to 2112 bytes,
+        *      for a total ancillary_state size of 2688 bytes.
+        *      This supports x86 state components up through the zmm31 register.
+        *      If you need more, please ask!
+        *      See the Intel Architecture Instruction Set Extensions Programming
+        *      Reference page 3-3 for detailed offsets in this region.
+       */
+       uint8_t                 extended_region[2112];
+
+       /* ancillary state  */
+} __attribute__((aligned(64))) ancillary_state_t;
index c121744..86b245b 100644 (file)
@@ -3,6 +3,7 @@
 #define ROS_KERN_ARCH_TRAP_H
 
 #include <ros/arch/msr-index.h>
+#include <ros/errno.h>
 
 #define NUM_IRQS                                       256
 
@@ -14,7 +15,7 @@
 #define T_OFLOW      4         // overflow
 #define T_BOUND      5         // bounds check
 #define T_ILLOP      6         // illegal opcode
-#define T_DEVICE     7         // device not available 
+#define T_DEVICE     7         // device not available
 #define T_DBLFLT     8         // double fault
 /* #define T_COPROC  9 */      // reserved (not generated by recent processors)
 #define T_TSS       10         // invalid task switch segment
@@ -155,6 +156,7 @@ extern void sysenter_handler(void);
 
 /* Defined and set up in in arch/init.c, used for XMM initialization */
 extern struct ancillary_state x86_default_fpu;
+extern uint64_t x86_default_xcr0;
 
 static inline void save_fp_state(struct ancillary_state *silly)
 {
index 708d729..9a13dbf 100644 (file)
@@ -1,5 +1,5 @@
 /* Copyright 2015 Google Inc.
- * 
+ *
  * See LICENSE for details.
  */
 
 #include <trap.h>
 #include <umem.h>
 
+#include <arch/x86.h>
+
+
 /* TODO: have better cpuid info storage and checks */
 bool x86_supports_vmx = FALSE;
 
 /* Figure out what kind of CPU we are on, and if it supports any reasonable
  * virtualization. For now, if we're not some sort of newer intel, don't
  * bother. This does all cores. Again, note, we make these decisions at runtime,
- * to avoid getting into the problems that compile-time decisions can cause. 
+ * to avoid getting into the problems that compile-time decisions can cause.
  * At this point, of course, it's still all intel.
  */
 void vmm_init(void)
index 1ce2f92..3203faf 100644 (file)
@@ -26,6 +26,7 @@ struct guest_pcore {
                struct vmx_msr_entry host[NR_AUTOLOAD_MSRS];
        } msr_autoload;
        struct vmcs *vmcs;
+       uint64_t xcr0;
 };
 
 struct vmm {