Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ac3bb16 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
  ...
parents eb3e8d9d c280f773
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -63,6 +63,15 @@ The topology of a system is described in the units of:
    The maximum possible number of packages in the system. Helpful for per
    The maximum possible number of packages in the system. Helpful for per
    package facilities to preallocate per package information.
    package facilities to preallocate per package information.


  - cpu_llc_id:

    A per-CPU variable containing:
    - On Intel, the first APIC ID of the list of CPUs sharing the Last Level
    Cache

    - On AMD, the Node ID or Core Complex ID containing the Last Level
    Cache. In general, it is a number identifying an LLC uniquely on the
    system.


* Cores:
* Cores:


+0 −6
Original line number Original line Diff line number Diff line
@@ -87,12 +87,6 @@ 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");
+58 −22
Original line number Original line Diff line number Diff line
@@ -602,33 +602,69 @@ static __always_inline void cpu_relax(void)
	rep_nop();
	rep_nop();
}
}


/* Stop speculative execution and prefetching of modified code. */
/*
 * This function forces the icache and prefetched instruction stream to
 * catch up with reality in two very specific cases:
 *
 *  a) Text was modified using one virtual address and is about to be executed
 *     from the same physical page at a different virtual address.
 *
 *  b) Text was modified on a different CPU, may subsequently be
 *     executed on this CPU, and you want to make sure the new version
 *     gets executed.  This generally means you're calling this in a IPI.
 *
 * If you're calling this for a different reason, you're probably doing
 * it wrong.
 */
