Linus,

please pull the latest x86-urgent-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 
x86-urgent-for-linus

This update contains:

  - MPX updates for handling 32bit processes

  - A fix for a long standing bug in 32bit signal frame handling
    related to FPU/XSAVE state

  - Handle get_xsave_addr() correctly in KVM

  - Fix SMAP check under paravirtualization

  - Add a comment to the static function trace entry to avoid further
    confusion about the difference to dynamic tracing.

Thanks,

        tglx

------------------>
Andrew Cooper (1):
      x86/cpu: Fix SMAP check in PVOPS environments

Dave Hansen (3):
      x86/mpx: Do proper get_user() when running 32-bit binaries on 64-bit 
kernels
      x86/mpx: Fix 32-bit address space calculation
      x86/fpu: Fix 32-bit signal frame handling

Huaitong Han (1):
      x86/fpu: Fix get_xsave_addr() behavior under virtualization

Namhyung Kim (1):
      x86/ftrace: Add comment on static function tracing


 arch/x86/kernel/cpu/common.c |  3 +--
 arch/x86/kernel/fpu/signal.c | 11 +++++------
 arch/x86/kernel/fpu/xstate.c |  1 -
 arch/x86/kernel/mcount_64.S  |  6 ++++++
 arch/x86/mm/mpx.c            | 47 ++++++++++++++++++++++++++++++++++++++------
 5 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 4ddd780aeac9..c2b7522cbf35 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -273,10 +273,9 @@ __setup("nosmap", setup_disable_smap);
 
 static __always_inline void setup_smap(struct cpuinfo_x86 *c)
 {
-       unsigned long eflags;
+       unsigned long eflags = native_save_fl();
 
        /* This should have been cleared long ago */
-       raw_local_save_flags(eflags);
        BUG_ON(eflags & X86_EFLAGS_AC);
 
        if (cpu_has(c, X86_FEATURE_SMAP)) {
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index ef29b742cea7..31c6a60505e6 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -385,20 +385,19 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame,
  */
 void fpu__init_prepare_fx_sw_frame(void)
 {
-       int fsave_header_size = sizeof(struct fregs_state);
        int size = xstate_size + FP_XSTATE_MAGIC2_SIZE;
 
-       if (config_enabled(CONFIG_X86_32))
-               size += fsave_header_size;
-
        fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1;
        fx_sw_reserved.extended_size = size;
        fx_sw_reserved.xfeatures = xfeatures_mask;
        fx_sw_reserved.xstate_size = xstate_size;
 
-       if (config_enabled(CONFIG_IA32_EMULATION)) {
+       if (config_enabled(CONFIG_IA32_EMULATION) ||
+           config_enabled(CONFIG_X86_32)) {
+               int fsave_header_size = sizeof(struct fregs_state);
+
                fx_sw_reserved_ia32 = fx_sw_reserved;
-               fx_sw_reserved_ia32.extended_size += fsave_header_size;
+               fx_sw_reserved_ia32.extended_size = size + fsave_header_size;
        }
 }
 
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 6454f2731b56..70fc312221fc 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -694,7 +694,6 @@ void *get_xsave_addr(struct xregs_state *xsave, int 
xstate_feature)
        if (!boot_cpu_has(X86_FEATURE_XSAVE))
                return NULL;
 
-       xsave = &current->thread.fpu.state.xsave;
        /*
         * We should not ever be requesting features that we
         * have not enabled.  Remember that pcntxt_mask is
diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S
index 94ea120fa21f..87e1762e2bca 100644
--- a/arch/x86/kernel/mcount_64.S
+++ b/arch/x86/kernel/mcount_64.S
@@ -278,6 +278,12 @@ trace:
        /* save_mcount_regs fills in first two parameters */
        save_mcount_regs
 
+       /*
+        * When DYNAMIC_FTRACE is not defined, ARCH_SUPPORTS_FTRACE_OPS is not
+        * set (see include/asm/ftrace.h and include/linux/ftrace.h).  Only the
+        * ip and parent ip are used and the list function is called when
+        * function tracing is enabled.
+        */
        call   *ftrace_trace_function
 
        restore_mcount_regs
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
index b0ae85f90f10..1202d5ca2fb5 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
@@ -586,6 +586,29 @@ static unsigned long mpx_bd_entry_to_bt_addr(struct 
mm_struct *mm,
 }
 
 /*
+ * We only want to do a 4-byte get_user() on 32-bit.  Otherwise,
+ * we might run off the end of the bounds table if we are on
+ * a 64-bit kernel and try to get 8 bytes.
+ */
+int get_user_bd_entry(struct mm_struct *mm, unsigned long *bd_entry_ret,
+               long __user *bd_entry_ptr)
+{
+       u32 bd_entry_32;
+       int ret;
+
+       if (is_64bit_mm(mm))
+               return get_user(*bd_entry_ret, bd_entry_ptr);
+
+       /*
+        * Note that get_user() uses the type of the *pointer* to
+        * establish the size of the get, not the destination.
+        */
+       ret = get_user(bd_entry_32, (u32 __user *)bd_entry_ptr);
+       *bd_entry_ret = bd_entry_32;
+       return ret;
+}
+
+/*
  * Get the base of bounds tables pointed by specific bounds
  * directory entry.
  */
@@ -605,7 +628,7 @@ static int get_bt_addr(struct mm_struct *mm,
                int need_write = 0;
 
                pagefault_disable();
-               ret = get_user(bd_entry, bd_entry_ptr);
+               ret = get_user_bd_entry(mm, &bd_entry, bd_entry_ptr);
                pagefault_enable();
                if (!ret)
                        break;
@@ -700,11 +723,23 @@ static unsigned long mpx_get_bt_entry_offset_bytes(struct 
mm_struct *mm,
  */
 static inline unsigned long bd_entry_virt_space(struct mm_struct *mm)
 {
-       unsigned long long virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
-       if (is_64bit_mm(mm))
-               return virt_space / MPX_BD_NR_ENTRIES_64;
-       else
-               return virt_space / MPX_BD_NR_ENTRIES_32;
+       unsigned long long virt_space;
+       unsigned long long GB = (1ULL << 30);
+
+       /*
+        * This covers 32-bit emulation as well as 32-bit kernels
+        * running on 64-bit harware.
+        */
+       if (!is_64bit_mm(mm))
+               return (4ULL * GB) / MPX_BD_NR_ENTRIES_32;
+
+       /*
+        * 'x86_virt_bits' returns what the hardware is capable
+        * of, and returns the full >32-bit adddress space when
+        * running 32-bit kernels on 64-bit hardware.
+        */
+       virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
+       return virt_space / MPX_BD_NR_ENTRIES_64;
 }
 
 /*
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to