linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [tip:x86/xsave] Define kernel API to get address of each state in xsave area
       [not found] <1401387164-43416-17-git-send-email-fenghua.yu@intel.com>
@ 2014-05-30 15:13 ` tip-bot for Fenghua Yu
  2014-05-31  3:36 ` [tip:x86/xsave] x86/xsaves: Clean up code in xstate offsets computation " tip-bot for Fenghua Yu
  1 sibling, 0 replies; 2+ messages in thread
From: tip-bot for Fenghua Yu @ 2014-05-30 15:13 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, fenghua.yu, tglx, hpa

Commit-ID:  7496d6458fe3219d63848ce4a9afbd86245cab22
Gitweb:     http://git.kernel.org/tip/7496d6458fe3219d63848ce4a9afbd86245cab22
Author:     Fenghua Yu <fenghua.yu@intel.com>
AuthorDate: Thu, 29 May 2014 11:12:44 -0700
Committer:  H. Peter Anvin <hpa@linux.intel.com>
CommitDate: Thu, 29 May 2014 14:33:09 -0700

Define kernel API to get address of each state in xsave area

In standard form, each state is saved in the xsave area in fixed offset.
But in compacted form, offset of each saved state only can be calculated during
run time because some xstates may not be enabled and saved.

We define kernel API get_xsave_addr() returns address of a given state saved in a xsave area.

It can be called in kernel to get address of each xstate in xsave area in
either standard format or compacted format.

It's useful when kernel wants to directly access each state in xsave area.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Link: http://lkml.kernel.org/r/1401387164-43416-17-git-send-email-fenghua.yu@intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
 arch/x86/include/asm/xsave.h |  3 +++
 arch/x86/kernel/process.c    |  1 +
 arch/x86/kernel/xsave.c      | 64 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)

diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h
index aa3ff0c..1ba577c 100644
--- a/arch/x86/include/asm/xsave.h
+++ b/arch/x86/include/asm/xsave.h
@@ -255,4 +255,7 @@ static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask)
 	return err;
 }
 
+void *get_xsave_addr(struct xsave_struct *xsave, int xstate);
+void setup_xstate_comp(void);
+
 #endif
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 4505e2a..f804dc9 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -93,6 +93,7 @@ void arch_task_cache_init(void)
         	kmem_cache_create("task_xstate", xstate_size,
 				  __alignof__(union thread_xstate),
 				  SLAB_PANIC | SLAB_NOTRACK, NULL);
+	setup_xstate_comp();
 }
 
 /*
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index f930f8a..a6cb823 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -482,6 +482,47 @@ static void __init setup_xstate_features(void)
 }
 
 /*
+ * This function sets up offsets and sizes of all extended states in
+ * xsave area. This supports both standard format and compacted format
+ * of the xsave aread.
+ *
+ * Input: void
+ * Output: void
+ */
+void setup_xstate_comp(void)
+{
+	int i;
+
+	xstate_comp_offsets = kmalloc(xstate_features * sizeof(int),
+				      GFP_KERNEL);
+	xstate_comp_sizes = kmalloc(xstate_features * sizeof(int), GFP_KERNEL);
+
+	if (!cpu_has_xsaves) {
+		for (i = 2; i < xstate_features; i++) {
+			if (test_bit(i, (unsigned long *)&pcntxt_mask)) {
+				xstate_comp_offsets[i] = xstate_offsets[i];
+				xstate_comp_sizes[i] = xstate_sizes[i];
+			}
+		}
+		return;
+	}
+
+	xstate_comp_offsets[2] = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+
+	for (i = 2; i < xstate_features; i++) {
+		if (test_bit(i, (unsigned long *)&pcntxt_mask))
+			xstate_comp_sizes[i] = xstate_sizes[i];
+		else
+			xstate_comp_sizes[i] = 0;
+
+		if (i > 2)
+			xstate_comp_offsets[i] = xstate_comp_offsets[i-1]
+					+ xstate_comp_sizes[i-1];
+
+	}
+}
+
+/*
  * setup the xstate image representing the init state
  */
 static void __init setup_init_fpu_buf(void)
@@ -668,3 +709,26 @@ void eager_fpu_init(void)
 	else
 		fxrstor_checking(&init_xstate_buf->i387);
 }
