Commit 0a23fb26 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'x86_microcode_for_v6.7_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 microcode loading updates from Borislac Petkov:
 "Major microcode loader restructuring, cleanup and improvements by
  Thomas Gleixner:

   - Restructure the code needed for it and add a temporary initrd
     mapping on 32-bit so that the loader can access the microcode
     blobs. This in itself is a preparation for the next major
     improvement:

   - Do not load microcode on 32-bit before paging has been enabled.

     Handling this has caused an endless stream of headaches, issues,
     ugly code and unnecessary hacks in the past. And there really
     wasn't any sensible reason to do that in the first place. So switch
     the 32-bit loading to happen after paging has been enabled and turn
     the loader code "real purrty" again

   - Drop mixed microcode steppings loading on Intel - there, a single
     patch loaded on the whole system is sufficient

   - Rework late loading to track which CPUs have updated microcode
     successfully and which haven't, act accordingly

   - Move late microcode loading on Intel in NMI context in order to
     guarantee concurrent loading on all threads

   - Make the late loading CPU-hotplug-safe and have the offlined
     threads be woken up for the purpose of the update

   - Add support for a minimum revision which determines whether late
     microcode loading is safe on a machine and the microcode does not
     change software visible features which the machine cannot use
     anyway since feature detection has happened already. Roughly, the
     minimum revision is the smallest revision number which must be
     loaded currently on the system so that late updates can be allowed

   - Other nice leanups, fixess, etc all over the place"

* tag 'x86_microcode_for_v6.7_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (40 commits)
  x86/microcode/intel: Add a minimum required revision for late loading
  x86/microcode: Prepare for minimal revision check
  x86/microcode: Handle "offline" CPUs correctly
  x86/apic: Provide apic_force_nmi_on_cpu()
  x86/microcode: Protect against instrumentation
  x86/microcode: Rendezvous and load in NMI
  x86/microcode: Replace the all-in-one rendevous handler
  x86/microcode: Provide new control functions
  x86/microcode: Add per CPU control field
  x86/microcode: Add per CPU result state
  x86/microcode: Sanitize __wait_for_cpus()
  x86/microcode: Clarify the late load logic
  x86/microcode: Handle "nosmt" correctly
  x86/microcode: Clean up mc_cpu_down_prep()
  x86/microcode: Get rid of the schedule work indirection
  x86/microcode: Mop up early loading leftovers
  x86/microcode/amd: Use cached microcode for AP load
  x86/microcode/amd: Cache builtin/initrd microcode early
  x86/microcode/amd: Cache builtin microcode too
  x86/microcode/amd: Use correct per CPU ucode_cpu_info
  ...
parents 5c5e048b cf5ab01c
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -3333,6 +3333,11 @@

	mga=		[HW,DRM]

	microcode.force_minrev=	[X86]
			Format: <bool>
			Enable or disable the microcode minimal revision
			enforcement for the runtime microcode loader.

	min_addr=nn[KMG]	[KNL,BOOT,IA-64] All physical memory below this
			physical address is ignored.

+27 −2
Original line number Diff line number Diff line
@@ -1313,16 +1313,41 @@ config MICROCODE
	def_bool y
	depends on CPU_SUP_AMD || CPU_SUP_INTEL

config MICROCODE_INITRD32
	def_bool y
	depends on MICROCODE && X86_32 && BLK_DEV_INITRD

config MICROCODE_LATE_LOADING
	bool "Late microcode loading (DANGEROUS)"
	default n
	depends on MICROCODE
	depends on MICROCODE && SMP
	help
	  Loading microcode late, when the system is up and executing instructions
	  is a tricky business and should be avoided if possible. Just the sequence
	  of synchronizing all cores and SMT threads is one fragile dance which does
	  not guarantee that cores might not softlock after the loading. Therefore,
	  use this at your own risk. Late loading taints the kernel too.
	  use this at your own risk. Late loading taints the kernel unless the
	  microcode header indicates that it is safe for late loading via the
	  minimal revision check. This minimal revision check can be enforced on
	  the kernel command line with "microcode.minrev=Y".

