Commit 042751d3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'x86-urgent-2025-03-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull misc x86 fixes from Ingo Molnar:

 - Fix CPUID leaf 0x2 parsing bugs

 - Sanitize very early boot parameters to avoid crash

 - Fix size overflows in the SGX code

 - Make CALL_NOSPEC use consistent

* tag 'x86-urgent-2025-03-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/boot: Sanitize boot params before parsing command line
  x86/sgx: Fix size overflows in sgx_encl_create()
  x86/cpu: Properly parse CPUID leaf 0x2 TLB descriptor 0x63
  x86/cpu: Validate CPUID leaf 0x2 EDX output
  x86/cacheinfo: Validate CPUID leaf 0x2 EDX output
  x86/speculation: Add a conditional CS prefix to CALL_NOSPEC
  x86/speculation: Simplify and make CALL_NOSPEC consistent
parents 8287dfc2 c00b413a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
#include "misc.h"
#include <asm/bootparam.h>
#include <asm/bootparam_utils.h>
#include <asm/e820/types.h>
#include <asm/processor.h>
#include "pgtable.h"
@@ -107,6 +108,7 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable)
	bool l5_required = false;

	/* Initialize boot_params. Required for cmdline_find_option_bool(). */
	sanitize_boot_params(bp);
	boot_params_ptr = bp;

	/*
+19 −13
Original line number Diff line number Diff line
@@ -198,9 +198,8 @@
.endm

/*
 * Equivalent to -mindirect-branch-cs-prefix; emit the 5 byte jmp/call
 * to the retpoline thunk with a CS prefix when the register requires
 * a RAX prefix byte to encode. Also see apply_retpolines().
 * Emits a conditional CS prefix that is compatible with
 * -mindirect-branch-cs-prefix.
 */
.macro __CS_PREFIX reg:req
	.irp rs,r8,r9,r10,r11,r12,r13,r14,r15
@@ -420,20 +419,27 @@ static inline void call_depth_return_thunk(void) {}

#ifdef CONFIG_X86_64

/*
 * Emits a conditional CS prefix that is compatible with
 * -mindirect-branch-cs-prefix.
 */
#define __CS_PREFIX(reg)				\
	".irp rs,r8,r9,r10,r11,r12,r13,r14,r15\n"	\
	".ifc \\rs," reg "\n"				\
	".byte 0x2e\n"					\
	".endif\n"					\
	".endr\n"

/*
 * Inline asm uses the %V modifier which is only in newer GCC
 * which is ensured when CONFIG_MITIGATION_RETPOLINE is defined.
 */
# define CALL_NOSPEC						\
	ALTERNATIVE_2(						\
	ANNOTATE_RETPOLINE_SAFE					\
	"call *%[thunk_target]\n",				\
	"call __x86_indirect_thunk_%V[thunk_target]\n",		\
	X86_FEATURE_RETPOLINE,					\
	"lfence;\n"						\
	ANNOTATE_RETPOLINE_SAFE					\
	"call *%[thunk_target]\n",				\
	X86_FEATURE_RETPOLINE_LFENCE)
#ifdef CONFIG_MITIGATION_RETPOLINE
#define CALL_NOSPEC	__CS_PREFIX("%V[thunk_target]")	\
			"call __x86_indirect_thunk_%V[thunk_target]\n"
#else
#define CALL_NOSPEC	"call *%[thunk_target]\n"
#endif

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

+1 −1
Original line number Diff line number Diff line
@@ -808,7 +808,7 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c)
			cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);

			/* If bit 31 is set, this is an unknown format */
			for (j = 0 ; j < 3 ; j++)
			for (j = 0 ; j < 4 ; j++)
				if (regs[j] & (1 << 31))
					regs[j] = 0;

+35 −17
Original line number Diff line number Diff line
@@ -648,6 +648,7 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
#define TLB_DATA_4K_4M		0x14

#define TLB_DATA_1G		0x16
#define TLB_DATA_1G_2M_4M	0x17

