Skip to content

Commit 6ac3bb1

Browse files
committed
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar: "There's a number of fixes: - a round of fixes for CPUID-less legacy CPUs - a number of microcode loader fixes - i8042 detection robustization fixes - stack dump/unwinder fixes - x86 SoC platform driver fixes - a GCC 7 warning fix - virtualization related fixes" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits) Revert "x86/unwind: Detect bad stack return address" x86/paravirt: Mark unused patch_default label x86/microcode/AMD: Reload proper initrd start address x86/platform/intel/quark: Add printf attribute to imr_self_test_result() x86/platform/intel-mid: Switch MPU3050 driver to IIO x86/alternatives: Do not use sync_core() to serialize I$ x86/topology: Document cpu_llc_id x86/hyperv: Handle unknown NMIs on one CPU when unknown_nmi_panic x86/asm: Rewrite sync_core() to use IRET-to-self x86/microcode/intel: Replace sync_core() with native_cpuid() Revert "x86/boot: Fail the boot if !M486 and CPUID is missing" x86/asm/32: Make sync_core() handle missing CPUID on all 32-bit kernels x86/cpu: Probe CPUID leaf 6 even when cpuid_level == 6 x86/tools: Fix gcc-7 warning in relocs.c x86/unwind: Dump stack data on warnings x86/unwind: Adjust last frame check for aligned function stacks x86/init: Fix a couple of comment typos x86/init: Remove i8042_detect() from platform ops Input: i8042 - Trust firmware a bit more when probing on X86 x86/init: Add i8042 state to the platform data ...
2 parents eb3e8d9 + c280f77 commit 6ac3bb1

File tree

23 files changed

+279
-117
lines changed

23 files changed

+279
-117
lines changed

Documentation/x86/topology.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ The topology of a system is described in the units of:
6363
The maximum possible number of packages in the system. Helpful for per
6464
package facilities to preallocate per package information.
6565

66+
- cpu_llc_id:
67+
68+
A per-CPU variable containing:
69+
- On Intel, the first APIC ID of the list of CPUs sharing the Last Level
70+
Cache
71+
72+
- On AMD, the Node ID or Core Complex ID containing the Last Level
73+
Cache. In general, it is a number identifying an LLC uniquely on the
74+
system.
6675

6776
* Cores:
6877

arch/x86/boot/cpu.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,6 @@ int validate_cpu(void)
8787
return -1;
8888
}
8989

90-
if (CONFIG_X86_MINIMUM_CPU_FAMILY <= 4 && !IS_ENABLED(CONFIG_M486) &&
91-
!has_eflag(X86_EFLAGS_ID)) {
92-
printf("This kernel requires a CPU with the CPUID instruction. Build with CONFIG_M486=y to run on this CPU.\n");
93-
return -1;
94-
}
95-
9690
if (err_flags) {
9791
puts("This kernel requires the following features "
9892
"not present on the CPU:\n");

arch/x86/include/asm/processor.h

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -602,33 +602,69 @@ static __always_inline void cpu_relax(void)
602602
rep_nop();
603603
}
604604

