[PATCH 13/23] x86/fpu: Make get_xsave_field_ptr() and get_xsave_addr() use feature number instead of mask

2018-11-07 Thread Sebastian Andrzej Siewior
After changing the argument of __raw_xsave_addr() from a mask to number
Dave suggested to check if it makes sense to do the same for
get_xsave_addr(). As it turns out it does. Only get_xsave_addr() needs
the mask to check if the requested feature is part of what is
support/saved and then uses the number again. The shift operation is
cheaper compared to "find last bit set". Also, the feature number uses
less opcode space compared to the mask :)

Make get_xsave_addr() argument a xfeature number instead of mask and fix
up its callers.
As part of this use xfeature_nr and xfeature_mask consistently.
This results in changes to the kvm code as:
feature -> xfeature_mask
index -> xfeature_nr

Suggested-by: Dave Hansen 
Signed-off-by: Sebastian Andrzej Siewior 
---
 arch/x86/include/asm/fpu/xstate.h |  4 ++--
 arch/x86/kernel/fpu/xstate.c  | 23 +++
 arch/x86/kernel/traps.c   |  2 +-
 arch/x86/kvm/x86.c| 28 ++--
 arch/x86/mm/mpx.c |  6 +++---
 5 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/arch/x86/include/asm/fpu/xstate.h 
b/arch/x86/include/asm/fpu/xstate.h
index 48581988d78c7..fbe41f808e5d8 100644
--- a/arch/x86/include/asm/fpu/xstate.h
+++ b/arch/x86/include/asm/fpu/xstate.h
@@ -46,8 +46,8 @@ extern void __init update_regset_xstate_info(unsigned int 
size,
 u64 xstate_mask);
 
 void fpu__xstate_clear_all_cpu_caps(void);
-void *get_xsave_addr(struct xregs_state *xsave, int xstate);
-const void *get_xsave_field_ptr(int xstate_field);
+void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr);
+const void *get_xsave_field_ptr(int xfeature_nr);
 int using_compacted_format(void);
 int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int 
offset, unsigned int size);
 int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned 
int offset, unsigned int size);
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 3dfe3627deaf6..375226055a413 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -832,15 +832,15 @@ static void *__raw_xsave_addr(struct xregs_state *xsave, 
int xfeature_nr)
  *
  * Inputs:
  * xstate: the thread's storage area for all FPU data
- * xstate_feature: state which is defined in xsave.h (e.g.
- * XFEATURE_MASK_FP, XFEATURE_MASK_SSE, etc...)
+ * xfeature_nr: state which is defined in xsave.h (e.g. XFEATURE_FP,
+ * XFEATURE_SSE, etc...)
  * Output:
  * address of the state in the xsave area, or NULL if the
  * field is not present in the xsave buffer.
  */
-void *get_xsave_addr(struct xregs_state *xsave, int xstate_feature)
+void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
 {
-   int xfeature_nr;
+   u64 xfeature_mask = 1ULL << xfeature_nr;
/*
 * Do we even *have* xsave state?
 */
@@ -852,11 +852,11 @@ void *get_xsave_addr(struct xregs_state *xsave, int 
xstate_feature)
 * have not enabled.  Remember that pcntxt_mask is
 * what we write to the XCR0 register.
 */
-   WARN_ONCE(!(xfeatures_mask & xstate_feature),
+   WARN_ONCE(!(xfeatures_mask & xfeature_mask),
  "get of unsupported state");
/*
 * This assumes the last 'xsave*' instruction to
-* have requested that 'xstate_feature' be saved.
+* have requested that 'xfeature_mask' be saved.
 * If it did not, we might be seeing and old value
 * of the field in the buffer.
 *
@@ -865,10 +865,9 @@ void *get_xsave_addr(struct xregs_state *xsave, int 
xstate_feature)
 * or because the "init optimization" caused it
 * to not be saved.
 */
-   if (!(xsave->header.xfeatures & xstate_feature))
+   if (!(xsave->header.xfeatures & xfeature_mask))
return NULL;
 
-   xfeature_nr = fls64(xstate_feature) - 1;
return __raw_xsave_addr(xsave, xfeature_nr);
 }
 EXPORT_SYMBOL_GPL(get_xsave_addr);
@@ -884,13 +883,13 @@ EXPORT_SYMBOL_GPL(get_xsave_addr);
  * Note that this only works on the current task.
  *
  * Inputs:
- * @xsave_state: state which is defined in xsave.h (e.g. XFEATURE_MASK_FP,
- * XFEATURE_MASK_SSE, etc...)
+ * @xfeature_nr: state which is defined in xsave.h (e.g. XFEATURE_FP,
+ * XFEATURE_SSE, etc...)
  * Output:
  * address of the state in the xsave area or NULL if the state
  * is not present or is in its 'init state'.
  */
-const void *get_xsave_field_ptr(int xsave_state)
+const void *get_xsave_field_ptr(int xfeature_nr)
 {
struct fpu *fpu = >thread.fpu;
 
@@ -900,7 +899,7 @@ const void *get_xsave_field_ptr(int xsave_state)
 */
fpu__save(fpu);
 
-   return get_xsave_addr(>state.xsave, xsave_state);
+   return get_xsave_addr(>state.xsave, xfeature_nr);
 }
 
 #ifdef CONFIG_ARCH_HAS_PKEYS
diff --git 

[PATCH 13/23] x86/fpu: Make get_xsave_field_ptr() and get_xsave_addr() use feature number instead of mask

2018-11-07 Thread Sebastian Andrzej Siewior
After changing the argument of __raw_xsave_addr() from a mask to number
Dave suggested to check if it makes sense to do the same for
get_xsave_addr(). As it turns out it does. Only get_xsave_addr() needs
the mask to check if the requested feature is part of what is
support/saved and then uses the number again. The shift operation is
cheaper compared to "find last bit set". Also, the feature number uses
less opcode space compared to the mask :)

