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

Changed files
+46 -9
arch
x86
include
kernel
+2
arch/x86/include/asm/i8259.h
··· 69 69 void (*make_irq)(unsigned int irq); 70 70 }; 71 71 72 + void legacy_pic_pcat_compat(void); 73 + 72 74 extern struct legacy_pic *legacy_pic; 73 75 extern struct legacy_pic null_legacy_pic; 74 76
+2
arch/x86/include/asm/intel-family.h
··· 27 27 * _X - regular server parts 28 28 * _D - micro server parts 29 29 * _N,_P - other mobile parts 30 + * _H - premium mobile parts 30 31 * _S - other client parts 31 32 * 32 33 * Historical OPTDIFFs: ··· 125 124 #define INTEL_FAM6_METEORLAKE 0xAC 126 125 #define INTEL_FAM6_METEORLAKE_L 0xAA 127 126 127 + #define INTEL_FAM6_ARROWLAKE_H 0xC5 128 128 #define INTEL_FAM6_ARROWLAKE 0xC6 129 129 130 130 #define INTEL_FAM6_LUNARLAKE_M 0xBD
+3
arch/x86/kernel/acpi/boot.c
··· 148 148 pr_debug("Local APIC address 0x%08x\n", madt->address); 149 149 } 150 150 151 + if (madt->flags & ACPI_MADT_PCAT_COMPAT) 152 + legacy_pic_pcat_compat(); 153 + 151 154 /* ACPI 6.3 and newer support the online capable bit. */ 152 155 if (acpi_gbl_FADT.header.revision > 6 || 153 156 (acpi_gbl_FADT.header.revision == 6 &&
+30 -8
arch/x86/kernel/i8259.c
··· 32 32 */ 33 33 static void init_8259A(int auto_eoi); 34 34 35 + static bool pcat_compat __ro_after_init; 35 36 static int i8259A_auto_eoi; 36 37 DEFINE_RAW_SPINLOCK(i8259A_lock); 37 38 ··· 300 299 301 300 static int probe_8259A(void) 302 301 { 302 + unsigned char new_val, probe_val = ~(1 << PIC_CASCADE_IR); 303 303 unsigned long flags; 304 - unsigned char probe_val = ~(1 << PIC_CASCADE_IR); 305 - unsigned char new_val; 304 + 306 305 /* 307 - * Check to see if we have a PIC. 308 - * Mask all except the cascade and read 309 - * back the value we just wrote. If we don't 310 - * have a PIC, we will read 0xff as opposed to the 311 - * value we wrote. 306 + * If MADT has the PCAT_COMPAT flag set, then do not bother probing 307 + * for the PIC. Some BIOSes leave the PIC uninitialized and probing 308 + * fails. 309 + * 310 + * Right now this causes problems as quite some code depends on 311 + * nr_legacy_irqs() > 0 or has_legacy_pic() == true. This is silly 312 + * when the system has an IO/APIC because then PIC is not required 313 + * at all, except for really old machines where the timer interrupt 314 + * must be routed through the PIC. So just pretend that the PIC is 315 + * there and let legacy_pic->init() initialize it for nothing. 316 + * 317 + * Alternatively this could just try to initialize the PIC and 318 + * repeat the probe, but for cases where there is no PIC that's 319 + * just pointless. 320 + */ 321 + if (pcat_compat) 322 + return nr_legacy_irqs(); 323 + 324 + /* 325 + * Check to see if we have a PIC. Mask all except the cascade and 326 + * read back the value we just wrote. If we don't have a PIC, we 327 + * will read 0xff as opposed to the value we wrote. 312 328 */ 313 329 raw_spin_lock_irqsave(&i8259A_lock, flags); 314 330 ··· 447 429 448 430 return 0; 449 431 } 450 - 451 432 device_initcall(i8259A_init_ops); 433 + 434 + void __init legacy_pic_pcat_compat(void) 435 + { 436 + pcat_compat = true; 437 + }
+9 -1
arch/x86/kernel/tsc_sync.c
··· 15 15 * ( The serial nature of the boot logic and the CPU hotplug lock 16 16 * protects against more than 2 CPUs entering this code. ) 17 17 */ 18 + #include <linux/workqueue.h> 18 19 #include <linux/topology.h> 19 20 #include <linux/spinlock.h> 20 21 #include <linux/kernel.h> ··· 343 342 return (cpumask_weight(topology_core_cpumask(cpu)) > 1) ? 2 : 20; 344 343 } 345 344 345 + static void tsc_sync_mark_tsc_unstable(struct work_struct *work) 346 + { 347 + mark_tsc_unstable("check_tsc_sync_source failed"); 348 + } 349 + 350 + static DECLARE_WORK(tsc_sync_work, tsc_sync_mark_tsc_unstable); 351 + 346 352 /* 347 353 * The freshly booted CPU initiates this via an async SMP function call. 348 354 */ ··· 403 395 "turning off TSC clock.\n", max_warp); 404 396 if (random_warps) 405 397 pr_warn("TSC warped randomly between CPUs\n"); 406 - mark_tsc_unstable("check_tsc_sync_source failed"); 398 + schedule_work(&tsc_sync_work); 407 399 } 408 400 409 401 /*