mirror of
https://github.com/openbsd/src.git
synced 2026-04-30 00:56:33 +00:00
revert changes to handle newer amd microcode
mlarkin reports this leads to a crash in pmap_randomize_level/memcpy on EPYC 7773X
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ucode.c,v 1.11 2025/11/25 00:01:24 jsg Exp $ */
|
||||
/* $OpenBSD: ucode.c,v 1.12 2025/11/25 04:17:04 jsg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018 Stefan Fritsch <fritsch@genua.de>
|
||||
* Copyright (c) 2018 Patrick Wildt <patrick@blueri.se>
|
||||
@@ -129,26 +129,21 @@ struct amd_equiv {
|
||||
struct amd_patch {
|
||||
uint32_t type;
|
||||
uint32_t len;
|
||||
uint32_t date;
|
||||
uint32_t a;
|
||||
uint32_t level;
|
||||
uint16_t data_id;
|
||||
uint8_t data_len;
|
||||
uint8_t flag;
|
||||
uint32_t data_val;
|
||||
uint32_t nb_dev;
|
||||
uint32_t sb_dev;
|
||||
uint8_t c[16];
|
||||
uint16_t eid;
|
||||
} __packed;
|
||||
|
||||
void
|
||||
cpu_ucode_amd_apply(struct cpu_info *ci)
|
||||
{
|
||||
uint64_t cur_level;
|
||||
uint64_t level;
|
||||
uint32_t magic, tlen, i;
|
||||
uint16_t eid = 0;
|
||||
uint32_t sig, ebx, ecx, edx;
|
||||
uint64_t start = 0;
|
||||
uint32_t patch_len = 0, new_level = 0;
|
||||
uint32_t patch_len = 0;
|
||||
|
||||
if (cpu_ucode_data == NULL || cpu_ucode_size == 0) {
|
||||
DPRINTF(("%s: no microcode provided\n", __func__));
|
||||
@@ -163,8 +158,8 @@ cpu_ucode_amd_apply(struct cpu_info *ci)
|
||||
|
||||
CPUID(1, sig, ebx, ecx, edx);
|
||||
|
||||
cur_level = rdmsr(MSR_PATCH_LEVEL);
|
||||
DPRINTF(("%s: cur patch level 0x%llx\n", __func__, cur_level));
|
||||
level = rdmsr(MSR_PATCH_LEVEL);
|
||||
DPRINTF(("%s: cur patch level 0x%llx\n", __func__, level));
|
||||
|
||||
memcpy(&magic, cpu_ucode_data, 4);
|
||||
if (magic != AMD_MAGIC) {
|
||||
@@ -187,10 +182,7 @@ cpu_ucode_amd_apply(struct cpu_info *ci)
|
||||
eid = ae.eid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for newer patch with the equivalence id. There can be
|
||||
* multiple patches for a given equivalence id.
|
||||
*/
|
||||
/* look for newer patch with the equivalence id */
|
||||
while (i < cpu_ucode_size) {
|
||||
struct amd_patch ap;
|
||||
if (i + sizeof(ap) > cpu_ucode_size) {
|
||||
@@ -198,18 +190,9 @@ cpu_ucode_amd_apply(struct cpu_info *ci)
|
||||
goto out;
|
||||
}
|
||||
memcpy(&ap, &cpu_ucode_data[i], sizeof(ap));
|
||||
if (ap.type == 1 && ap.eid == eid && ap.level > cur_level &&
|
||||
ap.level > new_level) {
|
||||
|
||||
/* check minimum version for fam >= 0x19 */
|
||||
if (ci->ci_family < 0x19 || cur_level >= ap.data_val) {
|
||||
start = (uint64_t)&cpu_ucode_data[i + 8];
|
||||
new_level = ap.level;
|
||||
patch_len = ap.len;
|
||||
} else {
|
||||
DPRINTF(("%s: ucode %#llx < min %#x\n",
|
||||
__func__, cur_level, ap.data_val));
|
||||
}
|
||||
if (ap.type == 1 && ap.eid == eid && ap.level > level) {
|
||||
start = (uint64_t)&cpu_ucode_data[i + 8];
|
||||
patch_len = ap.len;
|
||||
}
|
||||
if (i + ap.len + 8 > cpu_ucode_size) {
|
||||
DPRINTF(("%s: truncated patch\n", __func__));
|
||||
@@ -226,8 +209,8 @@ cpu_ucode_amd_apply(struct cpu_info *ci)
|
||||
memcpy(p, (uint8_t *)start, patch_len);
|
||||
start = (uint64_t)p;
|
||||
wrmsr(MSR_PATCH_LOADER, start);
|
||||
cur_level = rdmsr(MSR_PATCH_LEVEL);
|
||||
DPRINTF(("%s: new patch level 0x%llx\n", __func__, cur_level));
|
||||
level = rdmsr(MSR_PATCH_LEVEL);
|
||||
DPRINTF(("%s: new patch level 0x%llx\n", __func__, level));
|
||||
free(p, M_TEMP, patch_len);
|
||||
}
|
||||
out:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ucode.c,v 1.8 2025/11/25 00:01:24 jsg Exp $ */
|
||||
/* $OpenBSD: ucode.c,v 1.9 2025/11/25 04:17:04 jsg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018 Stefan Fritsch <fritsch@genua.de>
|
||||
* Copyright (c) 2018 Patrick Wildt <patrick@blueri.se>
|
||||
@@ -152,26 +152,21 @@ struct amd_equiv {
|
||||
struct amd_patch {
|
||||
uint32_t type;
|
||||
uint32_t len;
|
||||
uint32_t date;
|
||||
uint32_t a;
|
||||
uint32_t level;
|
||||
uint16_t data_id;
|
||||
uint8_t data_len;
|
||||
uint8_t flag;
|
||||
uint32_t data_val;
|
||||
uint32_t nb_dev;
|
||||
uint32_t sb_dev;
|
||||
uint8_t c[16];
|
||||
uint16_t eid;
|
||||
} __packed;
|
||||
|
||||
void
|
||||
cpu_ucode_amd_apply(struct cpu_info *ci)
|
||||
{
|
||||
uint64_t cur_level;
|
||||
uint64_t level;
|
||||
uint32_t magic, tlen, i;
|
||||
uint16_t eid = 0;
|
||||
uint32_t sig, ebx, ecx, edx;
|
||||
uint64_t start = 0;
|
||||
uint32_t patch_len = 0, new_level = 0;
|
||||
uint32_t patch_len = 0;
|
||||
|
||||
if (cpu_ucode_data == NULL || cpu_ucode_size == 0) {
|
||||
DPRINTF(("%s: no microcode provided\n", __func__));
|
||||
@@ -186,8 +181,8 @@ cpu_ucode_amd_apply(struct cpu_info *ci)
|
||||
|
||||
CPUID(1, sig, ebx, ecx, edx);
|
||||
|
||||
cur_level = rdmsr(MSR_PATCH_LEVEL);
|
||||
DPRINTF(("%s: cur patch level 0x%llx\n", __func__, cur_level));
|
||||
level = rdmsr(MSR_PATCH_LEVEL);
|
||||
DPRINTF(("%s: cur patch level 0x%llx\n", __func__, level));
|
||||
|
||||
memcpy(&magic, cpu_ucode_data, 4);
|
||||
if (magic != AMD_MAGIC) {
|
||||
@@ -210,10 +205,7 @@ cpu_ucode_amd_apply(struct cpu_info *ci)
|
||||
eid = ae.eid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for newer patch with the equivalence id. There can be
|
||||
* multiple patches for a given equivalence id.
|
||||
*/
|
||||
/* look for newer patch with the equivalence id */
|
||||
while (i < cpu_ucode_size) {
|
||||
struct amd_patch ap;
|
||||
if (i + sizeof(ap) > cpu_ucode_size) {
|
||||
@@ -221,18 +213,9 @@ cpu_ucode_amd_apply(struct cpu_info *ci)
|
||||
goto out;
|
||||
}
|
||||
memcpy(&ap, &cpu_ucode_data[i], sizeof(ap));
|
||||
if (ap.type == 1 && ap.eid == eid && ap.level > cur_level &&
|
||||
ap.level > new_level) {
|
||||
|
||||
/* check minimum version for fam >= 0x19 */
|
||||
if (ci->ci_family < 0x19 || cur_level >= ap.data_val) {
|
||||
start = (uint64_t)&cpu_ucode_data[i + 8];
|
||||
new_level = ap.level;
|
||||
patch_len = ap.len;
|
||||
} else {
|
||||
DPRINTF(("%s: ucode %#llx < min %#x\n",
|
||||
__func__, cur_level, ap.data_val));
|
||||
}
|
||||
if (ap.type == 1 && ap.eid == eid && ap.level > level) {
|
||||
start = (uint64_t)&cpu_ucode_data[i + 8];
|
||||
patch_len = ap.len;
|
||||
}
|
||||
if (i + ap.len + 8 > cpu_ucode_size) {
|
||||
DPRINTF(("%s: truncated patch\n", __func__));
|
||||
@@ -249,8 +232,8 @@ cpu_ucode_amd_apply(struct cpu_info *ci)
|
||||
memcpy(p, (uint8_t *)start, patch_len);
|
||||
start = (uint64_t)p;
|
||||
wrmsr(MSR_PATCH_LOADER, start);
|
||||
cur_level = rdmsr(MSR_PATCH_LEVEL);
|
||||
DPRINTF(("%s: new patch level 0x%llx\n", __func__, cur_level));
|
||||
level = rdmsr(MSR_PATCH_LEVEL);
|
||||
DPRINTF(("%s: new patch level 0x%llx\n", __func__, level));
|
||||
free(p, M_TEMP, patch_len);
|
||||
}
|
||||
out:
|
||||
|
||||
Reference in New Issue
Block a user