Commit 2af9b20d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'x86-urgent-2023-10-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull misc x86 fixes from Ingo Molnar:

 - Fix a possible CPU hotplug deadlock bug caused by the new TSC
   synchronization code

 - Fix a legacy PIC discovery bug that results in device troubles on
   affected systems, such as non-working keybards, etc

 - Add a new Intel CPU model number to <asm/intel-family.h>

* tag 'x86-urgent-2023-10-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/tsc: Defer marking TSC unstable to a worker
  x86/i8259: Skip probing when ACPI/MADT advertises PCAT compatibility
  x86/cpu: Add model number for Intel Arrow Lake mobile processor
parents e663ab6b bd94d86f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -69,6 +69,8 @@ struct legacy_pic {
	void (*make_irq)(unsigned int irq);
};

void legacy_pic_pcat_compat(void);

extern struct legacy_pic *legacy_pic;
extern struct legacy_pic null_legacy_pic;

+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
 *		_X	- regular server parts
 *		_D	- micro server parts
 *		_N,_P	- other mobile parts
 *		_H	- premium mobile parts
 *		_S	- other client parts
 *
 *		Historical OPTDIFFs:
@@ -124,6 +125,7 @@
#define INTEL_FAM6_METEORLAKE		0xAC
#define INTEL_FAM6_METEORLAKE_L		0xAA

#define INTEL_FAM6_ARROWLAKE_H		0xC5
#define INTEL_FAM6_ARROWLAKE		0xC6

#define INTEL_FAM6_LUNARLAKE_M		0xBD
+3 −0
Original line number Diff line number Diff line
@@ -148,6 +148,9 @@ static int __init acpi_parse_madt(struct acpi_table_header *table)
		pr_debug("Local APIC address 0x%08x\n", madt->address);
	}

	if (madt->flags & ACPI_MADT_PCAT_COMPAT)
		legacy_pic_pcat_compat();

	/* ACPI 6.3 and newer support the online capable bit. */
	if (acpi_gbl_FADT.header.revision > 6 ||
	    (acpi_gbl_FADT.header.revision == 6 &&
+30 −8
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
 */
static void init_8259A(int auto_eoi);

static bool pcat_compat __ro_after_init;
static int i8259A_auto_eoi;
DEFINE_RAW_SPINLOCK(i8259A_lock);

@@ -299,15 +300,32 @@ static void unmask_8259A(void)

static int probe_8259A(void)
{
	unsigned char new_val, probe_val = ~(1 << PIC_CASCADE_IR);
	unsigned long flags;
	unsigned char probe_val = ~(1 << PIC_CASCADE_IR);
	unsigned char new_val;

	/*
	 * Check to see if we have a PIC.
	 * Mask all except the cascade and read
	 * back the value we just wrote. If we don't
	 * have a PIC, we will read 0xff as opposed to the
	 * value we wrote.
	 * If MADT has the PCAT_COMPAT flag set, then do not bother probing
	 * for the PIC. Some BIOSes leave the PIC uninitialized and probing
	 * fails.
	 *
	 * Right now this causes problems as quite some code depends on
	 * nr_legacy_irqs() > 0 or has_legacy_pic() == true. This is silly
	 * when the system has an IO/APIC because then PIC is not required
	 * at all, except for really old machines where the timer interrupt
	 * must be routed through the PIC. So just pretend that the PIC is
	 * there and let legacy_pic->init() initialize it for nothing.
	 *
	 * Alternatively this could just try to initialize the PIC and
	 * repeat the probe, but for cases where there is no PIC that's
	 * just pointless.
	 */
	if (pcat_compat)
		return nr_legacy_irqs();

	/*
	 * Check to see if we have a PIC.  Mask all except the cascade and
	 * read back the value we just wrote. If we don't have a PIC, we
	 * will read 0xff as opposed to the value we wrote.
	 */
	raw_spin_lock_irqsave(&i8259A_lock, flags);

@@ -429,5 +447,9 @@ static int __init i8259A_init_ops(void)

	return 0;
}

device_initcall(i8259A_init_ops);

void __init legacy_pic_pcat_compat(void)
{
	pcat_compat = true;
}
+9 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 * ( The serial nature of the boot logic and the CPU hotplug lock
 *   protects against more than 2 CPUs entering this code. )
 */
#include <linux/workqueue.h>
#include <linux/topology.h>
#include <linux/spinlock.h>
#include <linux/kernel.h>
@@ -342,6 +343,13 @@ static inline unsigned int loop_timeout(int cpu)
	return (cpumask_weight(topology_core_cpumask(cpu)) > 1) ? 2 : 20;
}

static void tsc_sync_mark_tsc_unstable(struct work_struct *work)
{
	mark_tsc_unstable("check_tsc_sync_source failed");
}

static DECLARE_WORK(tsc_sync_work, tsc_sync_mark_tsc_unstable);

/*
 * The freshly booted CPU initiates this via an async SMP function call.
 */
@@ -395,7 +403,7 @@ static void check_tsc_sync_source(void *__cpu)
			"turning off TSC clock.\n", max_warp);
		if (random_warps)
			pr_warn("TSC warped randomly between CPUs\n");
		mark_tsc_unstable("check_tsc_sync_source failed");
		schedule_work(&tsc_sync_work);
	}

	/*