Make get_xsave_addr() argument a xfeature number instead of mask and fix
up its callers.
As part of this use xfeature_nr and xfeature_mask consistently.
This results in changes to the kvm code as:
feature -> xfeature_mask
index -> xfeature_nr

Suggested-by: Dave Hansen 
Signed-off-by: Sebastian Andrzej Siewior 
---
 arch/x86/include/asm/fpu/xstate.h |  4 ++--
 arch/x86/kernel/fpu/xstate.c  | 23 +++
 arch/x86/kernel/traps.c   |  2 +-
 arch/x86/kvm/x86.c| 28 ++--
 arch/x86/mm/mpx.c |  6 +++---
 5 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/arch/x86/include/asm/fpu/xstate.h 
b/arch/x86/include/asm/fpu/xstate.h
index 48581988d78c7..fbe41f808e5d8 100644
--- a/arch/x86/include/asm/fpu/xstate.h
+++ b/arch/x86/include/asm/fpu/xstate.h
@@ -46,8 +46,8 @@ extern void __init update_regset_xstate_info(unsigned int 
size,
 u64 xstate_mask);
 
 void fpu__xstate_clear_all_cpu_caps(void);
-void *get_xsave_addr(struct xregs_state *xsave, int xstate);
-const void *get_xsave_field_ptr(int xstate_field);
+void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr);
+const void *get_xsave_field_ptr(int xfeature_nr);
 int using_compacted_format(void);
 int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int 
offset, unsigned int size);
 int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned 
int offset, unsigned int size);
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 3dfe3627deaf6..375226055a413 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -832,15 +832,15 @@ static void *__raw_xsave_addr(struct xregs_state *xsave, 
int xfeature_nr)
  *
  * Inputs:
  * xstate: the thread's storage area for all FPU data
- * xstate_feature: state which is defined in xsave.h (e.g.
- * XFEATURE_MASK_FP, XFEATURE_MASK_SSE, etc...)
+ * xfeature_nr: state which is defined in xsave.h (e.g. XFEATURE_FP,
+ * XFEATURE_SSE, etc...)
  * Output:
  * address of the state in the xsave area, or NULL if the
  * field is not present in the xsave buffer.
  */
-void *get_xsave_addr(struct xregs_state *xsave, int xstate_feature)
+void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
 {
-   int xfeature_nr;
+   u64 xfeature_mask = 1ULL << xfeature_nr;
/*
 * Do we even *have* xsave state?
 */
@@ -852,11 +852,11 @@ void *get_xsave_addr(struct xregs_state *xsave, int 
xstate_feature)
 * have not enabled.  Remember that pcntxt_mask is
 * what we write to the XCR0 register.
 */
-   WARN_ONCE(!(xfeatures_mask & xstate_feature),
+   WARN_ONCE(!(xfeatures_mask & xfeature_mask),
  "get of unsupported state");
/*
 * This assumes the last 'xsave*' instruction to
-* have requested that 'xstate_feature' be saved.
+* have requested that 'xfeature_mask' be saved.
 * If it did not, we might be seeing and old value
 * of the field in the buffer.
 *
@@ -865,10 +865,9 @@ void *get_xsave_addr(struct xregs_state *xsave, int 
xstate_feature)
 * or because the "init optimization" caused it
 * to not be saved.
 */
-   if (!(xsave->header.xfeatures & xstate_feature))
+   if (!(xsave->header.xfeatures & xfeature_mask))
return NULL;
 
-   xfeature_nr = fls64(xstate_feature) - 1;
return __raw_xsave_addr(xsave, xfeature_nr);
 }
 EXPORT_SYMBOL_GPL(get_xsave_addr);
@@ -884,13 +883,13 @@ EXPORT_SYMBOL_GPL(get_xsave_addr);
  * Note that this only works on the current task.
  *
  * Inputs:
- * @xsave_state: state which is defined in xsave.h (e.g. XFEATURE_MASK_FP,
- * XFEATURE_MASK_SSE, etc...)
+ * @xfeature_nr: state which is defined in xsave.h (e.g. XFEATURE_FP,
+ * XFEATURE_SSE, etc...)
  * Output:
  * address of the state in the xsave area or NULL if the state
  * is not present or is in its 'init state'.
  */
-const void *get_xsave_field_ptr(int xsave_state)
+const void *get_xsave_field_ptr(int xfeature_nr)
 {
struct fpu *fpu = >thread.fpu;
 
@@ -900,7 +899,7 @@ const void *get_xsave_field_ptr(int xsave_state)
 */
fpu__save(fpu);
 
-   return get_xsave_addr(>state.xsave, xsave_state);
+   return get_xsave_addr(>state.xsave, xfeature_nr);
 }
 
 #ifdef CONFIG_ARCH_HAS_PKEYS
diff --git