Commit 7cfc4317 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar:
 "Misc fixes:
   - two fixes to make (very) old Intel CPUs boot reliably
   - fix the intel-mid driver and rename it
   - two KASAN false positive fixes
   - an FPU fix
   - two sysfb fixes
   - two build fixes related to new toolchain versions"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/platform/intel-mid: Rename platform_wdt to platform_mrfld_wdt
  x86/build: Build compressed x86 kernels as PIE when !CONFIG_RELOCATABLE as well
  x86/platform/intel-mid: Register watchdog device after SCU
  x86/fpu: Fix invalid FPU ptrace state after execve()
  x86/boot: Fail the boot if !M486 and CPUID is missing
  x86/traps: Ignore high word of regs->cs in early_fixup_exception()
  x86/dumpstack: Prevent KASAN false positive warnings
  x86/unwind: Prevent KASAN false positive warnings in guess unwinder
  x86/boot: Avoid warning for zero-filling .bss
  x86/sysfb: Fix lfb_size calculation
  x86/sysfb: Add support for 64bit EFI lfb_base
parents 3b404a51 e5dce286
...@@ -40,8 +40,8 @@ GCOV_PROFILE := n ...@@ -40,8 +40,8 @@ GCOV_PROFILE := n
UBSAN_SANITIZE :=n UBSAN_SANITIZE :=n
LDFLAGS := -m elf_$(UTS_MACHINE) LDFLAGS := -m elf_$(UTS_MACHINE)
ifeq ($(CONFIG_RELOCATABLE),y) # Compressed kernel should be built as PIE since it may be loaded at any
# If kernel is relocatable, build compressed kernel as PIE. # address by the bootloader.
ifeq ($(CONFIG_X86_32),y) ifeq ($(CONFIG_X86_32),y)
LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker) LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker)
else else
...@@ -51,7 +51,6 @@ else ...@@ -51,7 +51,6 @@ else
LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \ LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \
&& echo "-z noreloc-overflow -pie --no-dynamic-linker") && echo "-z noreloc-overflow -pie --no-dynamic-linker")
endif endif
endif
LDFLAGS_vmlinux := -T LDFLAGS_vmlinux := -T
hostprogs-y := mkpiggy hostprogs-y := mkpiggy
......
...@@ -87,6 +87,12 @@ int validate_cpu(void) ...@@ -87,6 +87,12 @@ int validate_cpu(void)
return -1; return -1;
} }
if (CONFIG_X86_MINIMUM_CPU_FAMILY <= 4 && !IS_ENABLED(CONFIG_M486) &&
!has_eflag(X86_EFLAGS_ID)) {
printf("This kernel requires a CPU with the CPUID instruction. Build with CONFIG_M486=y to run on this CPU.\n");
return -1;
}
if (err_flags) { if (err_flags) {
puts("This kernel requires the following features " puts("This kernel requires the following features "
"not present on the CPU:\n"); "not present on the CPU:\n");
......
...@@ -112,7 +112,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ...@@ -112,7 +112,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
for (; stack < stack_info.end; stack++) { for (; stack < stack_info.end; stack++) {
unsigned long real_addr; unsigned long real_addr;
int reliable = 0; int reliable = 0;
unsigned long addr = *stack; unsigned long addr = READ_ONCE_NOCHECK(*stack);
unsigned long *ret_addr_p = unsigned long *ret_addr_p =
unwind_get_return_address_ptr(&state); unwind_get_return_address_ptr(&state);
......
...@@ -521,14 +521,14 @@ void fpu__clear(struct fpu *fpu) ...@@ -521,14 +521,14 @@ void fpu__clear(struct fpu *fpu)
{ {
WARN_ON_FPU(fpu != &current->thread.fpu); /* Almost certainly an anomaly */ WARN_ON_FPU(fpu != &current->thread.fpu); /* Almost certainly an anomaly */
if (!use_eager_fpu() || !static_cpu_has(X86_FEATURE_FPU)) { fpu__drop(fpu);
/* FPU state will be reallocated lazily at the first use. */
fpu__drop(fpu); /*
} else { * Make sure fpstate is cleared and initialized.
if (!fpu->fpstate_active) { */
fpu__activate_curr(fpu); if (static_cpu_has(X86_FEATURE_FPU)) {
user_fpu_begin(); fpu__activate_curr(fpu);
} user_fpu_begin();
copy_init_fpstate_to_fpregs(); copy_init_fpstate_to_fpregs();
} }
} }
......
...@@ -665,14 +665,17 @@ __PAGE_ALIGNED_BSS ...@@ -665,14 +665,17 @@ __PAGE_ALIGNED_BSS
initial_pg_pmd: initial_pg_pmd:
.fill 1024*KPMDS,4,0 .fill 1024*KPMDS,4,0
#else #else
ENTRY(initial_page_table) .globl initial_page_table
initial_page_table:
.fill 1024,4,0 .fill 1024,4,0
#endif #endif
initial_pg_fixmap: initial_pg_fixmap:
.fill 1024,4,0 .fill 1024,4,0
ENTRY(empty_zero_page) .globl empty_zero_page
empty_zero_page:
.fill 4096,1,0 .fill 4096,1,0
ENTRY(swapper_pg_dir) .globl swapper_pg_dir
swapper_pg_dir:
.fill 1024,4,0 .fill 1024,4,0
EXPORT_SYMBOL(empty_zero_page) EXPORT_SYMBOL(empty_zero_page)
......
...@@ -66,13 +66,36 @@ __init int create_simplefb(const struct screen_info *si, ...@@ -66,13 +66,36 @@ __init int create_simplefb(const struct screen_info *si,
{ {
struct platform_device *pd; struct platform_device *pd;
struct resource res; struct resource res;
unsigned long len; u64 base, size;
u32 length;
/* don't use lfb_size as it may contain the whole VMEM instead of only /*
* the part that is occupied by the framebuffer */ * If the 64BIT_BASE capability is set, ext_lfb_base will contain the
len = mode->height * mode->stride; * upper half of the base address. Assemble the address, then make sure
len = PAGE_ALIGN(len); * it is valid and we can actually access it.
if (len > (u64)si->lfb_size << 16) { */
base = si->lfb_base;
if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE)
base |= (u64)si->ext_lfb_base << 32;
if (!base || (u64)(resource_size_t)base != base) {
printk(KERN_DEBUG "sysfb: inaccessible VRAM base\n");
return -EINVAL;
}
/*
* Don't use lfb_size as IORESOURCE size, since it may contain the
* entire VMEM, and thus require huge mappings. Use just the part we
* need, that is, the part where the framebuffer is located. But verify
* that it does not exceed the advertised VMEM.
* Note that in case of VBE, the lfb_size is shifted by 16 bits for
* historical reasons.
*/
size = si->lfb_size;
if (si->orig_video_isVGA == VIDEO_TYPE_VLFB)
size <<= 16;
length = mode->height * mode->stride;
length = PAGE_ALIGN(length);
if (length > size) {
printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n");
return -EINVAL; return -EINVAL;
} }
...@@ -81,8 +104,8 @@ __init int create_simplefb(const struct screen_info *si, ...@@ -81,8 +104,8 @@ __init int create_simplefb(const struct screen_info *si,
memset(&res, 0, sizeof(res)); memset(&res, 0, sizeof(res));
res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
res.name = simplefb_resname; res.name = simplefb_resname;
res.start = si->lfb_base; res.start = base;
res.end = si->lfb_base + len - 1; res.end = res.start + length - 1;
if (res.end <= res.start) if (res.end <= res.start)
return -EINVAL; return -EINVAL;
......
...@@ -7,11 +7,13 @@ ...@@ -7,11 +7,13 @@
unsigned long unwind_get_return_address(struct unwind_state *state) unsigned long unwind_get_return_address(struct unwind_state *state)
{ {
unsigned long addr = READ_ONCE_NOCHECK(*state->sp);
if (unwind_done(state)) if (unwind_done(state))
return 0; return 0;
return ftrace_graph_ret_addr(state->task, &state->graph_idx, return ftrace_graph_ret_addr(state->task, &state->graph_idx,
*state->sp, state->sp); addr, state->sp);
} }
EXPORT_SYMBOL_GPL(unwind_get_return_address); EXPORT_SYMBOL_GPL(unwind_get_return_address);
...@@ -23,8 +25,10 @@ bool unwind_next_frame(struct unwind_state *state) ...@@ -23,8 +25,10 @@ bool unwind_next_frame(struct unwind_state *state)
return false; return false;
do { do {
unsigned long addr = READ_ONCE_NOCHECK(*state->sp);
for (state->sp++; state->sp < info->end; state->sp++) for (state->sp++; state->sp < info->end; state->sp++)
if (__kernel_text_address(*state->sp)) if (__kernel_text_address(addr))
return true; return true;
state->sp = info->next_sp; state->sp = info->next_sp;
......
...@@ -135,7 +135,12 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr) ...@@ -135,7 +135,12 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
if (early_recursion_flag > 2) if (early_recursion_flag > 2)
goto halt_loop; goto halt_loop;
if (regs->cs != __KERNEL_CS) /*
* Old CPUs leave the high bits of CS on the stack
* undefined. I'm not sure which CPUs do this, but at least
* the 486 DX works this way.
*/
if ((regs->cs & 0xFFFF) != __KERNEL_CS)
goto fail; goto fail;
/* /*
......
...@@ -28,4 +28,4 @@ obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_pcal9555a.o ...@@ -28,4 +28,4 @@ obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_pcal9555a.o
obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o
# MISC Devices # MISC Devices
obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o
obj-$(subst m,y,$(CONFIG_INTEL_MID_WATCHDOG)) += platform_wdt.o obj-$(subst m,y,$(CONFIG_INTEL_MID_WATCHDOG)) += platform_mrfld_wdt.o
/* /*
* platform_wdt.c: Watchdog platform library file * Intel Merrifield watchdog platform device library file
* *
* (C) Copyright 2014 Intel Corporation * (C) Copyright 2014 Intel Corporation
* Author: David Cohen <david.a.cohen@linux.intel.com> * Author: David Cohen <david.a.cohen@linux.intel.com>
...@@ -14,7 +14,9 @@ ...@@ -14,7 +14,9 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/intel-mid_wdt.h> #include <linux/platform_data/intel-mid_wdt.h>
#include <asm/intel-mid.h> #include <asm/intel-mid.h>
#include <asm/intel_scu_ipc.h>
#include <asm/io_apic.h> #include <asm/io_apic.h>
#define TANGIER_EXT_TIMER0_MSI 15 #define TANGIER_EXT_TIMER0_MSI 15
...@@ -50,14 +52,34 @@ static struct intel_mid_wdt_pdata tangier_pdata = { ...@@ -50,14 +52,34 @@ static struct intel_mid_wdt_pdata tangier_pdata = {
.probe = tangier_probe, .probe = tangier_probe,
}; };
static int __init register_mid_wdt(void) static int wdt_scu_status_change(struct notifier_block *nb,
unsigned long code, void *data)
{ {
if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER) { if (code == SCU_DOWN) {
wdt_dev.dev.platform_data = &tangier_pdata; platform_device_unregister(&wdt_dev);
return platform_device_register(&wdt_dev); return 0;
} }
return -ENODEV; return platform_device_register(&wdt_dev);
} }
static struct notifier_block wdt_scu_notifier = {
.notifier_call = wdt_scu_status_change,
};
static int __init register_mid_wdt(void)
{
if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER)
return -ENODEV;
wdt_dev.dev.platform_data = &tangier_pdata;
/*
* We need to be sure that the SCU IPC is ready before watchdog device
* can be registered:
*/
intel_scu_notifier_add(&wdt_scu_notifier);
return 0;
}
rootfs_initcall(register_mid_wdt); rootfs_initcall(register_mid_wdt);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment