Skip to content

Commit 069ec22

Browse files
committed
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: "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" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/cpu: Fix SMAP check in PVOPS environments x86/ftrace: Add comment on static function tracing x86/fpu: Fix get_xsave_addr() behavior under virtualization x86/fpu: Fix 32-bit signal frame handling x86/mpx: Fix 32-bit address space calculation x86/mpx: Do proper get_user() when running 32-bit binaries on 64-bit kernels
2 parents 3ad5d7e + 581b7f1 commit 069ec22

File tree

5 files changed

+53
-15
lines changed

5 files changed

+53
-15
lines changed

arch/x86/kernel/cpu/common.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,9 @@ __setup("nosmap", setup_disable_smap);
273273

274274
static __always_inline void setup_smap(struct cpuinfo_x86 *c)
275275
{
276-
unsigned long eflags;
276+
unsigned long eflags = native_save_fl();
277277

278278
/* This should have been cleared long ago */
279-
raw_local_save_flags(eflags);
280279
BUG_ON(eflags & X86_EFLAGS_AC);
281280

282281
if (cpu_has(c, X86_FEATURE_SMAP)) {

arch/x86/kernel/fpu/signal.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -385,20 +385,19 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame,
385385
*/
386386
void fpu__init_prepare_fx_sw_frame(void)
387387
{
388-
int fsave_header_size = sizeof(struct fregs_state);
389388
int size = xstate_size + FP_XSTATE_MAGIC2_SIZE;
390389

391-
if (config_enabled(CONFIG_X86_32))
392-
size += fsave_header_size;
393-
394390
fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1;
395391
fx_sw_reserved.extended_size = size;
396392
fx_sw_reserved.xfeatures = xfeatures_mask;
397393
fx_sw_reserved.xstate_size = xstate_size;
398394

399-
if (config_enabled(CONFIG_IA32_EMULATION)) {
395+
if (config_enabled(CONFIG_IA32_EMULATION) ||
396+
config_enabled(CONFIG_X86_32)) {
397+
int fsave_header_size = sizeof(struct fregs_state);
398+
400399
fx_sw_reserved_ia32 = fx_sw_reserved;
401-
fx_sw_reserved_ia32.extended_size += fsave_header_size;
400+
fx_sw_reserved_ia32.extended_size = size + fsave_header_size;
402401
}
403402
}
404403

arch/x86/kernel/fpu/xstate.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,6 @@ void *get_xsave_addr(struct xregs_state *xsave, int xstate_feature)
694694
if (!boot_cpu_has(X86_FEATURE_XSAVE))
695695
return NULL;
696696

697-
xsave = &current->thread.fpu.state.xsave;
698697
/*
699698
* We should not ever be requesting features that we
700699
* have not enabled. Remember that pcntxt_mask is

arch/x86/kernel/mcount_64.S

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ trace:
278278
/* save_mcount_regs fills in first two parameters */
279279
save_mcount_regs
280280

281+
/*
282+
* When DYNAMIC_FTRACE is not defined, ARCH_SUPPORTS_FTRACE_OPS is not
283+
* set (see include/asm/ftrace.h and include/linux/ftrace.h). Only the
284+
* ip and parent ip are used and the list function is called when
285+
* function tracing is enabled.
286+
*/
281287
call *ftrace_trace_function
282288

283289
restore_mcount_regs

arch/x86/mm/mpx.c

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,29 @@ static unsigned long mpx_bd_entry_to_bt_addr(struct mm_struct *mm,
585585
return bt_addr;
586586
}
587587

588+
/*
589+
* We only want to do a 4-byte get_user() on 32-bit. Otherwise,
590+
* we might run off the end of the bounds table if we are on
591+
* a 64-bit kernel and try to get 8 bytes.
592+
*/
593+
int get_user_bd_entry(struct mm_struct *mm, unsigned long *bd_entry_ret,
594+
long __user *bd_entry_ptr)
595+
{
596+
u32 bd_entry_32;
597+
int ret;
598+
599+
if (is_64bit_mm(mm))
600+
return get_user(*bd_entry_ret, bd_entry_ptr);
601+
602+
/*
603+
* Note that get_user() uses the type of the *pointer* to
604+
* establish the size of the get, not the destination.
605+
*/
606+
ret = get_user(bd_entry_32, (u32 __user *)bd_entry_ptr);
607+
*bd_entry_ret = bd_entry_32;
608+
return ret;
609+
}
610+
588611
/*
589612
* Get the base of bounds tables pointed by specific bounds
590613
* directory entry.
@@ -605,7 +628,7 @@ static int get_bt_addr(struct mm_struct *mm,
605628
int need_write = 0;
606629

607630
pagefault_disable();
608-
ret = get_user(bd_entry, bd_entry_ptr);
631+
ret = get_user_bd_entry(mm, &bd_entry, bd_entry_ptr);
609632
pagefault_enable();
610633
if (!ret)
611634
break;
@@ -700,11 +723,23 @@ static unsigned long mpx_get_bt_entry_offset_bytes(struct mm_struct *mm,
700723
*/
701724
static inline unsigned long bd_entry_virt_space(struct mm_struct *mm)
702725
{
703-
unsigned long long virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
704-
if (is_64bit_mm(mm))
705-
return virt_space / MPX_BD_NR_ENTRIES_64;
706-
else
707-
return virt_space / MPX_BD_NR_ENTRIES_32;
726+
unsigned long long virt_space;
727+
unsigned long long GB = (1ULL << 30);
728+
729+
/*
730+
* This covers 32-bit emulation as well as 32-bit kernels
731+
* running on 64-bit harware.
732+
*/
733+
if (!is_64bit_mm(mm))
734+
return (4ULL * GB) / MPX_BD_NR_ENTRIES_32;
735+
736+
/*
737+
* 'x86_virt_bits' returns what the hardware is capable
738+
* of, and returns the full >32-bit adddress space when
739+
* running 32-bit kernels on 64-bit hardware.
740+
*/
741+
virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
742+
return virt_space / MPX_BD_NR_ENTRIES_64;
708743
}
709744

710745
/*

0 commit comments

Comments
 (0)