+
+/*
+ * Given the xsave area and a state inside, this function returns the
+ * address of the state.
+ *
+ * This is the API that is called to get xstate address in either
+ * standard format or compacted format of xsave area.
+ *
+ * Inputs:
+ *	xsave: base address of the xsave area;
+ *	xstate: state which is defined in xsave.h (e.g. XSTATE_FP, XSTATE_SSE,
+ *	etc.)
+ * Output:
+ *	address of the state in the xsave area.
+ */
+void *get_xsave_addr(struct xsave_struct *xsave, int xstate)
+{
+	int feature = fls64(xstate) - 1;
+	if (!test_bit(feature, (unsigned long *)&pcntxt_mask))
+		return NULL;
+
+	return (void *)xsave + xstate_comp_offsets[feature];
+}

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [tip:x86/xsave] x86/xsaves: Clean up code in xstate offsets computation in xsave area
       [not found] <1401387164-43416-17-git-send-email-fenghua.yu@intel.com>
  2014-05-30 15:13 ` [tip:x86/xsave] Define kernel API to get address of each state in xsave area tip-bot for Fenghua Yu
@ 2014-05-31  3:36 ` tip-bot for Fenghua Yu
  1 sibling, 0 replies; 2+ messages in thread
From: tip-bot for Fenghua Yu @ 2014-05-31  3:36 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, fenghua.yu, tglx, hpa

Commit-ID:  8ff925e10f2c72680918b95173ef4f8bb982d59e
Gitweb:     http://git.kernel.org/tip/8ff925e10f2c72680918b95173ef4f8bb982d59e
Author:     Fenghua Yu <fenghua.yu@intel.com>
AuthorDate: Fri, 30 May 2014 14:59:24 -0700
Committer:  H. Peter Anvin <hpa@linux.intel.com>
CommitDate: Fri, 30 May 2014 17:12:41 -0700

x86/xsaves: Clean up code in xstate offsets computation in xsave area

This patch cleans up some code in xstate offsets computation in xsave
area:

1. It changes xstate_comp_offsets as an array. This avoids possible NULL pointer
   caused by possible kmalloc() failure during boot time.
2. It changes the global variable xstate_comp_sizes to a local variable because
   it is used only in setup_xstate_comp().
3. It adds missing offsets for FP and SSE in xsave area.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Link: http://lkml.kernel.org/r/1401387164-43416-17-git-send-email-fenghua.yu@intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
 arch/x86/kernel/xsave.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index a6cb823..940b142 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -26,7 +26,7 @@ struct xsave_struct *init_xstate_buf;
 
 static struct _fpx_sw_bytes fx_sw_reserved, fx_sw_reserved_ia32;
 static unsigned int *xstate_offsets, *xstate_sizes;
-static unsigned int *xstate_comp_offsets, *xstate_comp_sizes;
+static unsigned int xstate_comp_offsets[sizeof(pcntxt_mask)*8];
 static unsigned int xstate_features;
 
 /*
@@ -491,11 +491,16 @@ static void __init setup_xstate_features(void)
  */
 void setup_xstate_comp(void)
 {
+	unsigned int xstate_comp_sizes[sizeof(pcntxt_mask)*8];
 	int i;
 
-	xstate_comp_offsets = kmalloc(xstate_features * sizeof(int),
-				      GFP_KERNEL);
-	xstate_comp_sizes = kmalloc(xstate_features * sizeof(int), GFP_KERNEL);
+	/*
+	 * The FP xstates and SSE xstates are legacy states. They are always
+	 * in the fixed offsets in the xsave area in either compacted form
+	 * or standard form.
+	 */
+	xstate_comp_offsets[0] = 0;
+	xstate_comp_offsets[1] = offsetof(struct i387_fxsave_struct, xmm_space);
 
 	if (!cpu_has_xsaves) {
 		for (i = 2; i < xstate_features; i++) {

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-05-31  3:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1401387164-43416-17-git-send-email-fenghua.yu@intel.com>
2014-05-30 15:13 ` [tip:x86/xsave] Define kernel API to get address of each state in xsave area tip-bot for Fenghua Yu
2014-05-31  3:36 ` [tip:x86/xsave] x86/xsaves: Clean up code in xstate offsets computation " tip-bot for Fenghua Yu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).