605-
/* Stop speculative execution and prefetching of modified code. */
605+
/*
606+
* This function forces the icache and prefetched instruction stream to
607+
* catch up with reality in two very specific cases:
608+
*
609+
* a) Text was modified using one virtual address and is about to be executed
610+
* from the same physical page at a different virtual address.
611+
*
612+
* b) Text was modified on a different CPU, may subsequently be
613+
* executed on this CPU, and you want to make sure the new version
614+
* gets executed. This generally means you're calling this in a IPI.
615+
*
616+
* If you're calling this for a different reason, you're probably doing
617+
* it wrong.
618+
*/
606619
static inline void sync_core(void)
607620
{
608-
int tmp;
609-
610-
#ifdef CONFIG_M486
611621
/*
612-
* Do a CPUID if available, otherwise do a jump. The jump
613-
* can conveniently enough be the jump around CPUID.
622+
* There are quite a few ways to do this. IRET-to-self is nice
623+
* because it works on every CPU, at any CPL (so it's compatible
624+
* with paravirtualization), and it never exits to a hypervisor.
625+
* The only down sides are that it's a bit slow (it seems to be
626+
* a bit more than 2x slower than the fastest options) and that
627+
* it unmasks NMIs. The "push %cs" is needed because, in
628+
* paravirtual environments, __KERNEL_CS may not be a valid CS
629+
* value when we do IRET directly.
630+
*
631+
* In case NMI unmasking or performance ever becomes a problem,
632+
* the next best option appears to be MOV-to-CR2 and an
633+
* unconditional jump. That sequence also works on all CPUs,
634+
* but it will fault at CPL3 (i.e. Xen PV and lguest).
635+
*
636+
* CPUID is the conventional way, but it's nasty: it doesn't
637+
* exist on some 486-like CPUs, and it usually exits to a
638+
* hypervisor.
639+
*
640+
* Like all of Linux's memory ordering operations, this is a
641+
* compiler barrier as well.
614642
*/
615-
asm volatile("cmpl %2,%1\n\t"
616-
"jl 1f\n\t"
617-
"cpuid\n"
618-
"1:"
619-
: "=a" (tmp)
620-
: "rm" (boot_cpu_data.cpuid_level), "ri" (0), "0" (1)
621-
: "ebx", "ecx", "edx", "memory");
643+
register void *__sp asm(_ASM_SP);
644+
645+
#ifdef CONFIG_X86_32
646+
asm volatile (
647+
"pushfl\n\t"
648+
"pushl %%cs\n\t"
649+
"pushl $1f\n\t"
650+
"iret\n\t"
651+
"1:"
652+
: "+r" (__sp) : : "memory");
622653
#else
623-
/*
624-
* CPUID is a barrier to speculative execution.
625-
* Prefetched instructions are automatically
626-
* invalidated when modified.
627-
*/
628-
asm volatile("cpuid"
629-
: "=a" (tmp)
630-
: "0" (1)
631-
: "ebx", "ecx", "edx", "memory");
654+
unsigned int tmp;
655+
656+
asm volatile (
657+
"mov %%ss, %0\n\t"
658+
"pushq %q0\n\t"
659+
"pushq %%rsp\n\t"
660+
"addq $8, (%%rsp)\n\t"
661+
"pushfq\n\t"
662+
"mov %%cs, %0\n\t"
663+
"pushq %q0\n\t"
664+
"pushq $1f\n\t"
665+
"iretq\n\t"
666+
"1:"
667+
: "=&r" (tmp), "+r" (__sp) : : "cc", "memory");
632668
#endif
633669
}
634670

