Commit 7cffdbe3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86-boot-2023-06-26' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 boot updates from Thomas Gleixner:
 "Initialize FPU late.

  Right now FPU is initialized very early during boot. There is no real
  requirement to do so. The only requirement is to have it done before
  alternatives are patched.

  That's done in check_bugs() which does way more than what the function
  name suggests.

  So first rename check_bugs() to arch_cpu_finalize_init() which makes
  it clear what this is about.

  Move the invocation of arch_cpu_finalize_init() earlier in
  start_kernel() as it has to be done before fork_init() which needs to
  know the FPU register buffer size.

  With those prerequisites the FPU initialization can be moved into
  arch_cpu_finalize_init(), which removes it from the early and fragile
  part of the x86 bringup"

* tag 'x86-boot-2023-06-26' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mem_encrypt: Unbreak the AMD_MEM_ENCRYPT=n build
  x86/fpu: Move FPU initialization into arch_cpu_finalize_init()
  x86/fpu: Mark init functions __init
  x86/fpu: Remove cpuinfo argument from init functions
  x86/init: Initialize signal frame size late
  init, x86: Move mem_encrypt_init() into arch_cpu_finalize_init()
  init: Invoke arch_cpu_finalize_init() earlier
  init: Remove check_bugs() leftovers
  um/cpu: Switch to arch_cpu_finalize_init()
  sparc/cpu: Switch to arch_cpu_finalize_init()
  sh/cpu: Switch to arch_cpu_finalize_init()
  mips/cpu: Switch to arch_cpu_finalize_init()
  m68k/cpu: Switch to arch_cpu_finalize_init()
  loongarch/cpu: Switch to arch_cpu_finalize_init()
  ia64/cpu: Switch to arch_cpu_finalize_init()
  ARM: cpu: Switch to arch_cpu_finalize_init()
  x86/cpu: Switch to arch_cpu_finalize_init()
  init: Provide arch_cpu_finalize_init()
