Commit 3088d269 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull misc x86 fixes from Ingo Molnar:

 - Fix hypercall detection on Xen guests

 - Extend the AMD microcode loader SHA check to Zen5, to block loading
   of any unreleased standalone Zen5 microcode patches

 - Add new Intel CPU model number for Bartlett Lake

 - Fix the workaround for AMD erratum 1054

 - Fix buggy early memory acceptance between SEV-SNP guests and the EFI
   stub

* tag 'x86-urgent-2025-04-18' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/boot/sev: Avoid shared GHCB page for early memory acceptance
  x86/cpu/amd: Fix workaround for erratum 1054
  x86/cpu: Add CPU model number for Bartlett Lake CPUs with Raptor Cove cores
  x86/microcode/AMD: Extend the SHA check to Zen5, block loading of any unreleased standalone Zen5 microcode patches
  x86/xen: Fix __xen_hypercall_setfunc()
parents ac85740e d54d6102
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -34,11 +34,14 @@ static bool early_is_tdx_guest(void)

void arch_accept_memory(phys_addr_t start, phys_addr_t end)
{
	static bool sevsnp;

	/* Platform-specific memory-acceptance call goes here */
	if (early_is_tdx_guest()) {
		if (!tdx_accept_memory(start, end))
			panic("TDX: Failed to accept memory\n");
	} else if (sev_snp_enabled()) {
	} else if (sevsnp || (sev_get_status() & MSR_AMD64_SEV_SNP_ENABLED)) {
		sevsnp = true;
		snp_accept_memory(start, end);
	} else {
		error("Cannot accept memory: unknown platform\n");
+15 −52
Original line number Diff line number Diff line
@@ -164,10 +164,7 @@ bool sev_snp_enabled(void)

static void __page_state_change(unsigned long paddr, enum psc_op op)
{
	u64 val;

	if (!sev_snp_enabled())
		return;
	u64 val, msr;

	/*
	 * If private -> shared then invalidate the page before requesting the
@@ -176,6 +173,9 @@ static void __page_state_change(unsigned long paddr, enum psc_op op)
	if (op == SNP_PAGE_STATE_SHARED)
		pvalidate_4k_page(paddr, paddr, false);

	/* Save the current GHCB MSR value */
	msr = sev_es_rd_ghcb_msr();

	/* Issue VMGEXIT to change the page state in RMP table. */
	sev_es_wr_ghcb_msr(GHCB_MSR_PSC_REQ_GFN(paddr >> PAGE_SHIFT, op));
	VMGEXIT();
@@ -185,6 +185,9 @@ static void __page_state_change(unsigned long paddr, enum psc_op op)
	if ((GHCB_RESP_CODE(val) != GHCB_MSR_PSC_RESP) || GHCB_MSR_PSC_RESP_VAL(val))
		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);

	/* Restore the GHCB MSR value */
	sev_es_wr_ghcb_msr(msr);

	/*
	 * Now that page state is changed in the RMP table, validate it so that it is
	 * consistent with the RMP entry.
@@ -195,11 +198,17 @@ static void __page_state_change(unsigned long paddr, enum psc_op op)

void snp_set_page_private(unsigned long paddr)
{
	if (!sev_snp_enabled())
		return;

	__page_state_change(paddr, SNP_PAGE_STATE_PRIVATE);
}

void snp_set_page_shared(unsigned long paddr)
{
	if (!sev_snp_enabled())
		return;

	__page_state_change(paddr, SNP_PAGE_STATE_SHARED);
}

@@ -223,56 +232,10 @@ static bool early_setup_ghcb(void)
	return true;
}

static phys_addr_t __snp_accept_memory(struct snp_psc_desc *desc,
				       phys_addr_t pa, phys_addr_t pa_end)
{
	struct psc_hdr *hdr;
	struct psc_entry *e;
	unsigned int i;

	hdr = &desc->hdr;
	memset(hdr, 0, sizeof(*hdr));

	e = desc->entries;

	i = 0;
	while (pa < pa_end && i < VMGEXIT_PSC_MAX_ENTRY) {
		hdr->end_entry = i;

		e->gfn = pa >> PAGE_SHIFT;
		e->operation = SNP_PAGE_STATE_PRIVATE;
		if (IS_ALIGNED(pa, PMD_SIZE) && (pa_end - pa) >= PMD_SIZE) {
			e->pagesize = RMP_PG_SIZE_2M;
			pa += PMD_SIZE;
		} else {
			e->pagesize = RMP_PG_SIZE_4K;
			pa += PAGE_SIZE;
		}

		e++;
		i++;
	}

	if (vmgexit_psc(boot_ghcb, desc))
		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);

	pvalidate_pages(desc);

	return pa;
}

void snp_accept_memory(phys_addr_t start, phys_addr_t end)
{
	struct snp_psc_desc desc = {};
	unsigned int i;
	phys_addr_t pa;

	if (!boot_ghcb && !early_setup_ghcb())
		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);

	pa = start;
	while (pa < end)
		pa = __snp_accept_memory(&desc, pa, end);
	for (phys_addr_t pa = start; pa < end; pa += PAGE_SIZE)
		__page_state_change(pa, SNP_PAGE_STATE_PRIVATE);
}

void sev_es_shutdown_ghcb(void)
+2 −0
Original line number Diff line number Diff line
@@ -12,11 +12,13 @@

bool sev_snp_enabled(void);
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
u64 sev_get_status(void);

#else

static inline bool sev_snp_enabled(void) { return false; }
static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
static inline u64 sev_get_status(void) { return 0; }

#endif

+2 −0
Original line number Diff line number Diff line
@@ -126,6 +126,8 @@
#define INTEL_GRANITERAPIDS_X		IFM(6, 0xAD) /* Redwood Cove */
#define INTEL_GRANITERAPIDS_D		IFM(6, 0xAE)

#define INTEL_BARTLETTLAKE		IFM(6, 0xD7) /* Raptor Cove */

/* "Hybrid" Processors (P-Core/E-Core) */

#define INTEL_LAKEFIELD			IFM(6, 0x8A) /* Sunny Cove / Tremont */
+12 −7
Original line number Diff line number Diff line
@@ -869,6 +869,16 @@ static void init_amd_zen1(struct cpuinfo_x86 *c)

	pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n");
	setup_force_cpu_bug(X86_BUG_DIV0);

	/*
	 * Turn off the Instructions Retired free counter on machines that are
	 * susceptible to erratum #1054 "Instructions Retired Performance
	 * Counter May Be Inaccurate".
	 */
	if (c->x86_model < 0x30) {
		msr_clear_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT);
		clear_cpu_cap(c, X86_FEATURE_IRPERF);
	}
}

static bool cpu_has_zenbleed_microcode(void)
@@ -1052,13 +1062,8 @@ static void init_amd(struct cpuinfo_x86 *c)
	if (!cpu_feature_enabled(X86_FEATURE_XENPV))
		set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);

	/*
	 * Turn on the Instructions Retired free counter on machines not
	 * susceptible to erratum #1054 "Instructions Retired Performance
	 * Counter May Be Inaccurate".
	 */
	if (cpu_has(c, X86_FEATURE_IRPERF) &&
	    (boot_cpu_has(X86_FEATURE_ZEN1) && c->x86_model > 0x2f))
	/* Enable the Instructions Retired free counter */
	if (cpu_has(c, X86_FEATURE_IRPERF))
		msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT);

	check_null_seg_clears_base(c);
Loading