Commit 03867292 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 KASAN fixes, two EFI boot fixes, two boot-delay
  optimization fixes, and a fix for a IRQ handling hang observed on
  virtual platforms"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mm, kasan: Silence KASAN warnings in get_wchan()
  compiler, atomics, kasan: Provide READ_ONCE_NOCHECK()
  x86, kasan: Fix build failure on KASAN=y && KMEMCHECK=y kernels
  x86/smpboot: Fix CPU #1 boot timeout
  x86/smpboot: Fix cpu_init_udelay=10000 corner case boot parameter misbehavior
  x86/ioapic: Disable interrupts when re-routing legacy IRQs
  x86/setup: Extend low identity map to cover whole kernel range
  x86/efi: Fix multiple GOP device support
parents df557936 f7d27c35
...@@ -667,6 +667,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto, ...@@ -667,6 +667,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
bool conout_found = false; bool conout_found = false;
void *dummy = NULL; void *dummy = NULL;
u32 h = handles[i]; u32 h = handles[i];
u32 current_fb_base;
status = efi_call_early(handle_protocol, h, status = efi_call_early(handle_protocol, h,
proto, (void **)&gop32); proto, (void **)&gop32);
...@@ -678,7 +679,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto, ...@@ -678,7 +679,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
if (status == EFI_SUCCESS) if (status == EFI_SUCCESS)
conout_found = true; conout_found = true;
status = __gop_query32(gop32, &info, &size, &fb_base); status = __gop_query32(gop32, &info, &size, &current_fb_base);
if (status == EFI_SUCCESS && (!first_gop || conout_found)) { if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
/* /*
* Systems that use the UEFI Console Splitter may * Systems that use the UEFI Console Splitter may
...@@ -692,6 +693,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto, ...@@ -692,6 +693,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
pixel_format = info->pixel_format; pixel_format = info->pixel_format;
pixel_info = info->pixel_information; pixel_info = info->pixel_information;
pixels_per_scan_line = info->pixels_per_scan_line; pixels_per_scan_line = info->pixels_per_scan_line;
fb_base = current_fb_base;
/* /*
* Once we've found a GOP supporting ConOut, * Once we've found a GOP supporting ConOut,
...@@ -770,6 +772,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto, ...@@ -770,6 +772,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
bool conout_found = false; bool conout_found = false;
void *dummy = NULL; void *dummy = NULL;
u64 h = handles[i]; u64 h = handles[i];
u32 current_fb_base;
status = efi_call_early(handle_protocol, h, status = efi_call_early(handle_protocol, h,
proto, (void **)&gop64); proto, (void **)&gop64);
...@@ -781,7 +784,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto, ...@@ -781,7 +784,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
if (status == EFI_SUCCESS) if (status == EFI_SUCCESS)
conout_found = true; conout_found = true;
status = __gop_query64(gop64, &info, &size, &fb_base); status = __gop_query64(gop64, &info, &size, &current_fb_base);
if (status == EFI_SUCCESS && (!first_gop || conout_found)) { if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
/* /*
* Systems that use the UEFI Console Splitter may * Systems that use the UEFI Console Splitter may
...@@ -795,6 +798,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto, ...@@ -795,6 +798,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
pixel_format = info->pixel_format; pixel_format = info->pixel_format;
pixel_info = info->pixel_information; pixel_info = info->pixel_information;
pixels_per_scan_line = info->pixels_per_scan_line; pixels_per_scan_line = info->pixels_per_scan_line;
fb_base = current_fb_base;
/* /*
* Once we've found a GOP supporting ConOut, * Once we've found a GOP supporting ConOut,
......
...@@ -27,12 +27,11 @@ static __always_inline void *__inline_memcpy(void *to, const void *from, size_t ...@@ -27,12 +27,11 @@ static __always_inline void *__inline_memcpy(void *to, const void *from, size_t
function. */ function. */
#define __HAVE_ARCH_MEMCPY 1 #define __HAVE_ARCH_MEMCPY 1
extern void *memcpy(void *to, const void *from, size_t len);
extern void *__memcpy(void *to, const void *from, size_t len); extern void *__memcpy(void *to, const void *from, size_t len);
#ifndef CONFIG_KMEMCHECK #ifndef CONFIG_KMEMCHECK
#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 #if (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || __GNUC__ < 4
extern void *memcpy(void *to, const void *from, size_t len);
#else
#define memcpy(dst, src, len) \ #define memcpy(dst, src, len) \
({ \ ({ \
size_t __len = (len); \ size_t __len = (len); \
......
...@@ -2907,6 +2907,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, ...@@ -2907,6 +2907,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
struct irq_data *irq_data; struct irq_data *irq_data;
struct mp_chip_data *data; struct mp_chip_data *data;
struct irq_alloc_info *info = arg; struct irq_alloc_info *info = arg;
unsigned long flags;
if (!info || nr_irqs > 1) if (!info || nr_irqs > 1)
return -EINVAL; return -EINVAL;
...@@ -2939,11 +2940,14 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, ...@@ -2939,11 +2940,14 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
cfg = irqd_cfg(irq_data); cfg = irqd_cfg(irq_data);
add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin); add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin);
local_irq_save(flags);
if (info->ioapic_entry) if (info->ioapic_entry)
mp_setup_entry(cfg, data, info->ioapic_entry); mp_setup_entry(cfg, data, info->ioapic_entry);
mp_register_handler(virq, data->trigger); mp_register_handler(virq, data->trigger);
if (virq < nr_legacy_irqs()) if (virq < nr_legacy_irqs())
legacy_pic->mask(virq); legacy_pic->mask(virq);
local_irq_restore(flags);
apic_printk(APIC_VERBOSE, KERN_DEBUG apic_printk(APIC_VERBOSE, KERN_DEBUG
"IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i Dest:%d)\n", "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i Dest:%d)\n",
......
...@@ -550,14 +550,14 @@ unsigned long get_wchan(struct task_struct *p) ...@@ -550,14 +550,14 @@ unsigned long get_wchan(struct task_struct *p)
if (sp < bottom || sp > top) if (sp < bottom || sp > top)
return 0; return 0;
fp = READ_ONCE(*(unsigned long *)sp); fp = READ_ONCE_NOCHECK(*(unsigned long *)sp);
do { do {
if (fp < bottom || fp > top) if (fp < bottom || fp > top)
return 0; return 0;
ip = READ_ONCE(*(unsigned long *)(fp + sizeof(unsigned long))); ip = READ_ONCE_NOCHECK(*(unsigned long *)(fp + sizeof(unsigned long)));
if (!in_sched_functions(ip)) if (!in_sched_functions(ip))
return ip; return ip;
fp = READ_ONCE(*(unsigned long *)fp); fp = READ_ONCE_NOCHECK(*(unsigned long *)fp);
} while (count++ < 16 && p->state != TASK_RUNNING); } while (count++ < 16 && p->state != TASK_RUNNING);
return 0; return 0;
} }
...@@ -1173,6 +1173,14 @@ void __init setup_arch(char **cmdline_p) ...@@ -1173,6 +1173,14 @@ void __init setup_arch(char **cmdline_p)
clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY, clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
swapper_pg_dir + KERNEL_PGD_BOUNDARY, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
KERNEL_PGD_PTRS); KERNEL_PGD_PTRS);
/*
* sync back low identity map too. It is used for example
* in the 32-bit EFI stub.
*/
clone_pgd_range(initial_page_table,
swapper_pg_dir + KERNEL_PGD_BOUNDARY,
KERNEL_PGD_PTRS);
#endif #endif
tboot_probe(); tboot_probe();
......
...@@ -509,7 +509,7 @@ void __inquire_remote_apic(int apicid) ...@@ -509,7 +509,7 @@ void __inquire_remote_apic(int apicid)
*/ */
#define UDELAY_10MS_DEFAULT 10000 #define UDELAY_10MS_DEFAULT 10000
static unsigned int init_udelay = UDELAY_10MS_DEFAULT; static unsigned int init_udelay = INT_MAX;
static int __init cpu_init_udelay(char *str) static int __init cpu_init_udelay(char *str)
{ {
...@@ -522,13 +522,16 @@ early_param("cpu_init_udelay", cpu_init_udelay); ...@@ -522,13 +522,16 @@ early_param("cpu_init_udelay", cpu_init_udelay);
static void __init smp_quirk_init_udelay(void) static void __init smp_quirk_init_udelay(void)
{ {
/* if cmdline changed it from default, leave it alone */ /* if cmdline changed it from default, leave it alone */
if (init_udelay != UDELAY_10MS_DEFAULT) if (init_udelay != INT_MAX)
return; return;
/* if modern processor, use no delay */ /* if modern processor, use no delay */
if (((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 6)) || if (((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 6)) ||
((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0xF))) ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0xF)))
init_udelay = 0; init_udelay = 0;
/* else, use legacy delay */
init_udelay = UDELAY_10MS_DEFAULT;
} }
/* /*
...@@ -657,7 +660,9 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) ...@@ -657,7 +660,9 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
/* /*
* Give the other CPU some time to accept the IPI. * Give the other CPU some time to accept the IPI.
*/ */
if (init_udelay) if (init_udelay == 0)
udelay(10);
else
udelay(300); udelay(300);
pr_debug("Startup point 1\n"); pr_debug("Startup point 1\n");
...@@ -668,7 +673,9 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) ...@@ -668,7 +673,9 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
/* /*
* Give the other CPU some time to accept the IPI. * Give the other CPU some time to accept the IPI.
*/ */
if (init_udelay) if (init_udelay == 0)
udelay(10);
else
udelay(200); udelay(200);
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
......
...@@ -237,12 +237,25 @@ ...@@ -237,12 +237,25 @@
#define KASAN_ABI_VERSION 3 #define KASAN_ABI_VERSION 3
#endif #endif
#if GCC_VERSION >= 40902
/*
* Tell the compiler that address safety instrumentation (KASAN)
* should not be applied to that function.
* Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
*/
#define __no_sanitize_address __attribute__((no_sanitize_address))
#endif
#endif /* gcc version >= 40000 specific checks */ #endif /* gcc version >= 40000 specific checks */
#if !defined(__noclone) #if !defined(__noclone)
#define __noclone /* not needed */ #define __noclone /* not needed */
#endif #endif
#if !defined(__no_sanitize_address)
#define __no_sanitize_address
#endif
/* /*
* A trick to suppress uninitialized variable warning without generating any * A trick to suppress uninitialized variable warning without generating any
* code * code
......
...@@ -198,20 +198,46 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); ...@@ -198,20 +198,46 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
#include <uapi/linux/types.h> #include <uapi/linux/types.h>
static __always_inline void __read_once_size(const volatile void *p, void *res, int size) #define __READ_ONCE_SIZE \
({ \
switch (size) { \
case 1: *(__u8 *)res = *(volatile __u8 *)p; break; \
case 2: *(__u16 *)res = *(volatile __u16 *)p; break; \
case 4: *(__u32 *)res = *(volatile __u32 *)p; break; \
case 8: *(__u64 *)res = *(volatile __u64 *)p; break; \
default: \
barrier(); \
__builtin_memcpy((void *)res, (const void *)p, size); \
barrier(); \
} \
})
static __always_inline
void __read_once_size(const volatile void *p, void *res, int size)
{ {
switch (size) { __READ_ONCE_SIZE;
case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
default:
barrier();
__builtin_memcpy((void *)res, (const void *)p, size);
barrier();
}
} }
#ifdef CONFIG_KASAN
/*
* This function is not 'inline' because __no_sanitize_address confilcts
* with inlining. Attempt to inline it may cause a build failure.
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
* '__maybe_unused' allows us to avoid defined-but-not-used warnings.
*/
static __no_sanitize_address __maybe_unused
void __read_once_size_nocheck(const volatile void *p, void *res, int size)
{
__READ_ONCE_SIZE;
}
#else
static __always_inline
void __read_once_size_nocheck(const volatile void *p, void *res, int size)
{
__READ_ONCE_SIZE;
}
#endif
static __always_inline void __write_once_size(volatile void *p, void *res, int size) static __always_inline void __write_once_size(volatile void *p, void *res, int size)
{ {
switch (size) { switch (size) {
...@@ -248,8 +274,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s ...@@ -248,8 +274,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
* required ordering. * required ordering.
*/ */
#define READ_ONCE(x) \ #define __READ_ONCE(x, check) \
({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; }) ({ \
union { typeof(x) __val; char __c[1]; } __u; \
if (check) \
__read_once_size(&(x), __u.__c, sizeof(x)); \
else \
__read_once_size_nocheck(&(x), __u.__c, sizeof(x)); \
__u.__val; \
})
#define READ_ONCE(x) __READ_ONCE(x, 1)
/*
* Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need
* to hide memory access from KASAN.
*/
#define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0)
#define WRITE_ONCE(x, val) \ #define WRITE_ONCE(x, val) \
({ \ ({ \
......
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