Skip to content

Commit 7405c0f

Browse files
committed
Merge tag 'x86-urgent-2025-03-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull misc x86 fixes and updates from Ingo Molnar: - Fix a large number of x86 Kconfig dependency and help text accuracy bugs/problems, by Mateusz Jończyk and David Heideberg - Fix a VM_PAT interaction with fork() crash. This also touches core kernel code - Fix an ORC unwinder bug for interrupt entries - Fixes and cleanups - Fix an AMD microcode loader bug that can promote verification failures into success - Add early-printk support for MMIO based UARTs on an x86 board that had no other serial debugging facility and also experienced early boot crashes * tag 'x86-urgent-2025-03-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/microcode/AMD: Fix __apply_microcode_amd()'s return value x86/mm/pat: Fix VM_PAT handling when fork() fails in copy_page_range() x86/fpu: Update the outdated comment above fpstate_init_user() x86/early_printk: Add support for MMIO-based UARTs x86/dumpstack: Fix inaccurate unwinding from exception stacks due to misplaced assignment x86/entry: Fix ORC unwinder for PUSH_REGS with save_ret=1 x86/Kconfig: Fix lists in X86_EXTENDED_PLATFORM help text x86/Kconfig: Correct X86_X2APIC help text x86/speculation: Remove the extra #ifdef around CALL_NOSPEC x86/Kconfig: Document release year of glibc 2.3.3 x86/Kconfig: Make CONFIG_PCI_CNB20LE_QUIRK depend on X86_32 x86/Kconfig: Document CONFIG_PCI_MMCONFIG x86/Kconfig: Update lists in X86_EXTENDED_PLATFORM x86/Kconfig: Move all X86_EXTENDED_PLATFORM options together x86/Kconfig: Always enable ARCH_SPARSEMEM_ENABLE x86/Kconfig: Enable X86_X2APIC by default and improve help text
2 parents b4c5c57 + 31ab12d commit 7405c0f

File tree

12 files changed

+172
-75
lines changed

12 files changed