parents 00173879 0a9567ac
...@@ -285,6 +285,9 @@ config ARCH_HAS_DMA_SET_UNCACHED ...@@ -285,6 +285,9 @@ config ARCH_HAS_DMA_SET_UNCACHED
config ARCH_HAS_DMA_CLEAR_UNCACHED config ARCH_HAS_DMA_CLEAR_UNCACHED
bool bool
config ARCH_HAS_CPU_FINALIZE_INIT
bool
# Select if arch init_task must go in the __init_task_data section # Select if arch init_task must go in the __init_task_data section
config ARCH_TASK_STRUCT_ON_STACK config ARCH_TASK_STRUCT_ON_STACK
bool bool
......
/*
* include/asm-alpha/bugs.h
*
* Copyright (C) 1994 Linus Torvalds
*/
/*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Needs:
* void check_bugs(void);
*/
/*
* I don't know of any alpha bugs yet.. Nice chip
*/
static void check_bugs(void)
{
}
...@@ -5,6 +5,7 @@ config ARM ...@@ -5,6 +5,7 @@ config ARM
select ARCH_32BIT_OFF_T select ARCH_32BIT_OFF_T
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND
select ARCH_HAS_BINFMT_FLAT select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_CPU_FINALIZE_INIT if MMU
select ARCH_HAS_CURRENT_STACK_POINTER select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL if MMU select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
......
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* arch/arm/include/asm/bugs.h
*
* Copyright (C) 1995-2003 Russell King * Copyright (C) 1995-2003 Russell King
*/ */
#ifndef __ASM_BUGS_H #ifndef __ASM_BUGS_H
...@@ -10,10 +8,8 @@ ...@@ -10,10 +8,8 @@
extern void check_writebuffer_bugs(void); extern void check_writebuffer_bugs(void);
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
extern void check_bugs(void);
extern void check_other_bugs(void); extern void check_other_bugs(void);
#else #else
#define check_bugs() do { } while (0)
#define check_other_bugs() do { } while (0) #define check_other_bugs() do { } while (0)
#endif #endif
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/init.h> #include <linux/init.h>
#include <linux/cpu.h>
#include <asm/bugs.h> #include <asm/bugs.h>
#include <asm/proc-fns.h> #include <asm/proc-fns.h>
...@@ -11,7 +12,7 @@ void check_other_bugs(void) ...@@ -11,7 +12,7 @@ void check_other_bugs(void)
#endif #endif
} }
void __init check_bugs(void) void __init arch_cpu_finalize_init(void)
{ {
check_writebuffer_bugs(); check_writebuffer_bugs();
check_other_bugs(); check_other_bugs();
......
...@@ -9,6 +9,7 @@ menu "Processor type and features" ...@@ -9,6 +9,7 @@ menu "Processor type and features"
config IA64 config IA64
bool bool
select ARCH_BINFMT_ELF_EXTRA_PHDRS select ARCH_BINFMT_ELF_EXTRA_PHDRS
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_DMA_MARK_CLEAN select ARCH_HAS_DMA_MARK_CLEAN
select ARCH_HAS_STRNCPY_FROM_USER select ARCH_HAS_STRNCPY_FROM_USER
select ARCH_HAS_STRNLEN_USER select ARCH_HAS_STRNLEN_USER
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Needs:
* void check_bugs(void);
*
* Based on <asm-alpha/bugs.h>.
*
* Modified 1998, 1999, 2003
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co.
*/
#ifndef _ASM_IA64_BUGS_H
#define _ASM_IA64_BUGS_H
#include <asm/processor.h>
extern void check_bugs (void);
#endif /* _ASM_IA64_BUGS_H */
...@@ -1067,8 +1067,7 @@ cpu_init (void) ...@@ -1067,8 +1067,7 @@ cpu_init (void)
} }
} }
void __init void __init arch_cpu_finalize_init(void)
check_bugs (void)
{ {
ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles, ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
(unsigned long) __end___mckinley_e9_bundles); (unsigned long) __end___mckinley_e9_bundles);
......
...@@ -10,6 +10,7 @@ config LOONGARCH ...@@ -10,6 +10,7 @@ config LOONGARCH
select ARCH_ENABLE_MEMORY_HOTPLUG select ARCH_ENABLE_MEMORY_HOTPLUG
select ARCH_ENABLE_MEMORY_HOTREMOVE select ARCH_ENABLE_MEMORY_HOTREMOVE
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_PTE_SPECIAL
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
*/
#ifndef _ASM_BUGS_H
#define _ASM_BUGS_H
#include <asm/cpu.h>
#include <asm/cpu-info.h>
extern void check_bugs(void);
#endif /* _ASM_BUGS_H */
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/cpu.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/export.h> #include <linux/export.h>
...@@ -37,7 +38,6 @@ ...@@ -37,7 +38,6 @@
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <asm/alternative.h> #include <asm/alternative.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/bugs.h>
#include <asm/cache.h> #include <asm/cache.h>
#include <asm/cpu.h> #include <asm/cpu.h>
#include <asm/dma.h> #include <asm/dma.h>
...@@ -87,7 +87,7 @@ const char *get_system_type(void) ...@@ -87,7 +87,7 @@ const char *get_system_type(void)
return "generic-loongson-machine"; return "generic-loongson-machine";
} }
void __init check_bugs(void) void __init arch_cpu_finalize_init(void)
{ {
alternative_instructions(); alternative_instructions();
} }
......
...@@ -4,6 +4,7 @@ config M68K ...@@ -4,6 +4,7 @@ config M68K
default y default y
select ARCH_32BIT_OFF_T select ARCH_32BIT_OFF_T
select ARCH_HAS_BINFMT_FLAT select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_CPU_FINALIZE_INIT if MMU
select ARCH_HAS_CURRENT_STACK_POINTER select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* include/asm-m68k/bugs.h
*
* Copyright (C) 1994 Linus Torvalds
*/
/*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Needs:
* void check_bugs(void);
*/
#ifdef CONFIG_MMU
extern void check_bugs(void); /* in arch/m68k/kernel/setup.c */
#else
static void check_bugs(void)
{
}
#endif
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/cpu.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -504,7 +505,7 @@ static int __init proc_hardware_init(void) ...@@ -504,7 +505,7 @@ static int __init proc_hardware_init(void)
module_init(proc_hardware_init); module_init(proc_hardware_init);
#endif #endif
void check_bugs(void) void __init arch_cpu_finalize_init(void)
{ {
#if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU) #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU)
if (m68k_fputype == 0) { if (m68k_fputype == 0) {
......
...@@ -4,6 +4,7 @@ config MIPS ...@@ -4,6 +4,7 @@ config MIPS
default y default y
select ARCH_32BIT_OFF_T if !64BIT select ARCH_32BIT_OFF_T if !64BIT
select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_CURRENT_STACK_POINTER if !CC_IS_CLANG || CLANG_VERSION >= 140000 select ARCH_HAS_CURRENT_STACK_POINTER if !CC_IS_CLANG || CLANG_VERSION >= 140000
select ARCH_HAS_DEBUG_VIRTUAL if !64BIT select ARCH_HAS_DEBUG_VIRTUAL if !64BIT
select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_FORTIFY_SOURCE
......
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
/* /*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Copyright (C) 2007 Maciej W. Rozycki * Copyright (C) 2007 Maciej W. Rozycki
*
* Needs:
* void check_bugs(void);
*/ */
#ifndef _ASM_BUGS_H #ifndef _ASM_BUGS_H
#define _ASM_BUGS_H #define _ASM_BUGS_H
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/delay.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/cpu.h> #include <asm/cpu.h>
...@@ -24,17 +18,6 @@ extern void check_bugs64_early(void); ...@@ -24,17 +18,6 @@ extern void check_bugs64_early(void);
extern void check_bugs32(void); extern void check_bugs32(void);
extern void check_bugs64(void); extern void check_bugs64(void);
static inline void __init check_bugs(void)
{
unsigned int cpu = smp_processor_id();
cpu_data[cpu].udelay_val = loops_per_jiffy;
check_bugs32();
if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64))
check_bugs64();
}
static inline int r4k_daddiu_bug(void) static inline int r4k_daddiu_bug(void)
{ {
if (!IS_ENABLED(CONFIG_CPU_R4X00_BUGS64)) if (!IS_ENABLED(CONFIG_CPU_R4X00_BUGS64))
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
* Copyright (C) 2000, 2001, 2002, 2007 Maciej W. Rozycki * Copyright (C) 2000, 2001, 2002, 2007 Maciej W. Rozycki
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/screen_info.h> #include <linux/screen_info.h>
...@@ -841,3 +843,14 @@ static int __init setnocoherentio(char *str) ...@@ -841,3 +843,14 @@ static int __init setnocoherentio(char *str)
} }
early_param("nocoherentio", setnocoherentio); early_param("nocoherentio", setnocoherentio);
#endif #endif
void __init arch_cpu_finalize_init(void)
{
unsigned int cpu = smp_processor_id();
cpu_data[cpu].udelay_val = loops_per_jiffy;
check_bugs32();
if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64))
check_bugs64();
}
/* SPDX-License-Identifier: GPL-2.0 */
/*
* include/asm-parisc/bugs.h
*
* Copyright (C) 1999 Mike Shaver
*/
/*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Needs:
* void check_bugs(void);
*/
#include <asm/processor.h>
static inline void check_bugs(void)
{
// identify_cpu(&boot_cpu_data);
}
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _ASM_POWERPC_BUGS_H
#define _ASM_POWERPC_BUGS_H
/*
*/
/*
* This file is included by 'init/main.c' to check for
* architecture-dependent bugs.
*/
static inline void check_bugs(void) { }
#endif /* _ASM_POWERPC_BUGS_H */
...@@ -6,6 +6,7 @@ config SUPERH ...@@ -6,6 +6,7 @@ config SUPERH
select ARCH_ENABLE_MEMORY_HOTREMOVE if SPARSEMEM && MMU select ARCH_ENABLE_MEMORY_HOTREMOVE if SPARSEMEM && MMU
select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A) select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
select ARCH_HAS_BINFMT_FLAT if !MMU select ARCH_HAS_BINFMT_FLAT if !MMU
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_CURRENT_STACK_POINTER select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_GIGANTIC_PAGE select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_GCOV_PROFILE_ALL
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_SH_BUGS_H
#define __ASM_SH_BUGS_H
/*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Needs:
* void check_bugs(void);
*/
/*
* I don't know of any Super-H bugs yet.
*/
#include <asm/processor.h>
extern void select_idle_routine(void);
static void __init check_bugs(void)
{
extern unsigned long loops_per_jiffy;
char *p = &init_utsname()->machine[2]; /* "sh" */
select_idle_routine();
current_cpu_data.loops_per_jiffy = loops_per_jiffy;
switch (current_cpu_data.family) {
case CPU_FAMILY_SH2:
*p++ = '2';
break;
case CPU_FAMILY_SH2A:
*p++ = '2';
*p++ = 'a';
break;
case CPU_FAMILY_SH3:
*p++ = '3';
break;
case CPU_FAMILY_SH4:
*p++ = '4';
break;
case CPU_FAMILY_SH4A:
*p++ = '4';
*p++ = 'a';
break;
case CPU_FAMILY_SH4AL_DSP:
*p++ = '4';
*p++ = 'a';
*p++ = 'l';
*p++ = '-';
*p++ = 'd';
*p++ = 's';
*p++ = 'p';
break;
case CPU_FAMILY_UNKNOWN:
/*
* Specifically use CPU_FAMILY_UNKNOWN rather than
* default:, so we're able to have the compiler whine
* about unhandled enumerations.
*/
break;
}
printk("CPU: %s\n", get_cpu_subtype(&current_cpu_data));
#ifndef __LITTLE_ENDIAN__
/* 'eb' means 'Endian Big' */
*p++ = 'e';
*p++ = 'b';
#endif
*p = '\0';
}
#endif /* __ASM_SH_BUGS_H */
...@@ -166,6 +166,8 @@ extern unsigned int instruction_size(unsigned int insn); ...@@ -166,6 +166,8 @@ extern unsigned int instruction_size(unsigned int insn);
#define instruction_size(insn) (2) #define instruction_size(insn) (2)
#endif #endif
void select_idle_routine(void);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#include <asm/processor_32.h> #include <asm/processor_32.h>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/irqflags.h> #include <linux/irqflags.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/processor.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/bl_bit.h> #include <asm/bl_bit.h>
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/mmzone.h> #include <asm/mmzone.h>
#include <asm/processor.h>
#include <asm/sparsemem.h> #include <asm/sparsemem.h>
#include <asm/platform_early.h> #include <asm/platform_early.h>
...@@ -354,3 +355,57 @@ int test_mode_pin(int pin) ...@@ -354,3 +355,57 @@ int test_mode_pin(int pin)
{ {
return sh_mv.mv_mode_pins() & pin; return sh_mv.mv_mode_pins() & pin;
} }
void __init arch_cpu_finalize_init(void)
{
char *p = &init_utsname()->machine[2]; /* "sh" */
select_idle_routine();
current_cpu_data.loops_per_jiffy = loops_per_jiffy;
switch (current_cpu_data.family) {
case CPU_FAMILY_SH2:
*p++ = '2';
break;
case CPU_FAMILY_SH2A:
*p++ = '2';
*p++ = 'a';
break;
case CPU_FAMILY_SH3:
*p++ = '3';
break;
case CPU_FAMILY_SH4:
*p++ = '4';
break;
case CPU_FAMILY_SH4A:
*p++ = '4';
*p++ = 'a';
break;
case CPU_FAMILY_SH4AL_DSP:
*p++ = '4';
*p++ = 'a';
*p++ = 'l';
*p++ = '-';
*p++ = 'd';
*p++ = 's';
*p++ = 'p';
break;
case CPU_FAMILY_UNKNOWN:
/*
* Specifically use CPU_FAMILY_UNKNOWN rather than
* default:, so we're able to have the compiler whine
* about unhandled enumerations.
*/
break;
}
pr_info("CPU: %s\n", get_cpu_subtype(&current_cpu_data));
#ifndef __LITTLE_ENDIAN__
/* 'eb' means 'Endian Big' */
*p++ = 'e';
*p++ = 'b';
#endif
*p = '\0';
}
...@@ -52,6 +52,7 @@ config SPARC ...@@ -52,6 +52,7 @@ config SPARC
config SPARC32 config SPARC32
def_bool !64BIT def_bool !64BIT
select ARCH_32BIT_OFF_T select ARCH_32BIT_OFF_T
select ARCH_HAS_CPU_FINALIZE_INIT if !SMP
select ARCH_HAS_SYNC_DMA_FOR_CPU select ARCH_HAS_SYNC_DMA_FOR_CPU
select CLZ_TAB select CLZ_TAB
select DMA_DIRECT_REMAP select DMA_DIRECT_REMAP
......
/* SPDX-License-Identifier: GPL-2.0 */
/* include/asm/bugs.h: Sparc probes for various bugs.
*
* Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
*/
#ifdef CONFIG_SPARC32
#include <asm/cpudata.h>
#endif
extern unsigned long loops_per_jiffy;
static void __init check_bugs(void)
{
#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP)
cpu_data(0).udelay_val = loops_per_jiffy;
#endif
}
...@@ -412,3 +412,10 @@ static int __init topology_init(void) ...@@ -412,3 +412,10 @@ static int __init topology_init(void)
} }
subsys_initcall(topology_init); subsys_initcall(topology_init);
#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP)
void __init arch_cpu_finalize_init(void)
{
cpu_data(0).udelay_val = loops_per_jiffy;
}
#endif
...@@ -6,6 +6,7 @@ config UML ...@@ -6,6 +6,7 @@ config UML
bool bool
default y default y
select ARCH_EPHEMERAL_INODES select ARCH_EPHEMERAL_INODES
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_KCOV select ARCH_HAS_KCOV
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UM_BUGS_H
#define __UM_BUGS_H
void check_bugs(void);
#endif
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/ */
#include <linux/cpu.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -430,7 +431,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -430,7 +431,7 @@ void __init setup_arch(char **cmdline_p)
} }
} }
void __init check_bugs(void) void __init arch_cpu_finalize_init(void)
{ {
arch_check_bugs(); arch_check_bugs();
os_check_bugs(); os_check_bugs();
......
...@@ -71,6 +71,7 @@ config X86 ...@@ -71,6 +71,7 @@ config X86
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_CACHE_LINE_SIZE select ARCH_HAS_CACHE_LINE_SIZE
select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_CURRENT_STACK_POINTER select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
#include <asm/processor.h> #include <asm/processor.h>
extern void check_bugs(void);
#if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32) #if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32)
int ppro_with_ram_bug(void); int ppro_with_ram_bug(void);
#else #else
......
...@@ -109,7 +109,7 @@ extern void fpu_reset_from_exception_fixup(void); ...@@ -109,7 +109,7 @@ extern void fpu_reset_from_exception_fixup(void);
/* Boot, hotplug and resume */ /* Boot, hotplug and resume */
extern void fpu__init_cpu(void); extern void fpu__init_cpu(void);
extern void fpu__init_system(struct cpuinfo_x86 *c); extern void fpu__init_system(void);
extern void fpu__init_check_bugs(void); extern void fpu__init_check_bugs(void);
extern void fpu__resume_cpu(void); extern void fpu__resume_cpu(void);
......
...@@ -17,6 +17,12 @@ ...@@ -17,6 +17,12 @@
#include <asm/bootparam.h> #include <asm/bootparam.h>
#ifdef CONFIG_X86_MEM_ENCRYPT
void __init mem_encrypt_init(void);
#else
static inline void mem_encrypt_init(void) { }
#endif
#ifdef CONFIG_AMD_MEM_ENCRYPT #ifdef CONFIG_AMD_MEM_ENCRYPT
extern u64 sme_me_mask; extern u64 sme_me_mask;
...@@ -87,9 +93,6 @@ static inline void mem_encrypt_free_decrypted_mem(void) { } ...@@ -87,9 +93,6 @@ static inline void mem_encrypt_free_decrypted_mem(void) { }
#endif /* CONFIG_AMD_MEM_ENCRYPT */ #endif /* CONFIG_AMD_MEM_ENCRYPT */
/* Architecture __weak replacement functions */
void __init mem_encrypt_init(void);
void add_encrypt_protection_map(void); void add_encrypt_protection_map(void);
/* /*
......
...@@ -85,6 +85,4 @@ struct rt_sigframe_x32 { ...@@ -85,6 +85,4 @@ struct rt_sigframe_x32 {
#endif /* CONFIG_X86_64 */ #endif /* CONFIG_X86_64 */
void __init init_sigframe_size(void);
#endif /* _ASM_X86_SIGFRAME_H */ #endif /* _ASM_X86_SIGFRAME_H */
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
* - Andrew D. Balsa (code cleanup). * - Andrew D. Balsa (code cleanup).
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/utsname.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/nospec.h> #include <linux/nospec.h>
...@@ -27,8 +26,6 @@ ...@@ -27,8 +26,6 @@
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/vmx.h> #include <asm/vmx.h>
#include <asm/paravirt.h> #include <asm/paravirt.h>
#include <asm/alternative.h>
#include <asm/set_memory.h>
#include <asm/intel-family.h> #include <asm/intel-family.h>
#include <asm/e820/api.h> #include <asm/e820/api.h>
#include <asm/hypervisor.h> #include <asm/hypervisor.h>
...@@ -125,21 +122,8 @@ DEFINE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); ...@@ -125,21 +122,8 @@ DEFINE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush);
DEFINE_STATIC_KEY_FALSE(mmio_stale_data_clear); DEFINE_STATIC_KEY_FALSE(mmio_stale_data_clear);
EXPORT_SYMBOL_GPL(mmio_stale_data_clear); EXPORT_SYMBOL_GPL(mmio_stale_data_clear);
void __init check_bugs(void) void __init cpu_select_mitigations(void)
{ {
identify_boot_cpu();
/*
* identify_boot_cpu() initialized SMT support information, let the
* core code know.
*/
cpu_smt_check_topology();
if (!IS_ENABLED(CONFIG_SMP)) {
pr_info("CPU: ");
print_cpu_info(&boot_cpu_data);
}
/* /*
* Read the SPEC_CTRL MSR to account for reserved bits which may * Read the SPEC_CTRL MSR to account for reserved bits which may
* have unknown values. AMD64_LS_CFG MSR is cached in the early AMD * have unknown values. AMD64_LS_CFG MSR is cached in the early AMD
...@@ -176,39 +160,6 @@ void __init check_bugs(void) ...@@ -176,39 +160,6 @@ void __init check_bugs(void)
md_clear_select_mitigation(); md_clear_select_mitigation();
srbds_select_mitigation(); srbds_select_mitigation();
l1d_flush_select_mitigation(); l1d_flush_select_mitigation();
arch_smt_update();
#ifdef CONFIG_X86_32
/*
* Check whether we are able to run this kernel safely on SMP.
*
* - i386 is no longer supported.
* - In order to run on anything without a TSC, we need to be
* compiled for a i486.
*/
if (boot_cpu_data.x86 < 4)
panic("Kernel requires i486+ for 'invlpg' and other features");
init_utsname()->machine[1] =
'0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
alternative_instructions();
fpu__init_check_bugs();
#else /* CONFIG_X86_64 */
alternative_instructions();
/*
* Make sure the first 2MB area is not mapped by huge pages
* There are typically fixed size MTRRs in there and overlapping
* MTRRs into large pages causes slow downs.
*
* Right now we don't do that with gbpages because there seems
* very little benefit for that case.
*/
if (!direct_gbpages)
set_memory_4k((unsigned long)__va(0), 1);
#endif
} }
/* /*
......
...@@ -18,12 +18,16 @@ ...@@ -18,12 +18,16 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <linux/kgdb.h> #include <linux/kgdb.h>
#include <linux/mem_encrypt.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/cpu.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/syscore_ops.h> #include <linux/syscore_ops.h>
#include <linux/pgtable.h> #include <linux/pgtable.h>
#include <linux/stackprotector.h> #include <linux/stackprotector.h>
#include <linux/utsname.h>
#include <asm/alternative.h>
#include <asm/cmdline.h> #include <asm/cmdline.h>
#include <asm/perf_event.h> #include <asm/perf_event.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
...@@ -59,7 +63,7 @@ ...@@ -59,7 +63,7 @@
#include <asm/intel-family.h> #include <asm/intel-family.h>
#include <asm/cpu_device_id.h> #include <asm/cpu_device_id.h>
#include <asm/uv/uv.h> #include <asm/uv/uv.h>
#include <asm/sigframe.h> #include <asm/set_memory.h>
#include <asm/traps.h> #include <asm/traps.h>
#include <asm/sev.h> #include <asm/sev.h>
...@@ -1600,10 +1604,6 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) ...@@ -1600,10 +1604,6 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
sld_setup(c); sld_setup(c);
fpu__init_system(c);
init_sigframe_size();
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
/* /*
* Regardless of whether PCID is enumerated, the SDM says * Regardless of whether PCID is enumerated, the SDM says
...@@ -2285,8 +2285,6 @@ void cpu_init(void) ...@@ -2285,8 +2285,6 @@ void cpu_init(void)
doublefault_init_cpu_tss(); doublefault_init_cpu_tss();
fpu__init_cpu();
if (is_uv_system()) if (is_uv_system())
uv_cpu_init(); uv_cpu_init();
...@@ -2302,6 +2300,7 @@ void cpu_init_secondary(void) ...@@ -2302,6 +2300,7 @@ void cpu_init_secondary(void)
*/ */
cpu_init_exception_handling(); cpu_init_exception_handling();
cpu_init(); cpu_init();
fpu__init_cpu();
} }
#endif #endif
...@@ -2362,3 +2361,69 @@ void arch_smt_update(void) ...@@ -2362,3 +2361,69 @@ void arch_smt_update(void)
/* Check whether IPI broadcasting can be enabled */ /* Check whether IPI broadcasting can be enabled */
apic_smt_update(); apic_smt_update();
} }
void __init arch_cpu_finalize_init(void)
{
identify_boot_cpu();
/*
* identify_boot_cpu() initialized SMT support information, let the
* core code know.
*/
cpu_smt_check_topology();
if (!IS_ENABLED(CONFIG_SMP)) {
pr_info("CPU: ");
print_cpu_info(&boot_cpu_data);
}
cpu_select_mitigations();
arch_smt_update();
if (IS_ENABLED(CONFIG_X86_32)) {
/*
* Check whether this is a real i386 which is not longer
* supported and fixup the utsname.
*/
if (boot_cpu_data.x86 < 4)
panic("Kernel requires i486+ for 'invlpg' and other features");
init_utsname()->machine[1] =
'0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
}
/*
* Must be before alternatives because it might set or clear
* feature bits.
*/
fpu__init_system();
fpu__init_cpu();
alternative_instructions();
if (IS_ENABLED(CONFIG_X86_64)) {
/*
* Make sure the first 2MB area is not mapped by huge pages
* There are typically fixed size MTRRs in there and overlapping
* MTRRs into large pages causes slow downs.
*
* Right now we don't do that with gbpages because there seems
* very little benefit for that case.
*/
if (!direct_gbpages)
set_memory_4k((unsigned long)__va(0), 1);
} else {
fpu__init_check_bugs();
}
/*
* This needs to be called before any devices perform DMA
* operations that might use the SWIOTLB bounce buffers. It will
* mark the bounce buffers as decrypted so that their usage will
* not cause "plain-text" data to be decrypted when accessed. It
* must be called after late_time_init() so that Hyper-V x86/x64
* hypercalls work when the SWIOTLB bounce buffers are decrypted.
*/
mem_encrypt_init();
}
...@@ -79,6 +79,7 @@ extern void detect_ht(struct cpuinfo_x86 *c); ...@@ -79,6 +79,7 @@ extern void detect_ht(struct cpuinfo_x86 *c);
extern void check_null_seg_clears_base(struct cpuinfo_x86 *c); extern void check_null_seg_clears_base(struct cpuinfo_x86 *c);
unsigned int aperfmperf_get_khz(int cpu); unsigned int aperfmperf_get_khz(int cpu);
void cpu_select_mitigations(void);
extern void x86_spec_ctrl_setup_ap(void); extern void x86_spec_ctrl_setup_ap(void);
extern void update_srbds_msr(void); extern void update_srbds_msr(void);
......
...@@ -53,7 +53,7 @@ void fpu__init_cpu(void) ...@@ -53,7 +53,7 @@ void fpu__init_cpu(void)
fpu__init_cpu_xstate(); fpu__init_cpu_xstate();
} }
static bool fpu__probe_without_cpuid(void) static bool __init fpu__probe_without_cpuid(void)
{ {
unsigned long cr0; unsigned long cr0;
u16 fsw, fcw; u16 fsw, fcw;
...@@ -71,7 +71,7 @@ static bool fpu__probe_without_cpuid(void) ...@@ -71,7 +71,7 @@ static bool fpu__probe_without_cpuid(void)
return fsw == 0 && (fcw & 0x103f) == 0x003f; return fsw == 0 && (fcw & 0x103f) == 0x003f;
} }
static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) static void __init fpu__init_system_early_generic(void)
{ {
if (!boot_cpu_has(X86_FEATURE_CPUID) && if (!boot_cpu_has(X86_FEATURE_CPUID) &&
!test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { !test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) {
...@@ -211,10 +211,10 @@ static void __init fpu__init_system_xstate_size_legacy(void) ...@@ -211,10 +211,10 @@ static void __init fpu__init_system_xstate_size_legacy(void)
* Called on the boot CPU once per system bootup, to set up the initial * Called on the boot CPU once per system bootup, to set up the initial
* FPU state that is later cloned into all processes: * FPU state that is later cloned into all processes:
*/ */
void __init fpu__init_system(struct cpuinfo_x86 *c) void __init fpu__init_system(void)
{ {
fpstate_reset(&current->thread.fpu); fpstate_reset(&current->thread.fpu);
fpu__init_system_early_generic(c); fpu__init_system_early_generic();
/* /*
* The FPU has to be operational for some of the * The FPU has to be operational for some of the
......
...@@ -182,7 +182,7 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size, ...@@ -182,7 +182,7 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size,
static unsigned long __ro_after_init max_frame_size; static unsigned long __ro_after_init max_frame_size;
static unsigned int __ro_after_init fpu_default_state_size; static unsigned int __ro_after_init fpu_default_state_size;
void __init init_sigframe_size(void) static int __init init_sigframe_size(void)
{ {
fpu_default_state_size = fpu__get_fpstate_size(); fpu_default_state_size = fpu__get_fpstate_size();
...@@ -194,7 +194,9 @@ void __init init_sigframe_size(void) ...@@ -194,7 +194,9 @@ void __init init_sigframe_size(void)
max_frame_size = round_up(max_frame_size, FRAME_ALIGNMENT); max_frame_size = round_up(max_frame_size, FRAME_ALIGNMENT);
pr_info("max sigframe size: %lu\n", max_frame_size); pr_info("max sigframe size: %lu\n", max_frame_size);
return 0;
} }
early_initcall(init_sigframe_size);
unsigned long get_sigframe_size(void) unsigned long get_sigframe_size(void)
{ {
......
/*
* include/asm-xtensa/bugs.h
*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Xtensa processors don't have any bugs. :)
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file "COPYING" in the main directory of
* this archive for more details.
*/
#ifndef _XTENSA_BUGS_H
#define _XTENSA_BUGS_H
static void check_bugs(void) { }
#endif /* _XTENSA_BUGS_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_GENERIC_BUGS_H
#define __ASM_GENERIC_BUGS_H
/*
* This file is included by 'init/main.c' to check for
* architecture-dependent bugs.
*/
static inline void check_bugs(void) { }
#endif /* __ASM_GENERIC_BUGS_H */
...@@ -184,6 +184,12 @@ void arch_cpu_idle_enter(void); ...@@ -184,6 +184,12 @@ void arch_cpu_idle_enter(void);
void arch_cpu_idle_exit(void); void arch_cpu_idle_exit(void);
void __noreturn arch_cpu_idle_dead(void); void __noreturn arch_cpu_idle_dead(void);
#ifdef CONFIG_ARCH_HAS_CPU_FINALIZE_INIT
void arch_cpu_finalize_init(void);
#else
static inline void arch_cpu_finalize_init(void) { }
#endif
int cpu_report_state(int cpu); int cpu_report_state(int cpu);
int cpu_check_up_prepare(int cpu); int cpu_check_up_prepare(int cpu);
void cpu_set_state_online(int cpu); void cpu_set_state_online(int cpu);
......
...@@ -95,7 +95,6 @@ ...@@ -95,7 +95,6 @@
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/rodata_test.h> #include <linux/rodata_test.h>
#include <linux/jump_label.h> #include <linux/jump_label.h>
#include <linux/mem_encrypt.h>
#include <linux/kcsan.h> #include <linux/kcsan.h>
#include <linux/init_syscalls.h> #include <linux/init_syscalls.h>
#include <linux/stackdepot.h> #include <linux/stackdepot.h>
...@@ -103,7 +102,6 @@ ...@@ -103,7 +102,6 @@
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/bugs.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
...@@ -787,8 +785,6 @@ void __init __weak thread_stack_cache_init(void) ...@@ -787,8 +785,6 @@ void __init __weak thread_stack_cache_init(void)
} }
#endif #endif
void __init __weak mem_encrypt_init(void) { }
void __init __weak poking_init(void) { } void __init __weak poking_init(void) { }
void __init __weak pgtable_cache_init(void) { } void __init __weak pgtable_cache_init(void) { }
...@@ -1042,15 +1038,7 @@ asmlinkage __visible void __init __no_sanitize_address __noreturn start_kernel(v ...@@ -1042,15 +1038,7 @@ asmlinkage __visible void __init __no_sanitize_address __noreturn start_kernel(v
sched_clock_init(); sched_clock_init();
calibrate_delay(); calibrate_delay();
/* arch_cpu_finalize_init();
* This needs to be called before any devices perform DMA
* operations that might use the SWIOTLB bounce buffers. It will
* mark the bounce buffers as decrypted so that their usage will
* not cause "plain-text" data to be decrypted when accessed. It
* must be called after late_time_init() so that Hyper-V x86/x64
* hypercalls work when the SWIOTLB bounce buffers are decrypted.
*/
mem_encrypt_init();
pid_idr_init(); pid_idr_init();
anon_vma_init(); anon_vma_init();
...@@ -1078,8 +1066,6 @@ asmlinkage __visible void __init __no_sanitize_address __noreturn start_kernel(v ...@@ -1078,8 +1066,6 @@ asmlinkage __visible void __init __no_sanitize_address __noreturn start_kernel(v
taskstats_init_early(); taskstats_init_early();
delayacct_init(); delayacct_init();
check_bugs();
acpi_subsystem_init(); acpi_subsystem_init();
arch_post_acpi_subsys_init(); arch_post_acpi_subsys_init();
kcsan_init(); kcsan_init();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment