x86 fixes
Subsystems (5)
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
# HEAD: d52c0569bab4edc888832df44dc7ac28517134f6 x86/apic/x2apic, smp/hotplug: Don't use before alloc in x2apic_cluster_probe()
This is bigger than usual - the reason is partly a pent-up stream of fixes after the merge window and partly accidental. The fixes are:
- 5 patches to fix a boot failure on Andy Lutomirsky's laptop.
- a KASAN fix
- 4 SGI UV platform fixes
- a warnings fix
- a documentation update
- a swap entry definition fix
- a pkeys fix
- an irq stats fix
Thanks,
Ingo
------------------>
Aaron Lu (1):
x86/irq: Do not substract irq_tlb_count from irq_call_count
Alexander Potapenko (1):
x86, kasan, ftrace: Put APIC interrupt handlers into .irqentry.text
Andy Lutomirski (5):
x86/boot: Run reserve_bios_regions() after we initialize the memory map x86/boot: Synchronize trampoline_cr4_features and mmu_cr4_features directly x86/boot: Defer setup_real_mode() to early_initcall time x86/boot: Rework reserve_real_mode() to allow multiple tries x86/efi: Allocate a trampoline if needed in efi_free_boot_services()
Borislav Petkov (1):
x86/entry: Clarify the RF saving/restoring situation with SYSCALL/SYSRET
Dave Hansen (2):
x86/mm/pkeys: Fix compact mode by removing protection keys' XSAVE buffer manipulation x86/mm: Fix swap entry comment and macro
Mike Travis (4):
x86/platform/UV: Fix problem with UV4 Socket IDs not being contiguous x86/platform/UV: Fix bug with iounmap() of the UV4 EFI System Table causing a crash x86/platform/UV: Fix problem with UV4 BIOS providing incorrect PXM values x86/platform/UV: Fix kernel panic running RHEL kdump kernel on UV systems
Nicolas Iooss (1):
x86/mm/kaslr: Fix -Wformat-security warning
Sebastian Andrzej Siewior (2):
x86/mm: Disable preemption during CR3 read+write x86/apic/x2apic, smp/hotplug: Don't use before alloc in x2apic_cluster_probe()
Thomas Garnier (2):
x86/mm/KASLR: Fix physical memory calculation on KASLR memory randomization x86/mm/KASLR: Increase BRK pages for KASLR memory randomization
Valdis Kletnieks (1):
x86/build: Reduce the W=1 warnings noise when compiling x86 syscall tables
arch/x86/entry/Makefile | 2 + arch/x86/entry/entry_64.S | 25 ++++-- arch/x86/include/asm/hardirq.h | 4 - arch/x86/include/asm/pgtable_64.h | 4 +- arch/x86/include/asm/realmode.h | 10 ++- arch/x86/include/asm/tlbflush.h | 7 ++ arch/x86/include/asm/uv/bios.h | 5 +- arch/x86/kernel/apic/x2apic_cluster.c | 13 +++- arch/x86/kernel/apic/x2apic_uv_x.c | 42 +++++------ arch/x86/kernel/fpu/xstate.c | 138 +++++----------------------------- arch/x86/kernel/head32.c | 2 - arch/x86/kernel/head64.c | 1 - arch/x86/kernel/irq.c | 3 +- arch/x86/kernel/setup.c | 27 ++++--- arch/x86/lib/kaslr.c | 2 +- arch/x86/mm/init.c | 14 +++- arch/x86/mm/kaslr.c | 2 +- arch/x86/platform/efi/quirks.c | 21 ++++++ arch/x86/platform/uv/bios_uv.c | 8 +- arch/x86/realmode/init.c | 47 +++++++++--- 20 files changed, 182 insertions(+), 195 deletions(-)
arch/x86/entry/Makefile +2 -0
@@ -5,6 +5,8 @@ OBJECT_FILES_NON_STANDARD_entry_$(BITS).o := y OBJECT_FILES_NON_STANDARD_entry_64_compat.o := y +CFLAGS_syscall_64.o += -Wno-override-init +CFLAGS_syscall_32.o += -Wno-override-init obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o obj-y += common.o
arch/x86/entry/entry_64.S +20 -5
@@ -288,11 +288,15 @@ GLOBAL(entry_SYSCALL_64_after_swapgs) jne opportunistic_sysret_failed /* - * SYSRET can't restore RF. SYSRET can restore TF, but unlike IRET, - * restoring TF results in a trap from userspace immediately after - * SYSRET. This would cause an infinite loop whenever #DB happens - * with register state that satisfies the opportunistic SYSRET - * conditions. For example, single-stepping this user code: + * SYSCALL clears RF when it saves RFLAGS in R11 and SYSRET cannot + * restore RF properly. If the slowpath sets it for whatever reason, we + * need to restore it correctly. + * + * SYSRET can restore TF, but unlike IRET, restoring TF results in a + * trap from userspace immediately after SYSRET. This would cause an + * infinite loop whenever #DB happens with register state that satisfies + * the opportunistic SYSRET conditions. For example, single-stepping + * this user code: * * movq $stuck_here, %rcx * pushfq
@@ -601,9 +605,20 @@ apicinterrupt3 \num trace(\sym) smp_trace(\sym) .endm #endif +/* Make sure APIC interrupt handlers end up in the irqentry section: */ +#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN) +# define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax" +# define POP_SECTION_IRQENTRY .popsection +#else +# define PUSH_SECTION_IRQENTRY +# define POP_SECTION_IRQENTRY +#endif + .macro apicinterrupt num sym do_sym +PUSH_SECTION_IRQENTRY apicinterrupt3 \num \sym \do_sym trace_apicinterrupt \num \sym +POP_SECTION_IRQENTRY .endm #ifdef CONFIG_SMP
arch/x86/include/asm/hardirq.h +0 -4
@@ -22,10 +22,6 @@ typedef struct {#ifdef CONFIG_SMP unsigned int irq_resched_count;unsigned int irq_call_count; -/* -* irq_tlb_count is double-counted in irq_call_count, so it must be -* subtracted from irq_call_count when displaying irq_call_count -*/ unsigned int irq_tlb_count;#endif #ifdef CONFIG_X86_THERMAL_VECTOR
arch/x86/include/asm/pgtable_64.h +2 -2
@@ -145,7 +145,7 @@ static inline int pgd_large(pgd_t pgd) { return 0; }* * | ... | 11| 10| 9|8|7|6|5| 4| 3|2|1|0| <- bit number * | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U|W|P| <- bit names -* | OFFSET (14->63) | TYPE (10-13) |0|X|X|X| X| X|X|X|0| <- swp entry +* | OFFSET (14->63) | TYPE (9-13) |0|X|X|X| X| X|X|X|0| <- swp entry * * G (8) is aliased and used as a PROT_NONE indicator for * !present ptes. We need to start storing swap entries above
@@ -156,7 +156,7 @@ static inline int pgd_large(pgd_t pgd) { return 0; }#define SWP_TYPE_FIRST_BIT (_PAGE_BIT_PROTNONE + 1)#define SWP_TYPE_BITS 5/* Place the offset above the type: */ -#define SWP_OFFSET_FIRST_BIT (SWP_TYPE_FIRST_BIT + SWP_TYPE_BITS + 1) +#define SWP_OFFSET_FIRST_BIT (SWP_TYPE_FIRST_BIT + SWP_TYPE_BITS)#define MAX_SWAPFILES_CHECK () BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)
arch/x86/include/asm/realmode.h +9 -1
@@ -58,7 +58,15 @@ extern unsigned char boot_gdt[];extern unsigned char secondary_startup_64[];#endif +static inline size_t real_mode_size_needed (void ) +{ +if (real_mode_header) +return 0 ;/* already allocated. */ + +return ALIGN (real_mode_blob_end - real_mode_blob,PAGE_SIZE ); +} + +void set_real_mode_mem (phys_addr_t mem,size_t size);void reserve_real_mode (void ); -void setup_real_mode (void );#endif /* _ARCH_X86_REALMODE_H */
arch/x86/include/asm/tlbflush.h +7 -0
@@ -135,7 +135,14 @@ static inline void cr4_set_bits_and_update_boot(unsigned long mask)static inline void __native_flush_tlb (void ) { +/* +* If current->mm == NULL then we borrow a mm which may change during a +* task switch and therefore we must not be preempted while we write CR3 +* back: +*/ +preempt_disable ();native_write_cr3 (native_read_cr3 ()); +preempt_enable (); }static inline void __native_flush_tlb_global_irq_disabled (void )
arch/x86/include/asm/uv/bios.h +3 -2
@@ -79,7 +79,7 @@ struct uv_gam_range_entry {u16 nasid;/* HNasid */ u16 sockid;/* Socket ID, high bits of APIC ID */ u16 pnode;/* Index to MMR and GRU spaces */ -u32 pxm;/* ACPI proximity domain number */ +u32 unused2;u32 limit;/* PA bits 56:26 (UV_GAM_RANGE_SHFT) */ };
@@ -88,7 +88,8 @@ struct uv_gam_range_entry {#define UV_SYSTAB_VERSION_UV4 0x400/* UV4 BIOS base version */ #define UV_SYSTAB_VERSION_UV4_1 0x401/* + gpa_shift */ #define UV_SYSTAB_VERSION_UV4_2 0x402/* + TYPE_NVRAM/WINDOW/MBOX */ -#define UV_SYSTAB_VERSION_UV4_LATEST UV_SYSTAB_VERSION_UV4_2 +#define UV_SYSTAB_VERSION_UV4_3 0x403/* - GAM Range PXM Value */ +#define UV_SYSTAB_VERSION_UV4_LATEST UV_SYSTAB_VERSION_UV4_3#define UV_SYSTAB_TYPE_UNUSED 0/* End of table (offset == 0) */ #define UV_SYSTAB_TYPE_GAM_PARAMS 1/* GAM PARAM conversions */
arch/x86/kernel/apic/x2apic_cluster.c +9 -4
@@ -155,7 +155,7 @@ static void init_x2apic_ldr(void)/* * At CPU state changes, update the x2apic cluster sibling info. */ -int x2apic_prepare_cpu (unsigned int cpu) +static int x2apic_prepare_cpu (unsigned int cpu) {if (!zalloc_cpumask_var (&per_cpu (cpus_in_cluster, cpu),GFP_KERNEL ))return -ENOMEM ;
@@ -168,7 +168,7 @@ int x2apic_prepare_cpu(unsigned int cpu)return 0 ; } -int x2apic_dead_cpu (unsigned int this_cpu) +static int x2apic_dead_cpu (unsigned int this_cpu) {int cpu;
@@ -186,13 +186,18 @@ int x2apic_dead_cpu(unsigned int this_cpu)static int x2apic_cluster_probe (void ) {int cpu =smp_processor_id (); +int ret;if (!x2apic_mode)return 0 ; + ret =cpuhp_setup_state (CPUHP_X2APIC_PREPARE ,"X2APIC_PREPARE" , + x2apic_prepare_cpu, x2apic_dead_cpu); +if (ret <0 ) { +pr_err ("Failed to register X2APIC_PREPARE\n" ); +return 0 ; + }cpumask_set_cpu (cpu,per_cpu (cpus_in_cluster, cpu)); -cpuhp_setup_state (CPUHP_X2APIC_PREPARE ,"X2APIC_PREPARE" , - x2apic_prepare_cpu, x2apic_dead_cpu);return 1 ; }
arch/x86/kernel/apic/x2apic_uv_x.c +20 -22
111 lines not on this page · raw message
arch/x86/kernel/fpu/xstate.c +17 -121
165 lines not on this page · raw message
arch/x86/kernel/head32.c +0 -2
@@ -25,8 +25,6 @@ static void __init i386_default_early_setup(void)/* Initialize 32bit specific setup functions */ x86_init.resources.reserve_resources = i386_reserve_resources; x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc; - -reserve_bios_regions (); } asmlinkage __visible void __init i386_start_kernel(void)
arch/x86/kernel/head64.c +0 -1
@@ -183,7 +183,6 @@ void __init x86_64_start_reservations(char *real_mode_data)copy_bootdata (__va (real_mode_data));x86_early_init_platform_quirks (); -reserve_bios_regions ();switch (boot_params.hdr.hardware_subarch) {case X86_SUBARCH_INTEL_MID :
arch/x86/kernel/irq.c +1 -2
@@ -102,8 +102,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)seq_puts (p," Rescheduling interrupts\n" );seq_printf (p,"%*s: " , prec,"CAL" );for_each_online_cpu (j) -seq_printf (p,"%10u " ,irq_stats (j)->irq_call_count - -irq_stats (j)->irq_tlb_count); +seq_printf (p,"%10u " ,irq_stats (j)->irq_call_count);seq_puts (p," Function call interrupts\n" );seq_printf (p,"%*s: " , prec,"TLB" );for_each_online_cpu (j)
arch/x86/kernel/setup.c +17 -10
@@ -936,8 +936,6 @@ void __init setup_arch(char **cmdline_p) x86_init.oem.arch_setup (); -kernel_randomize_memory (); - iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) -1 ;setup_memory_map ();parse_setup_data ();
@@ -1055,6 +1053,12 @@ void __init setup_arch(char **cmdline_p) max_possible_pfn = max_pfn; +/* +* Define random base addresses for memory sections after max_pfn is +* defined and before each memory section base is used. +*/ +kernel_randomize_memory (); +#ifdef CONFIG_X86_32 /* max_low_pfn get updated here */ find_low_pfn_range ();
@@ -1097,6 +1101,8 @@ void __init setup_arch(char **cmdline_p)efi_find_mirror (); } +reserve_bios_regions (); +/* * The EFI specification says that boot service code won't be called * after ExitBootServices(). This is, in fact, a lie.
@@ -1125,7 +1131,15 @@ void __init setup_arch(char **cmdline_p)early_trap_pf_init (); -setup_real_mode (); +/* +* Update mmu_cr4_features (and, indirectly, trampoline_cr4_features) +* with the current CR4 value. This may not be necessary, but +* auditing all the early-boot CR4 manipulation would be needed to +* rule it out. +*/ +if (boot_cpu_data.cpuid_level >=0 ) +/* A CPU has %cr4 if and only if it has CPUID. */ + mmu_cr4_features =__read_cr4 ();memblock_set_current_limit (get_max_mapped ());
@@ -1174,13 +1188,6 @@ void __init setup_arch(char **cmdline_p)kasan_init (); -if (boot_cpu_data.cpuid_level >=0 ) { -/* A CPU has %cr4 if and only if it has CPUID */ - mmu_cr4_features =__read_cr4 (); -if (trampoline_cr4_features) - *trampoline_cr4_features = mmu_cr4_features; - } -#ifdef CONFIG_X86_32 /* sync back kernel address range */ clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
arch/x86/lib/kaslr.c +1 -1
@@ -19,7 +19,7 @@#include <asm/cpufeature.h> #include <asm/setup.h> -#define debug_putstr (v) early_printk(v) +#define debug_putstr (v) early_printk("%s", v)#define has_cpuflag (f) boot_cpu_has(f)#define get_boot_seed () kaslr_offset()#endif
arch/x86/mm/init.c +12 -2
@@ -122,8 +122,18 @@ __ref void *alloc_low_pages(unsigned int num)return __va (pfn <<PAGE_SHIFT ); } -/* need 3 4k for initial PMD_SIZE, 3 4k for 0-ISA_END_ADDRESS */ -#define INIT_PGT_BUF_SIZE (6 * PAGE_SIZE) +/* +* By default need 3 4k for initial PMD_SIZE, 3 4k for 0-ISA_END_ADDRESS. +* With KASLR memory randomization, depending on the machine e820 memory +* and the PUD alignment. We may need twice more pages when KASLR memory +* randomization is enabled. +*/ +#ifndef CONFIG_RANDOMIZE_MEMORY +#define INIT_PGD_PAGE_COUNT 6 +#else +#define INIT_PGD_PAGE_COUNT 12 +#endif +#define INIT_PGT_BUF_SIZE (INIT_PGD_PAGE_COUNT * PAGE_SIZE)RESERVE_BRK (early_pgt_alloc,INIT_PGT_BUF_SIZE );void __init early_alloc_pgt_buf (void ) {
arch/x86/mm/kaslr.c +1 -1
@@ -97,7 +97,7 @@ void __init kernel_randomize_memory(void)* add padding if needed (especially for memory hotplug support). */ BUG_ON (kaslr_regions[0 ].base != &page_offset_base); - memory_tb = ((max_pfn <<PAGE_SHIFT ) >>TB_SHIFT ) + + memory_tb =DIV_ROUND_UP (max_pfn <<PAGE_SHIFT ,1UL <<TB_SHIFT ) +CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING ;/* Adapt phyiscal memory region size based on available memory */
arch/x86/platform/efi/quirks.c +21 -0
@@ -254,6 +254,7 @@ void __init efi_free_boot_services(void)for_each_efi_memory_desc (md) {unsigned long long start = md->phys_addr;unsigned long long size = md->num_pages <<EFI_PAGE_SHIFT ; +size_t rm_size;if (md->type !=EFI_BOOT_SERVICES_CODE && md->type !=EFI_BOOT_SERVICES_DATA )
@@ -263,6 +264,26 @@ void __init efi_free_boot_services(void)if (md->attribute &EFI_MEMORY_RUNTIME )continue ; +/* +* Nasty quirk: if all sub-1MB memory is used for boot +* services, we can get here without having allocated the +* real mode trampoline. It's too late to hand boot services +* memory back to the memblock allocator, so instead +* try to manually allocate the trampoline if needed. +* +* I've seen this on a Dell XPS 13 9350 with firmware +* 1.4.4 with SGX enabled booting Linux via Fedora 24's +* grub2-efi on a hard disk. (And no, I don't know why +* this happened, but Linux should still try to boot rather +* panicing early.) +*/ + rm_size =real_mode_size_needed (); +if (rm_size && (start + rm_size) < (1 <<20 ) && size >= rm_size) { +set_real_mode_mem (start, rm_size); + start += rm_size; + size -= rm_size; + } +free_bootmem_late (start, size); }
arch/x86/platform/uv/bios_uv.c +5 -3
@@ -199,12 +199,14 @@ void uv_bios_init(void)return ; } +/* Starting with UV4 the UV systab size is variable */ if (uv_systab->revision >=UV_SYSTAB_VERSION_UV4 ) { +int size = uv_systab->size; +iounmap (uv_systab); - uv_systab =ioremap (efi.uv_systab, uv_systab->size); + uv_systab =ioremap (efi.uv_systab, size);if (!uv_systab) { -pr_err ("UV: UVsystab: ioremap(%d) failed!\n" , - uv_systab->size); +pr_err ("UV: UVsystab: ioremap(%d) failed!\n" , size);return ; } }
arch/x86/realmode/init.c +35 -12
90 lines not on this page · raw message