config MICROCODE_LATE_FORCE_MINREV
	bool "Enforce late microcode loading minimal revision check"
	default n
	depends on MICROCODE_LATE_LOADING
	help
	  To prevent that users load microcode late which modifies already
	  in use features, newer microcode patches have a minimum revision field
	  in the microcode header, which tells the kernel which minimum
	  revision must be active in the CPU to safely load that new microcode
	  late into the running system. If disabled the check will not
	  be enforced but the kernel will be tainted when the minimal
	  revision check fails.

	  This minimal revision check can also be controlled via the
	  "microcode.minrev" parameter on the kernel command line.

	  If unsure say Y.

config X86_MSR
	tristate "/dev/cpu/*/msr - Model-specific register support"
+4 −1
Original line number Diff line number Diff line
@@ -276,7 +276,8 @@ struct apic {

	u32	disable_esr		: 1,
		dest_mode_logical	: 1,
		x2apic_set_max_apicid	: 1;
		x2apic_set_max_apicid	: 1,
		nmi_to_offline_cpu	: 1;

	u32	(*calc_dest_apicid)(unsigned int cpu);

@@ -531,6 +532,8 @@ extern u32 apic_flat_calc_apicid(unsigned int cpu);
extern void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap);
extern u32 default_cpu_present_to_apicid(int mps_cpu);

void apic_send_nmi_to_offline_cpu(unsigned int cpu);

#else /* CONFIG_X86_LOCAL_APIC */

static inline u32 read_apic_id(void) { return 0; }
+3 −17
Original line number Diff line number Diff line
@@ -71,26 +71,12 @@ static inline void init_ia32_feat_ctl(struct cpuinfo_x86 *c) {}

extern __noendbr void cet_disable(void);

struct ucode_cpu_info;
struct cpu_signature;

int intel_cpu_collect_info(struct ucode_cpu_info *uci);

static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1,
					      unsigned int s2, unsigned int p2)
{
	if (s1 != s2)
		return false;

	/* Processor flags are either both 0 ... */
	if (!p1 && !p2)
		return true;

	/* ... or they intersect. */
	return p1 & p2;
}
void intel_collect_cpu_info(struct cpu_signature *sig);

extern u64 x86_read_arch_cap_msr(void);
int intel_find_matching_signature(void *mc, unsigned int csig, int cpf);
bool intel_find_matching_signature(void *mc, struct cpu_signature *sig);
int intel_microcode_sanity_check(void *mc, bool print_err, int hdr_type);

extern struct cpumask cpus_stop_mask;
+16 −5
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ static inline void load_ucode_ap(void) { }
static inline void microcode_bsp_resume(void) { }
#endif

extern unsigned long initrd_start_early;

#ifdef CONFIG_CPU_SUP_INTEL
/* Intel specific microcode defines. Public for IFS */
struct microcode_header_intel {
@@ -36,7 +38,8 @@ struct microcode_header_intel {
	unsigned int	datasize;
	unsigned int	totalsize;
	unsigned int	metasize;
	unsigned int	reserved[2];
	unsigned int	min_req_ver;
	unsigned int	reserved;
};

struct microcode_intel {
@@ -68,11 +71,19 @@ static inline u32 intel_get_microcode_revision(void)

	return rev;
}
#endif /* !CONFIG_CPU_SUP_INTEL */

void show_ucode_info_early(void);
bool microcode_nmi_handler(void);
void microcode_offline_nmi_handler(void);

#else /* CONFIG_CPU_SUP_INTEL */
static inline void show_ucode_info_early(void) { }
#endif /* !CONFIG_CPU_SUP_INTEL */
#ifdef CONFIG_MICROCODE_LATE_LOADING
DECLARE_STATIC_KEY_FALSE(microcode_nmi_handler_enable);
static __always_inline bool microcode_nmi_handler_enabled(void)
{
	return static_branch_unlikely(&microcode_nmi_handler_enable);
}
#else
static __always_inline bool microcode_nmi_handler_enabled(void) { return false; }
#endif

#endif /* _ASM_X86_MICROCODE_H */
Loading