kernel: Add errata patching for AMD "Zenbleed".

Part of #18525.

Change-Id: I6b5d73f6634d122dba13ad9544f340358ddef113
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6767
Reviewed-by: Jérôme Duval <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Augustin Cavalier
2023-08-02 15:27:07 +00:00
committed by waddlesplash
parent 26a211b054
commit 4ae33413f2
+31 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2019, Haiku, Inc. All rights reserved.
* Copyright 2019-2023, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -10,6 +10,28 @@
#include <arch_cpu.h>
static bool
needs_zenbleed_patch(const uint32 family, const uint32 model, const uint64 microcode)
{
if (family != 0x17)
return false;
// https://github.com/torvalds/linux/blob/522b1d6921/arch/x86/kernel/cpu/amd.c#L986
if (model >= 0x30 && model <= 0x3f)
return (microcode < 0x0830107a);
if (model >= 0x60 && model <= 0x67)
return (microcode < 0x0860010b);
if (model >= 0x68 && model <= 0x6f)
return (microcode < 0x08608105);
if (model >= 0x70 && model <= 0x7f)
return (microcode < 0x08701032);
if (model >= 0xa0 && model <= 0xaf)
return (microcode < 0x08a00008);
return false;
}
static status_t
patch_errata_percpu_amd(int currentCPU, const cpu_ent* cpu)
{
@@ -20,6 +42,7 @@ patch_errata_percpu_amd(int currentCPU, const cpu_ent* cpu)
const uint32 family = cpu->arch.family + cpu->arch.extended_family,
model = (cpu->arch.extended_model << 4) | cpu->arch.model;
const uint64 microcode = x86_read_msr(IA32_MSR_UCODE_REV);
// Family 10h and 12h, Erratum 721:
//
@@ -91,6 +114,13 @@ patch_errata_percpu_amd(int currentCPU, const cpu_ent* cpu)
x86_write_msr(0xc0011020, x86_read_msr(0xc0011020) | ((uint64)1 << 57));
}
// Family 17h ("Zen")
// Cross-Process Information Leak (aka. "Zenbleed")
// https://www.amd.com/en/resources/product-security/bulletin/amd-sb-7008.html
if (needs_zenbleed_patch(family, model, microcode)) {
x86_write_msr(MSR_F10H_DE_CFG, x86_read_msr(MSR_F10H_DE_CFG) | (1 << 9));
}
return B_OK;
}