arch/x86/include/asm/unwind.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct unwind_state {
1212
struct task_struct *task;
1313
int graph_idx;
1414
#ifdef CONFIG_FRAME_POINTER
15-
unsigned long *bp;
15+
unsigned long *bp, *orig_sp;
1616
struct pt_regs *regs;
1717
#else
1818
unsigned long *sp;

arch/x86/include/asm/x86_init.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct x86_init_irqs {
5959

6060
/**
6161
* struct x86_init_oem - oem platform specific customizing functions
62-
* @arch_setup: platform specific architecure setup
62+
* @arch_setup: platform specific architecture setup
6363
* @banner: print a platform specific banner
6464
*/
6565
struct x86_init_oem {
@@ -164,9 +164,26 @@ struct x86_legacy_devices {
164164
int pnpbios;
165165
};
166166

167+
/**
168+
* enum x86_legacy_i8042_state - i8042 keyboard controller state
169+
* @X86_LEGACY_I8042_PLATFORM_ABSENT: the controller is always absent on
170+
* given platform/subarch.
171+
* @X86_LEGACY_I8042_FIRMWARE_ABSENT: firmware reports that the controller
172+
* is absent.
173+
* @X86_LEGACY_i8042_EXPECTED_PRESENT: the controller is likely to be
174+
* present, the i8042 driver should probe for controller existence.
175+
*/
176+
enum x86_legacy_i8042_state {
177+
X86_LEGACY_I8042_PLATFORM_ABSENT,
178+
X86_LEGACY_I8042_FIRMWARE_ABSENT,
179+
X86_LEGACY_I8042_EXPECTED_PRESENT,
180+
};
181+
167182
/**
168183
* struct x86_legacy_features - legacy x86 features
169184
*
185+
* @i8042: indicated if we expect the device to have i8042 controller
186+
* present.
170187
* @rtc: this device has a CMOS real-time clock present
171188
* @reserve_bios_regions: boot code will search for the EBDA address and the
172189
* start of the 640k - 1M BIOS region. If false, the platform must
@@ -175,6 +192,7 @@ struct x86_legacy_devices {
175192
* documentation for further details.
176193
*/
177194
struct x86_legacy_features {
195+
enum x86_legacy_i8042_state i8042;
178196
int rtc;
179197
int reserve_bios_regions;
180198
struct x86_legacy_devices devices;
@@ -188,15 +206,14 @@ struct x86_legacy_features {
188206
* @set_wallclock: set time back to HW clock
189207
* @is_untracked_pat_range exclude from PAT logic
190208
* @nmi_init enable NMI on cpus
191-
* @i8042_detect pre-detect if i8042 controller exists
192209
* @save_sched_clock_state: save state for sched_clock() on suspend
193210
* @restore_sched_clock_state: restore state for sched_clock() on resume
194-
* @apic_post_init: adjust apic if neeeded
211+
* @apic_post_init: adjust apic if needed
195212
* @legacy: legacy features
196213
* @set_legacy_features: override legacy features. Use of this callback
197214
* is highly discouraged. You should only need
198215
* this if your hardware platform requires further
199-
* custom fine tuning far beyong what may be
216+
* custom fine tuning far beyond what may be
200217
* possible in x86_early_init_platform_quirks() by
201218
* only using the current x86_hardware_subarch
202219
* semantics.
@@ -210,7 +227,6 @@ struct x86_platform_ops {
210227
bool (*is_untracked_pat_range)(u64 start, u64 end);
211228
void (*nmi_init)(void);
212229
unsigned char (*get_nmi_reason)(void);
213-
int (*i8042_detect)(void);
214230
void (*save_sched_clock_state)(void);
215231
void (*restore_sched_clock_state)(void);
216232
void (*apic_post_init)(void);

arch/x86/kernel/acpi/boot.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,13 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
930930
x86_platform.legacy.devices.pnpbios = 0;
931931
}
932932

933+
if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
934+
!(acpi_gbl_FADT.boot_flags & ACPI_FADT_8042) &&
935+
x86_platform.legacy.i8042 != X86_LEGACY_I8042_PLATFORM_ABSENT) {
936+
pr_debug("ACPI: i8042 controller is absent\n");
937+
x86_platform.legacy.i8042 = X86_LEGACY_I8042_FIRMWARE_ABSENT;
938+
}
939+
933940
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC) {
934941
pr_debug("ACPI: not registering RTC platform device\n");
935942
x86_platform.legacy.rtc = 0;

arch/x86/kernel/alternative.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,11 @@ recompute_jump(struct alt_instr *a, u8 *orig_insn, u8 *repl_insn, u8 *insnbuf)
337337
n_dspl, (unsigned long)orig_insn + n_dspl + repl_len);
338338
}
339339

340-
static void __init_or_module optimize_nops(struct alt_instr *a, u8 *instr)
340+
/*
341+
* "noinline" to cause control flow change and thus invalidate I$ and
342+
* cause refetch after modification.
343+
*/
344+
static void __init_or_module noinline optimize_nops(struct alt_instr *a, u8 *instr)
341345
{
342346
unsigned long flags;
343347

@@ -346,7 +350,6 @@ static void __init_or_module optimize_nops(struct alt_instr *a, u8 *instr)
346350

347351
local_irq_save(flags);
348352
add_nops(instr + (a->instrlen - a->padlen), a->padlen);
349-
sync_core();
350353
local_irq_restore(flags);
351354

352355
DUMP_BYTES(instr, a->instrlen, "%p: [%d:%d) optimized NOPs: ",
@@ -359,9 +362,12 @@ static void __init_or_module optimize_nops(struct alt_instr *a, u8 *instr)
359362
* This implies that asymmetric systems where APs have less capabilities than
360363
* the boot processor are not handled. Tough. Make sure you disable such
361364
* features by hand.
365+
*
366+
* Marked "noinline" to cause control flow change and thus insn cache
367+
* to refetch changed I$ lines.
362368
*/
363-
void __init_or_module apply_alternatives(struct alt_instr *start,
364-
struct alt_instr *end)
369+
void __init_or_module noinline apply_alternatives(struct alt_instr *start,
370+
struct alt_instr *end)
365371
{
366372
struct alt_instr *a;
367373
u8 *instr, *replacement;
@@ -667,7 +673,6 @@ void *__init_or_module text_poke_early(void *addr, const void *opcode,
667673
unsigned long flags;
668674
local_irq_save(flags);
669675
memcpy(addr, opcode, len);
670-
sync_core();
671676
local_irq_restore(flags);
672677
/* Could also do a CLFLUSH here to speed up CPU recovery; but
673678
that causes hangs on some VIA CPUs. */

arch/x86/kernel/cpu/common.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -667,13 +667,14 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
667667
c->x86_capability[CPUID_1_EDX] = edx;
668668
}
669669

670+
/* Thermal and Power Management Leaf: level 0x00000006 (eax) */
671+
if (c->cpuid_level >= 0x00000006)
672+
c->x86_capability[CPUID_6_EAX] = cpuid_eax(0x00000006);
673+
670674
/* Additional Intel-defined flags: level 0x00000007 */
671675
if (c->cpuid_level >= 0x00000007) {
672676
cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx);
673-
674677
c->x86_capability[CPUID_7_0_EBX] = ebx;
675-
676-
c->x86_capability[CPUID_6_EAX] = cpuid_eax(0x00000006);
677678
c->x86_capability[CPUID_7_ECX] = ecx;
678679
}
679680

0 commit comments

Comments
 (0)