Skip to content

Commit 846e751

Browse files
jithu83jwrdegoede
authored andcommitted
platform/x86/intel/ifs: Check IFS Image sanity
IFS image is designed specifically for a given family, model and stepping of the processor. Like Intel microcode header, the IFS image has the Processor Signature, Checksum and Processor Flags that must be matched with the information returned by the CPUID. Reviewed-by: Dan Williams <[email protected]> Signed-off-by: Jithu Joseph <[email protected]> Co-developed-by: Tony Luck <[email protected]> Signed-off-by: Tony Luck <[email protected]> Acked-by: Hans de Goede <[email protected]> Reviewed-by: Greg Kroah-Hartman <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Hans de Goede <[email protected]>
1 parent fb57fc7 commit 846e751

File tree

1 file changed

+66
-0
lines changed
  • drivers/platform/x86/intel/ifs

1 file changed

+66
-0
lines changed

drivers/platform/x86/intel/ifs/load.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,72 @@
22
/* Copyright(c) 2022 Intel Corporation. */
33

44
#include <linux/firmware.h>
5+
#include <asm/cpu.h>
6+
#include <asm/microcode_intel.h>
57

68
#include "ifs.h"
79

10+
static int ifs_sanity_check(struct device *dev,
11+
const struct microcode_header_intel *mc_header)
12+
{
13+
unsigned long total_size, data_size;
14+
u32 sum, *mc;
15+
16+
total_size = get_totalsize(mc_header);
17+
data_size = get_datasize(mc_header);
18+
19+
if ((data_size + MC_HEADER_SIZE > total_size) || (total_size % sizeof(u32))) {
20+
dev_err(dev, "bad ifs data file size.\n");
21+
return -EINVAL;
22+
}
23+
24+
if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
25+
dev_err(dev, "invalid/unknown ifs update format.\n");
26+
return -EINVAL;
27+
}
28+
29+
mc = (u32 *)mc_header;
30+
sum = 0;
31+
for (int i = 0; i < total_size / sizeof(u32); i++)
32+
sum += mc[i];
33+
34+
if (sum) {
35+
dev_err(dev, "bad ifs data checksum, aborting.\n");
36+
return -EINVAL;
37+
}
38+
39+
return 0;
40+
}
41+
42+
static bool find_ifs_matching_signature(struct device *dev, struct ucode_cpu_info *uci,
43+
const struct microcode_header_intel *shdr)
44+
{
45+
unsigned int mc_size;
46+
47+
mc_size = get_totalsize(shdr);
48+
49+
if (!mc_size || ifs_sanity_check(dev, shdr) < 0) {
50+
dev_err(dev, "ifs sanity check failure\n");
51+
return false;
52+
}
53+
54+
if (!intel_cpu_signatures_match(uci->cpu_sig.sig, uci->cpu_sig.pf, shdr->sig, shdr->pf)) {
55+
dev_err(dev, "ifs signature, pf not matching\n");
56+
return false;
57+
}
58+
59+
return true;
60+
}
61+
62+
static bool ifs_image_sanity_check(struct device *dev, const struct microcode_header_intel *data)
63+
{
64+
struct ucode_cpu_info uci;
65+
66+
intel_cpu_collect_info(&uci);
67+
68+
return find_ifs_matching_signature(dev, &uci, data);
69+
}
70+
871
/*
972
* Load ifs image. Before loading ifs module, the ifs image must be located
1073
* in /lib/firmware/intel/ifs and named as {family/model/stepping}.{testname}.
@@ -24,5 +87,8 @@ void ifs_load_firmware(struct device *dev)
2487
return;
2588
}
2689

90+
if (!ifs_image_sanity_check(dev, (struct microcode_header_intel *)fw->data))
91+
dev_err(dev, "ifs header sanity check failed\n");
92+
2793
release_firmware(fw);
2894
}

0 commit comments

Comments
 (0)