+172
-75
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1407,14 +1407,21 @@
14071407
earlyprintk=serial[,0x...[,baudrate]]
14081408
earlyprintk=ttySn[,baudrate]
14091409
earlyprintk=dbgp[debugController#]
1410-
earlyprintk=pciserial[,force],bus:device.function[,baudrate]
1410+
earlyprintk=pciserial[,force],bus:device.function[,{nocfg|baudrate}]
14111411
earlyprintk=xdbc[xhciController#]
14121412
earlyprintk=bios
1413+
earlyprintk=mmio,membase[,{nocfg|baudrate}]
14131414

14141415
earlyprintk is useful when the kernel crashes before
14151416
the normal console is initialized. It is not enabled by
14161417
default because it has some cosmetic problems.
14171418

1419+
Only 32-bit memory addresses are supported for "mmio"
1420+
and "pciserial" devices.
1421+
1422+
Use "nocfg" to skip UART configuration, assume
1423+
BIOS/firmware has configured UART correctly.
1424+
14181425
Append ",keep" to not disable it when the real console
14191426
takes over.
14201427

arch/x86/Kconfig

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -460,20 +460,28 @@ config SMP
460460
If you don't know what to do here, say N.
461461

462462
config X86_X2APIC
463-
bool "Support x2apic"
463+
bool "x2APIC interrupt controller architecture support"
464464
depends on X86_LOCAL_APIC && X86_64 && (IRQ_REMAP || HYPERVISOR_GUEST)
465+
default y
465466
help
466-
This enables x2apic support on CPUs that have this feature.
467+
x2APIC is an interrupt controller architecture, a component of which
468+
(the local APIC) is present in the CPU. It allows faster access to
469+
the local APIC and supports a larger number of CPUs in the system
470+
than the predecessors.
467471

468-
This allows 32-bit apic IDs (so it can support very large systems),
469-
and accesses the local apic via MSRs not via mmio.
472+
x2APIC was introduced in Intel CPUs around 2008 and in AMD EPYC CPUs
473+
in 2019, but it can be disabled by the BIOS. It is also frequently
474+
emulated in virtual machines, even when the host CPU does not support
475+
it. Support in the CPU can be checked by executing
476+
grep x2apic /proc/cpuinfo
470477

471-
Some Intel systems circa 2022 and later are locked into x2APIC mode
472-
and can not fall back to the legacy APIC modes if SGX or TDX are
473-
enabled in the BIOS. They will boot with very reduced functionality
474-
without enabling this option.
478+
If this configuration option is disabled, the kernel will boot with
479+
very reduced functionality and performance on some platforms that
480+
have x2APIC enabled. On the other hand, on hardware that does not
481+
support x2APIC, a kernel with this option enabled will just fallback
482+
to older APIC implementations.
475483

476-
If you don't know what to do here, say N.
484+
If in doubt, say Y.
477485

478486
config X86_POSTED_MSI
479487
bool "Enable MSI and MSI-x delivery by posted interrupts"
@@ -544,16 +552,17 @@ config X86_EXTENDED_PLATFORM
544552
CONFIG_64BIT.
545553

546554
32-bit platforms (CONFIG_64BIT=n):
547-
Goldfish (Android emulator)
548-
AMD Elan
555+
Goldfish (mostly Android emulator)
556+
Intel CE media processor (CE4100) SoC
557+
Intel Quark
549558
RDC R-321x SoC
550-
SGI 320/540 (Visual Workstation)
551559

552560
64-bit platforms (CONFIG_64BIT=y):
553561
Numascale NumaChip
554562
ScaleMP vSMP
555563
SGI Ultraviolet
556564
Merrifield/Moorefield MID devices
565+
Goldfish (mostly Android emulator)
557566

558567
If you have one of these systems, or if you want to build a
559568
generic distribution kernel, say Y here - otherwise say N.
@@ -667,6 +676,17 @@ config X86_INTEL_QUARK
667676
Say Y here if you have a Quark based system such as the Arduino
668677
compatible Intel Galileo.
669678

679+
config X86_RDC321X
680+
bool "RDC R-321x SoC"
681+
depends on X86_32
682+
depends on X86_EXTENDED_PLATFORM
683+
select M486
684+
select X86_REBOOTFIXUPS
685+
help
686+
This option is needed for RDC R-321x system-on-chip, also known
687+
as R-8610-(G).
688+
If you don't have one of these chips, you should say N here.
689+
670690
config X86_INTEL_LPSS
671691
bool "Intel Low Power Subsystem Support"
672692
depends on X86 && ACPI && PCI
@@ -720,17 +740,6 @@ config IOSF_MBI_DEBUG
720740

721741
If you don't require the option or are in doubt, say N.
722742

723-
config X86_RDC321X
724-
bool "RDC R-321x SoC"
725-
depends on X86_32
726-
depends on X86_EXTENDED_PLATFORM
727-
select M486
728-
select X86_REBOOTFIXUPS
729-
help
730-
This option is needed for RDC R-321x system-on-chip, also known
731-
as R-8610-(G).
732-
If you don't have one of these chips, you should say N here.
733-
734743
config X86_SUPPORTS_MEMORY_FAILURE
735744
def_bool y
736745
# MCE code calls memory_failure():
@@ -1565,7 +1574,6 @@ config ARCH_FLATMEM_ENABLE
15651574

15661575
config ARCH_SPARSEMEM_ENABLE
15671576
def_bool y
1568-
depends on X86_64 || NUMA || X86_32
15691577
select SPARSEMEM_STATIC if X86_32
15701578
select SPARSEMEM_VMEMMAP_ENABLE if X86_64
15711579

@@ -2212,7 +2220,7 @@ config HOTPLUG_CPU
22122220

22132221
config COMPAT_VDSO
22142222
def_bool n
2215-
prompt "Disable the 32-bit vDSO (needed for glibc 2.3.3)"
2223+
prompt "Workaround for glibc 2.3.2 / 2.3.3 (released in year 2003/2004)"
22162224
depends on COMPAT_32
22172225
help
22182226
Certain buggy versions of glibc will crash if they are
@@ -2901,6 +2909,19 @@ config PCI_MMCONFIG
29012909
default y
29022910
depends on PCI && (ACPI || JAILHOUSE_GUEST)
29032911
depends on X86_64 || (PCI_GOANY || PCI_GOMMCONFIG)
2912+
help
2913+
Add support for accessing the PCI configuration space as a memory
2914+
mapped area. It is the recommended method if the system supports
2915+
this (it must have PCI Express and ACPI for it to be available).
2916+
2917+
In the unlikely case that enabling this configuration option causes
2918+
problems, the mechanism can be switched off with the 'pci=nommconf'
2919+
command line parameter.
2920+
2921+
Say N only if you are sure that your platform does not support this
2922+
access method or you have problems caused by it.
2923+
2924+
Say Y otherwise.
29042925

29052926
config PCI_OLPC
29062927
def_bool y
@@ -2915,13 +2936,21 @@ config MMCONF_FAM10H
29152936
depends on X86_64 && PCI_MMCONFIG && ACPI
29162937

29172938
config PCI_CNB20LE_QUIRK
2918-
bool "Read CNB20LE Host Bridge Windows" if EXPERT
2919-
depends on PCI
2939+
bool "Read PCI host bridge windows from the CNB20LE chipset" if EXPERT
2940+
depends on X86_32 && PCI
29202941
help
29212942
Read the PCI windows out of the CNB20LE host bridge. This allows
29222943
PCI hotplug to work on systems with the CNB20LE chipset which do
29232944
not have ACPI.
29242945

2946+
The ServerWorks (later Broadcom) CNB20LE was a chipset designed
2947+
most probably only for Pentium III.
2948+
2949+
To find out if you have such a chipset, search for a PCI device with
2950+
1166:0009 PCI IDs, for example by executing
2951+
lspci -nn | grep '1166:0009'
2952+
The code is inactive if there is none.
2953+
29252954
There's no public spec for this chipset, and this functionality
29262955
is known to be incomplete.
29272956

arch/x86/entry/calling.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ For 32-bit we have the following conventions - kernel is built with
7070
pushq %rsi /* pt_regs->si */
7171
movq 8(%rsp), %rsi /* temporarily store the return address in %rsi */
7272
movq %rdi, 8(%rsp) /* pt_regs->di (overwriting original return address) */
73+
/* We just clobbered the return address - use the IRET frame for unwinding: */
74+
UNWIND_HINT_IRET_REGS offset=3*8
7375
.else
7476
pushq %rdi /* pt_regs->di */
7577
pushq %rsi /* pt_regs->si */

arch/x86/include/asm/nospec-branch.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -435,12 +435,8 @@ static inline void call_depth_return_thunk(void) {}
435435
* Inline asm uses the %V modifier which is only in newer GCC
436436
* which is ensured when CONFIG_MITIGATION_RETPOLINE is defined.
437437
*/
438-
#ifdef CONFIG_MITIGATION_RETPOLINE
439438
#define CALL_NOSPEC __CS_PREFIX("%V[thunk_target]") \
440439
"call __x86_indirect_thunk_%V[thunk_target]\n"
441-
#else
442-
#define CALL_NOSPEC "call *%[thunk_target]\n"
443-
#endif
444440

445441
# define THUNK_TARGET(addr) [thunk_target] "r" (addr)
446442

arch/x86/kernel/cpu/microcode/amd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ static bool __apply_microcode_amd(struct microcode_amd *mc, u32 *cur_rev,
600600
unsigned long p_addr = (unsigned long)&mc->hdr.data_code;
601601

602602
if (!verify_sha256_digest(mc->hdr.patch_id, *cur_rev, (const u8 *)p_addr, psize))
603-
return -1;
603+
return false;
604604

605605
native_wrmsrl(MSR_AMD64_PATCH_LOADER, p_addr);
606606

arch/x86/kernel/dumpstack.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
195195
printk("%sCall Trace:\n", log_lvl);
196196

197197
unwind_start(&state, task, regs, stack);
198+
stack = stack ?: get_stack_pointer(task, regs);
198199
regs = unwind_get_entry_regs(&state, &partial);
199200

200201
/*
@@ -213,9 +214,7 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
213214
* - hardirq stack
214215
* - entry stack
215216
*/
216-
for (stack = stack ?: get_stack_pointer(task, regs);
217-
stack;
218-
stack = stack_info.next_sp) {
217+
for (; stack; stack = stack_info.next_sp) {
219218
const char *stack_name;
220219

221220
stack = PTR_ALIGN(stack, sizeof(long));

arch/x86/kernel/early_printk.c

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ static __init void early_serial_init(char *s)
190190
early_serial_hw_init(divisor);
191191
}
192192

193-
#ifdef CONFIG_PCI
194193
static __noendbr void mem32_serial_out(unsigned long addr, int offset, int value)
195194
{
196195
u32 __iomem *vaddr = (u32 __iomem *)addr;
@@ -207,6 +206,45 @@ static __noendbr unsigned int mem32_serial_in(unsigned long addr, int offset)
207206
}
208207
ANNOTATE_NOENDBR_SYM(mem32_serial_in);
209208

209+
/*
210+
* early_mmio_serial_init() - Initialize MMIO-based early serial console.
211+
* @s: MMIO-based serial specification.
212+
*/
213+
static __init void early_mmio_serial_init(char *s)
214+
{
215+
unsigned long baudrate;
216+
unsigned long membase;
217+
char *e;
218+
219+
if (*s == ',')
220+
s++;
221+
222+
if (!strncmp(s, "0x", 2)) {
223+
/* NB: only 32-bit addresses are supported. */
224+
membase = simple_strtoul(s, &e, 16);
225+
early_serial_base = (unsigned long)early_ioremap(membase, PAGE_SIZE);
226+
227+
static_call_update(serial_in, mem32_serial_in);
228+
static_call_update(serial_out, mem32_serial_out);
229+
230+
s += strcspn(s, ",");
231+
if (*s == ',')
232+
s++;
233+
}
234+
235+
if (!strncmp(s, "nocfg", 5)) {
236+
baudrate = 0;
237+
} else {
238+
baudrate = simple_strtoul(s, &e, 0);
239+
if (baudrate == 0 || s == e)
240+
baudrate = DEFAULT_BAUD;
241+
}
242+
243+
if (baudrate)
244+
early_serial_hw_init(115200 / baudrate);
245+
}
246+
247+
#ifdef CONFIG_PCI
210248
/*
211249
* early_pci_serial_init()
212250
*
@@ -351,6 +389,11 @@ static int __init setup_early_printk(char *buf)
351389
keep = (strstr(buf, "keep") != NULL);
352390

353391
while (*buf != '\0') {
392+
if (!strncmp(buf, "mmio", 4)) {
393+
early_mmio_serial_init(buf + 4);
394+
early_console_register(&early_serial_console, keep);
395+
buf += 4;
396+
}
354397
if (!strncmp(buf, "serial", 6)) {
355398
buf += 6;
356399
early_serial_init(buf);

arch/x86/kernel/fpu/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ static inline void fpstate_init_fstate(struct fpstate *fpstate)
508508
/*
509509
* Used in two places:
510510
* 1) Early boot to setup init_fpstate for non XSAVE systems
511-
* 2) fpu_init_fpstate_user() which is invoked from KVM
511+
* 2) fpu_alloc_guest_fpstate() which is invoked from KVM
512512
*/
513513
void fpstate_init_user(struct fpstate *fpstate)
514514
{

arch/x86/mm/pat/memtype.c

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -984,29 +984,42 @@ static int get_pat_info(struct vm_area_struct *vma, resource_size_t *paddr,
984984
return -EINVAL;
985985
}
986986

987-
/*
988-
* track_pfn_copy is called when vma that is covering the pfnmap gets
989-
* copied through copy_page_range().
990-
*
991-
* If the vma has a linear pfn mapping for the entire range, we get the prot
992-
* from pte and reserve the entire vma range with single reserve_pfn_range call.
993-
*/
994-
int track_pfn_copy(struct vm_area_struct *vma)
987+
int track_pfn_copy(struct vm_area_struct *dst_vma,
988+
struct vm_area_struct *src_vma, unsigned long *pfn)
995989
{
990+
const unsigned long vma_size = src_vma->vm_end - src_vma->vm_start;
996991
resource_size_t paddr;
997-
unsigned long vma_size = vma->vm_end - vma->vm_start;
998992
pgprot_t pgprot;
993+
int rc;
999994

1000-
if (vma->vm_flags & VM_PAT) {
1001-
if (get_pat_info(vma, &paddr, &pgprot))
1002-
return -EINVAL;
1003-
/* reserve the whole chunk covered by vma. */
1004-
return reserve_pfn_range(paddr, vma_size, &pgprot, 1);
1005-
}
995+
if (!(src_vma->vm_flags & VM_PAT))
996+
return 0;
997+
998+
/*
999+
* Duplicate the PAT information for the dst VMA based on the src
1000+
* VMA.
1001+
*/
1002+
if (get_pat_info(src_vma, &paddr, &pgprot))
1003+
return -EINVAL;
1004+
rc = reserve_pfn_range(paddr, vma_size, &pgprot, 1);
1005+
if (rc)
1006+
return rc;
10061007

1008+
/* Reservation for the destination VMA succeeded. */
1009+
vm_flags_set(dst_vma, VM_PAT);
1010+
*pfn = PHYS_PFN(paddr);
10071011
return 0;
10081012
}
10091013

1014+
void untrack_pfn_copy(struct vm_area_struct *dst_vma, unsigned long pfn)
1015+
{
1016+
untrack_pfn(dst_vma, pfn, dst_vma->vm_end - dst_vma->vm_start, true);
1017+
/*
1018+
* Reservation was freed, any copied page tables will get cleaned
1019+
* up later, but without getting PAT involved again.
1020+
*/
1021+
}
1022+
10101023
/*
10111024
* prot is passed in as a parameter for the new mapping. If the vma has
10121025
* a linear pfn mapping for the entire range, or no vma is provided,
@@ -1095,15 +1108,6 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
10951108
}
10961109
}
10971110

1098-
/*
1099-
* untrack_pfn_clear is called if the following situation fits:
1100-
*
1101-
* 1) while mremapping a pfnmap for a new region, with the old vma after
1102-
* its pfnmap page table has been removed. The new vma has a new pfnmap
1103-
* to the same pfn & cache type with VM_PAT set.
1104-
* 2) while duplicating vm area, the new vma fails to copy the pgtable from
1105-
* old vma.
1106-
*/
11071111
void untrack_pfn_clear(struct vm_area_struct *vma)
11081112
{
11091113
vm_flags_clear(vma, VM_PAT);

0 commit comments

Comments
 (0)