#define TLB_DATA0_4K		0x21
#define TLB_DATA0_4M		0x22
@@ -656,6 +657,16 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
#define STLB_4K			0x41
#define STLB_4K_2M		0x42

/*
 * All of leaf 0x2's one-byte TLB descriptors implies the same number of
 * entries for their respective TLB types.  The 0x63 descriptor is an
 * exception: it implies 4 dTLB entries for 1GB pages 32 dTLB entries
 * for 2MB or 4MB pages.  Encode descriptor 0x63 dTLB entry count for
 * 2MB/4MB pages here, as its count for dTLB 1GB pages is already at the
 * intel_tlb_table[] mapping.
 */
#define TLB_0x63_2M_4M_ENTRIES	32

static const struct _tlb_table intel_tlb_table[] = {
	{ 0x01, TLB_INST_4K,		32,	" TLB_INST 4 KByte pages, 4-way set associative" },
	{ 0x02, TLB_INST_4M,		2,	" TLB_INST 4 MByte pages, full associative" },
@@ -676,7 +687,8 @@ static const struct _tlb_table intel_tlb_table[] = {
	{ 0x5c, TLB_DATA_4K_4M,		128,	" TLB_DATA 4 KByte and 4 MByte pages" },
	{ 0x5d, TLB_DATA_4K_4M,		256,	" TLB_DATA 4 KByte and 4 MByte pages" },
	{ 0x61, TLB_INST_4K,		48,	" TLB_INST 4 KByte pages, full associative" },
	{ 0x63, TLB_DATA_1G,		4,	" TLB_DATA 1 GByte pages, 4-way set associative" },
	{ 0x63, TLB_DATA_1G_2M_4M,	4,	" TLB_DATA 1 GByte pages, 4-way set associative"
						" (plus 32 entries TLB_DATA 2 MByte or 4 MByte pages, not encoded here)" },
	{ 0x6b, TLB_DATA_4K,		256,	" TLB_DATA 4 KByte pages, 8-way associative" },
	{ 0x6c, TLB_DATA_2M_4M,		128,	" TLB_DATA 2 MByte or 4 MByte pages, 8-way associative" },
	{ 0x6d, TLB_DATA_1G,		16,	" TLB_DATA 1 GByte pages, fully associative" },
@@ -776,6 +788,12 @@ static void intel_tlb_lookup(const unsigned char desc)
		if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries)
			tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries;
		break;
	case TLB_DATA_1G_2M_4M:
		if (tlb_lld_2m[ENTRIES] < TLB_0x63_2M_4M_ENTRIES)
			tlb_lld_2m[ENTRIES] = TLB_0x63_2M_4M_ENTRIES;
		if (tlb_lld_4m[ENTRIES] < TLB_0x63_2M_4M_ENTRIES)
			tlb_lld_4m[ENTRIES] = TLB_0x63_2M_4M_ENTRIES;
		fallthrough;
	case TLB_DATA_1G:
		if (tlb_lld_1g[ENTRIES] < intel_tlb_table[k].entries)
			tlb_lld_1g[ENTRIES] = intel_tlb_table[k].entries;
@@ -799,7 +817,7 @@ static void intel_detect_tlb(struct cpuinfo_x86 *c)
		cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);

		/* If bit 31 is set, this is an unknown format */
		for (j = 0 ; j < 3 ; j++)
		for (j = 0 ; j < 4 ; j++)
			if (regs[j] & (1 << 31))
				regs[j] = 0;

+7 −0
Original line number Diff line number Diff line
@@ -64,6 +64,13 @@ static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs)
	struct file *backing;
	long ret;

	/*
	 * ECREATE would detect this too, but checking here also ensures
	 * that the 'encl_size' calculations below can never overflow.
	 */
	if (!is_power_of_2(secs->size))
		return -EINVAL;

	va_page = sgx_encl_grow(encl, true);
	if (IS_ERR(va_page))
		return PTR_ERR(va_page);