static inline void sync_core(void)
static inline void sync_core(void)
{
{
	int tmp;

#ifdef CONFIG_M486
	/*
	/*
	 * Do a CPUID if available, otherwise do a jump.  The jump
	 * There are quite a few ways to do this.  IRET-to-self is nice
	 * can conveniently enough be the jump around CPUID.
	 * because it works on every CPU, at any CPL (so it's compatible
	 * with paravirtualization), and it never exits to a hypervisor.
	 * The only down sides are that it's a bit slow (it seems to be
	 * a bit more than 2x slower than the fastest options) and that
	 * it unmasks NMIs.  The "push %cs" is needed because, in
	 * paravirtual environments, __KERNEL_CS may not be a valid CS
	 * value when we do IRET directly.
	 *
	 * In case NMI unmasking or performance ever becomes a problem,
	 * the next best option appears to be MOV-to-CR2 and an
	 * unconditional jump.  That sequence also works on all CPUs,
	 * but it will fault at CPL3 (i.e. Xen PV and lguest).
	 *
	 * CPUID is the conventional way, but it's nasty: it doesn't
	 * exist on some 486-like CPUs, and it usually exits to a
	 * hypervisor.
	 *
	 * Like all of Linux's memory ordering operations, this is a
	 * compiler barrier as well.
	 */
	 */
	asm volatile("cmpl %2,%1\n\t"
	register void *__sp asm(_ASM_SP);
		     "jl 1f\n\t"

		     "cpuid\n"
#ifdef CONFIG_X86_32
	asm volatile (
		"pushfl\n\t"
		"pushl %%cs\n\t"
		"pushl $1f\n\t"
		"iret\n\t"
		"1:"
		"1:"
		     : "=a" (tmp)
		: "+r" (__sp) : : "memory");
		     : "rm" (boot_cpu_data.cpuid_level), "ri" (0), "0" (1)
		     : "ebx", "ecx", "edx", "memory");
#else
#else
	/*
	unsigned int tmp;
	 * CPUID is a barrier to speculative execution.

	 * Prefetched instructions are automatically
	asm volatile (
	 * invalidated when modified.
		"mov %%ss, %0\n\t"
	 */
		"pushq %q0\n\t"
	asm volatile("cpuid"
		"pushq %%rsp\n\t"
		     : "=a" (tmp)
		"addq $8, (%%rsp)\n\t"
		     : "0" (1)
		"pushfq\n\t"
		     : "ebx", "ecx", "edx", "memory");
		"mov %%cs, %0\n\t"
		"pushq %q0\n\t"
		"pushq $1f\n\t"
		"iretq\n\t"
		"1:"
		: "=&r" (tmp), "+r" (__sp) : : "cc", "memory");
#endif
#endif
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -12,7 +12,7 @@ struct unwind_state {
	struct task_struct *task;
	struct task_struct *task;
	int graph_idx;
	int graph_idx;
#ifdef CONFIG_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
	unsigned long *bp;
	unsigned long *bp, *orig_sp;
	struct pt_regs *regs;
	struct pt_regs *regs;
#else
#else
	unsigned long *sp;
	unsigned long *sp;
+21 −5
Original line number Original line Diff line number Diff line
@@ -59,7 +59,7 @@ struct x86_init_irqs {


/**
/**
 * struct x86_init_oem - oem platform specific customizing functions
 * struct x86_init_oem - oem platform specific customizing functions
 * @arch_setup:			platform specific architecure setup
 * @arch_setup:			platform specific architecture setup
 * @banner:			print a platform specific banner
 * @banner:			print a platform specific banner
 */
 */
struct x86_init_oem {
struct x86_init_oem {
@@ -164,9 +164,26 @@ struct x86_legacy_devices {
	int pnpbios;
	int pnpbios;
};
};


/**
 * enum x86_legacy_i8042_state - i8042 keyboard controller state
 * @X86_LEGACY_I8042_PLATFORM_ABSENT: the controller is always absent on
 *	given platform/subarch.
 * @X86_LEGACY_I8042_FIRMWARE_ABSENT: firmware reports that the controller
 *	is absent.
 * @X86_LEGACY_i8042_EXPECTED_PRESENT: the controller is likely to be
 *	present, the i8042 driver should probe for controller existence.
 */
enum x86_legacy_i8042_state {
	X86_LEGACY_I8042_PLATFORM_ABSENT,
	X86_LEGACY_I8042_FIRMWARE_ABSENT,
	X86_LEGACY_I8042_EXPECTED_PRESENT,
};

/**
/**
 * struct x86_legacy_features - legacy x86 features
 * struct x86_legacy_features - legacy x86 features
 *
 *
 * @i8042: indicated if we expect the device to have i8042 controller
 *	present.
 * @rtc: this device has a CMOS real-time clock present
 * @rtc: this device has a CMOS real-time clock present
 * @reserve_bios_regions: boot code will search for the EBDA address and the
 * @reserve_bios_regions: boot code will search for the EBDA address and the
 * 	start of the 640k - 1M BIOS region.  If false, the platform must
 * 	start of the 640k - 1M BIOS region.  If false, the platform must
@@ -175,6 +192,7 @@ struct x86_legacy_devices {
 * 	documentation for further details.
 * 	documentation for further details.
 */
 */
struct x86_legacy_features {
struct x86_legacy_features {
	enum x86_legacy_i8042_state i8042;
	int rtc;
	int rtc;
	int reserve_bios_regions;
	int reserve_bios_regions;
	struct x86_legacy_devices devices;
	struct x86_legacy_devices devices;
@@ -188,15 +206,14 @@ struct x86_legacy_features {
 * @set_wallclock:		set time back to HW clock
 * @set_wallclock:		set time back to HW clock
 * @is_untracked_pat_range	exclude from PAT logic
 * @is_untracked_pat_range	exclude from PAT logic
 * @nmi_init			enable NMI on cpus
 * @nmi_init			enable NMI on cpus
 * @i8042_detect		pre-detect if i8042 controller exists
 * @save_sched_clock_state:	save state for sched_clock() on suspend
 * @save_sched_clock_state:	save state for sched_clock() on suspend
 * @restore_sched_clock_state:	restore state for sched_clock() on resume
 * @restore_sched_clock_state:	restore state for sched_clock() on resume
 * @apic_post_init:		adjust apic if neeeded
 * @apic_post_init:		adjust apic if needed
 * @legacy:			legacy features
 * @legacy:			legacy features
 * @set_legacy_features:	override legacy features. Use of this callback
 * @set_legacy_features:	override legacy features. Use of this callback
 * 				is highly discouraged. You should only need
 * 				is highly discouraged. You should only need
 * 				this if your hardware platform requires further
 * 				this if your hardware platform requires further
 * 				custom fine tuning far beyong what may be
 * 				custom fine tuning far beyond what may be
 * 				possible in x86_early_init_platform_quirks() by
 * 				possible in x86_early_init_platform_quirks() by
 * 				only using the current x86_hardware_subarch
 * 				only using the current x86_hardware_subarch
 * 				semantics.
 * 				semantics.
@@ -210,7 +227,6 @@ struct x86_platform_ops {
	bool (*is_untracked_pat_range)(u64 start, u64 end);
	bool (*is_untracked_pat_range)(u64 start, u64 end);
	void (*nmi_init)(void);
	void (*nmi_init)(void);
	unsigned char (*get_nmi_reason)(void);
	unsigned char (*get_nmi_reason)(void);
	int (*i8042_detect)(void);
	void (*save_sched_clock_state)(void);
	void (*save_sched_clock_state)(void);
	void (*restore_sched_clock_state)(void);
	void (*restore_sched_clock_state)(void);
	void (*apic_post_init)(void);
	void (*apic_post_init)(void);
Loading