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
This commit is contained in:
commit
0386729247
|
@ -667,6 +667,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
|
|||
bool conout_found = false;
|
||||
void *dummy = NULL;
|
||||
u32 h = handles[i];
|
||||
u32 current_fb_base;
|
||||
|
||||
status = efi_call_early(handle_protocol, h,
|
||||
proto, (void **)&gop32);
|
||||
|
@ -678,7 +679,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
|
|||
if (status == EFI_SUCCESS)
|
||||
conout_found = true;
|
||||
|
||||
status = __gop_query32(gop32, &info, &size, &fb_base);
|
||||
status = __gop_query32(gop32, &info, &size, ¤t_fb_base);
|
||||
if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
|
||||
/*
|
||||
* Systems that use the UEFI Console Splitter may
|
||||
|
@ -692,6 +693,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
|
|||
pixel_format = info->pixel_format;
|
||||
pixel_info = info->pixel_information;
|
||||
pixels_per_scan_line = info->pixels_per_scan_line;
|
||||
fb_base = current_fb_base;
|
||||
|
||||
/*
|
||||
* Once we've found a GOP supporting ConOut,
|
||||
|
@ -770,6 +772,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
|
|||
bool conout_found = false;
|
||||
void *dummy = NULL;
|
||||
u64 h = handles[i];
|
||||
u32 current_fb_base;
|
||||
|
||||
status = efi_call_early(handle_protocol, h,
|
||||
proto, (void **)&gop64);
|
||||
|
@ -781,7 +784,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
|
|||
if (status == EFI_SUCCESS)
|
||||
conout_found = true;
|
||||
|
||||
status = __gop_query64(gop64, &info, &size, &fb_base);
|
||||
status = __gop_query64(gop64, &info, &size, ¤t_fb_base);
|
||||
if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
|
||||
/*
|
||||
* Systems that use the UEFI Console Splitter may
|
||||
|
@ -795,6 +798,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
|
|||
pixel_format = info->pixel_format;
|
||||
pixel_info = info->pixel_information;
|
||||
pixels_per_scan_line = info->pixels_per_scan_line;
|
||||
fb_base = current_fb_base;
|
||||
|
||||
/*
|
||||
* 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
|
|||
function. */
|
||||
|
||||
#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);
|
||||
|
||||
#ifndef CONFIG_KMEMCHECK
|
||||
#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
|
||||
extern void *memcpy(void *to, const void *from, size_t len);
|
||||
#else
|
||||
#if (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || __GNUC__ < 4
|
||||
#define memcpy(dst, src, len) \
|
||||
({ \
|
||||
size_t __len = (len); \
|
||||
|
|
|
@ -2907,6 +2907,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
|
|||
struct irq_data *irq_data;
|
||||
struct mp_chip_data *data;
|
||||
struct irq_alloc_info *info = arg;
|
||||
unsigned long flags;
|
||||
|
||||
if (!info || nr_irqs > 1)
|
||||
return -EINVAL;
|
||||
|
@ -2939,11 +2940,14 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
|
|||
|
||||
cfg = irqd_cfg(irq_data);
|
||||
add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin);
|
||||
|
||||
local_irq_save(flags);
|
||||
if (info->ioapic_entry)
|
||||
mp_setup_entry(cfg, data, info->ioapic_entry);
|
||||
mp_register_handler(virq, data->trigger);
|
||||
if (virq < nr_legacy_irqs())
|
||||
legacy_pic->mask(virq);
|
||||
local_irq_restore(flags);
|
||||
|
||||
apic_printk(APIC_VERBOSE, KERN_DEBUG
|
||||
"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)
|
|||
if (sp < bottom || sp > top)
|
||||
return 0;
|
||||
|
||||
fp = READ_ONCE(*(unsigned long *)sp);
|
||||
fp = READ_ONCE_NOCHECK(*(unsigned long *)sp);
|
||||
do {
|
||||
if (fp < bottom || fp > top)
|
||||
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))
|
||||
return ip;
|
||||
fp = READ_ONCE(*(unsigned long *)fp);
|
||||
fp = READ_ONCE_NOCHECK(*(unsigned long *)fp);
|
||||
} while (count++ < 16 && p->state != TASK_RUNNING);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1173,6 +1173,14 @@ void __init setup_arch(char **cmdline_p)
|
|||
clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
|
||||
swapper_pg_dir + KERNEL_PGD_BOUNDARY,
|
||||
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
|
||||
|
||||
tboot_probe();
|
||||
|
|
|
@ -509,7 +509,7 @@ void __inquire_remote_apic(int apicid)
|
|||
*/
|
||||
#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)
|
||||
{
|
||||
|
@ -522,13 +522,16 @@ early_param("cpu_init_udelay", cpu_init_udelay);
|
|||
static void __init smp_quirk_init_udelay(void)
|
||||
{
|
||||
/* if cmdline changed it from default, leave it alone */
|
||||
if (init_udelay != UDELAY_10MS_DEFAULT)
|
||||
if (init_udelay != INT_MAX)
|
||||
return;
|
||||
|
||||
/* if modern processor, use no delay */
|
||||
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)))
|
||||
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)
|
|||
/*
|
||||
* Give the other CPU some time to accept the IPI.
|
||||
*/
|
||||
if (init_udelay)
|
||||
if (init_udelay == 0)
|
||||
udelay(10);
|
||||
else
|
||||
udelay(300);
|
||||
|
||||
pr_debug("Startup point 1\n");
|
||||
|
@ -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.
|
||||
*/
|
||||
if (init_udelay)
|
||||
if (init_udelay == 0)
|
||||
udelay(10);
|
||||
else
|
||||
udelay(200);
|
||||
|
||||
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
|
||||
|
|
|
@ -237,12 +237,25 @@
|
|||
#define KASAN_ABI_VERSION 3
|
||||
#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 */
|
||||
|
||||
#if !defined(__noclone)
|
||||
#define __noclone /* not needed */
|
||||
#endif
|
||||
|
||||
#if !defined(__no_sanitize_address)
|
||||
#define __no_sanitize_address
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A trick to suppress uninitialized variable warning without generating any
|
||||
* code
|
||||
|
|
|
@ -198,20 +198,46 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
|
|||
|
||||
#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) {
|
||||
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();
|
||||
}
|
||||
__READ_ONCE_SIZE;
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
switch (size) {
|
||||
|
@ -248,8 +274,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
|
|||
* required ordering.
|
||||
*/
|
||||
|
||||
#define READ_ONCE(x) \
|
||||
({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
|
||||
#define __READ_ONCE(x, check) \
|
||||
({ \
|
||||
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) \
|
||||
({ \
|
||||
|
|
Loading…
Reference in a new issue