Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+53 -15
+1 -2
arch/x86/kernel/cpu/common.c
··· 273 273 274 274 static __always_inline void setup_smap(struct cpuinfo_x86 *c) 275 275 { 276 - unsigned long eflags; 276 + unsigned long eflags = native_save_fl(); 277 277 278 278 /* This should have been cleared long ago */ 279 - raw_local_save_flags(eflags); 280 279 BUG_ON(eflags & X86_EFLAGS_AC); 281 280 282 281 if (cpu_has(c, X86_FEATURE_SMAP)) {
+5 -6
arch/x86/kernel/fpu/signal.c
··· 385 385 */ 386 386 void fpu__init_prepare_fx_sw_frame(void) 387 387 { 388 - int fsave_header_size = sizeof(struct fregs_state); 389 388 int size = xstate_size + FP_XSTATE_MAGIC2_SIZE; 390 - 391 - if (config_enabled(CONFIG_X86_32)) 392 - size += fsave_header_size; 393 389 394 390 fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1; 395 391 fx_sw_reserved.extended_size = size; 396 392 fx_sw_reserved.xfeatures = xfeatures_mask; 397 393 fx_sw_reserved.xstate_size = xstate_size; 398 394 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 + 400 399 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; 402 401 } 403 402 } 404 403
-1
arch/x86/kernel/fpu/xstate.c
··· 694 694 if (!boot_cpu_has(X86_FEATURE_XSAVE)) 695 695 return NULL; 696 696 697 - xsave = &current->thread.fpu.state.xsave; 698 697 /* 699 698 * We should not ever be requesting features that we 700 699 * have not enabled. Remember that pcntxt_mask is
+6
arch/x86/kernel/mcount_64.S
··· 278 278 /* save_mcount_regs fills in first two parameters */ 279 279 save_mcount_regs 280 280 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 + */ 281 287 call *ftrace_trace_function 282 288 283 289 restore_mcount_regs
+41 -6
arch/x86/mm/mpx.c
··· 586 586 } 587 587 588 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 + 611 + /* 589 612 * Get the base of bounds tables pointed by specific bounds 590 613 * directory entry. 591 614 */ ··· 628 605 int need_write = 0; 629 606 630 607 pagefault_disable(); 631 - ret = get_user(bd_entry, bd_entry_ptr); 608 + ret = get_user_bd_entry(mm, &bd_entry, bd_entry_ptr); 632 609 pagefault_enable(); 633 610 if (!ret) 634 611 break; ··· 723 700 */ 724 701 static inline unsigned long bd_entry_virt_space(struct mm_struct *mm) 725 702 { 726 - unsigned long long virt_space = (1ULL << boot_cpu_data.x86_virt_bits); 727 - if (is_64bit_mm(mm)) 728 - return virt_space / MPX_BD_NR_ENTRIES_64; 729 - else 730 - return virt_space / MPX_BD_NR_ENTRIES_32; 703 + unsigned long long virt_space; 704 + unsigned long long GB = (1ULL << 30); 705 + 706 + /* 707 + * This covers 32-bit emulation as well as 32-bit kernels 708 + * running on 64-bit harware. 709 + */ 710 + if (!is_64bit_mm(mm)) 711 + return (4ULL * GB) / MPX_BD_NR_ENTRIES_32; 712 + 713 + /* 714 + * 'x86_virt_bits' returns what the hardware is capable 715 + * of, and returns the full >32-bit adddress space when 716 + * running 32-bit kernels on 64-bit hardware. 717 + */ 718 + virt_space = (1ULL << boot_cpu_data.x86_virt_bits); 719 + return virt_space / MPX_BD_NR_ENTRIES_64; 731 720 } 732 721 733 722 /*