]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
x86, xsave: Track the offset, size of state in the xsave layout
authorSuresh Siddha <suresh.b.siddha@intel.com>
Mon, 19 Jul 2010 23:05:48 +0000 (16:05 -0700)
committerH. Peter Anvin <hpa@linux.intel.com>
Tue, 20 Jul 2010 00:51:17 +0000 (17:51 -0700)
Subleaves of the cpuid vector 0xd provides the offset and size of different
feature state that are managed by the xsave/xrstor. Track this for the upcoming
usage during signal handling.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
LKML-Reference: <20100719230205.262987929@sbs-t61.sc.intel.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
arch/x86/kernel/xsave.c

index 980149867a1910db07040aed05537ecd66e3752e..4993caa4181c3a942f3625c8a7eef50714811a7d 100644 (file)
@@ -21,6 +21,8 @@ struct _fpx_sw_bytes fx_sw_reserved;
 struct _fpx_sw_bytes fx_sw_reserved_ia32;
 #endif
 
+static unsigned int *xstate_offsets, *xstate_sizes, xstate_features;
+
 /*
  * Check for the presence of extended state information in the
  * user fpstate pointer in the sigcontext.
@@ -301,6 +303,31 @@ void __cpuinit xsave_init(void)
        xsetbv(XCR_XFEATURE_ENABLED_MASK, pcntxt_mask);
 }
 
+/*
+ * Record the offsets and sizes of different state managed by the xsave
+ * memory layout.
+ */
+static void setup_xstate_features(void)
+{
+       int eax, ebx, ecx, edx, leaf = 0x2;
+
+       xstate_features = fls64(pcntxt_mask);
+       xstate_offsets = alloc_bootmem(xstate_features * sizeof(int));
+       xstate_sizes = alloc_bootmem(xstate_features * sizeof(int));
+
+       do {
+               cpuid_count(0xd, leaf, &eax, &ebx, &ecx, &edx);
+
+               if (eax == 0)
+                       break;
+
+               xstate_offsets[leaf] = ebx;
+               xstate_sizes[leaf] = eax;
+
+               leaf++;
+       } while (1);
+}
+
 /*
  * setup the xstate image representing the init state
  */
@@ -308,6 +335,8 @@ static void __init setup_xstate_init(void)
 {
        init_xstate_buf = alloc_bootmem(xstate_size);
        init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;
+
+       setup_xstate_features();
 }
 
 /*