Skip to content

Commit a70210f

Browse files
committed
Merge tag 'x86_microcode_for_v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 microcode and IFS updates from Borislav Petkov: "The IFS (In-Field Scan) stuff goes through tip because the IFS driver uses the same structures and similar functionality as the microcode loader and it made sense to route it all through this branch so that there are no conflicts. - Add support for multiple testing sequences to the Intel In-Field Scan driver in order to be able to run multiple different test patterns. Rework things and remove the BROKEN dependency so that the driver can be enabled (Jithu Joseph) - Remove the subsys interface usage in the microcode loader because it is not really needed - A couple of smaller fixes and cleanups" * tag 'x86_microcode_for_v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits) x86/microcode/intel: Do not retry microcode reloading on the APs x86/microcode/intel: Do not print microcode revision and processor flags platform/x86/intel/ifs: Add missing kernel-doc entry Revert "platform/x86/intel/ifs: Mark as BROKEN" Documentation/ABI: Update IFS ABI doc platform/x86/intel/ifs: Add current_batch sysfs entry platform/x86/intel/ifs: Remove reload sysfs entry platform/x86/intel/ifs: Add metadata validation platform/x86/intel/ifs: Use generic microcode headers and functions platform/x86/intel/ifs: Add metadata support x86/microcode/intel: Use a reserved field for metasize x86/microcode/intel: Add hdr_type to intel_microcode_sanity_check() x86/microcode/intel: Reuse microcode_sanity_check() x86/microcode/intel: Use appropriate type in microcode_sanity_check() x86/microcode/intel: Reuse find_matching_signature() platform/x86/intel/ifs: Remove memory allocation from load path platform/x86/intel/ifs: Remove image loading during init platform/x86/intel/ifs: Return a more appropriate error code platform/x86/intel/ifs: Remove unused selection x86/microcode: Drop struct ucode_cpu_info.valid ...
2 parents 3ef3ace + be1b670 commit a70210f

File tree

14 files changed

+410
-476
lines changed

14 files changed

+410
-476
lines changed
Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,41 @@
11
What: /sys/devices/virtual/misc/intel_ifs_<N>/run_test
2-
Date: April 21 2022
3-
KernelVersion: 5.19
2+
Date: Nov 16 2022
3+
KernelVersion: 6.2
44
Contact: "Jithu Joseph" <[email protected]>
55
Description: Write <cpu#> to trigger IFS test for one online core.
66
Note that the test is per core. The cpu# can be
77
for any thread on the core. Running on one thread
88
completes the test for the core containing that thread.
99
Example: to test the core containing cpu5: echo 5 >
10-
/sys/devices/platform/intel_ifs.<N>/run_test
10+
/sys/devices/virtual/misc/intel_ifs_<N>/run_test
1111

1212
What: /sys/devices/virtual/misc/intel_ifs_<N>/status
13-
Date: April 21 2022
14-
KernelVersion: 5.19
13+
Date: Nov 16 2022
14+
KernelVersion: 6.2
1515
Contact: "Jithu Joseph" <[email protected]>
1616
Description: The status of the last test. It can be one of "pass", "fail"
1717
or "untested".
1818

1919
What: /sys/devices/virtual/misc/intel_ifs_<N>/details
20-
Date: April 21 2022
21-
KernelVersion: 5.19
20+
Date: Nov 16 2022
21+
KernelVersion: 6.2
2222
Contact: "Jithu Joseph" <[email protected]>
2323
Description: Additional information regarding the last test. The details file reports
2424
the hex value of the SCAN_STATUS MSR. Note that the error_code field
2525
may contain driver defined software code not defined in the Intel SDM.
2626

2727
What: /sys/devices/virtual/misc/intel_ifs_<N>/image_version
28-
Date: April 21 2022
29-
KernelVersion: 5.19
28+
Date: Nov 16 2022
29+
KernelVersion: 6.2
3030
Contact: "Jithu Joseph" <[email protected]>
3131
Description: Version (hexadecimal) of loaded IFS binary image. If no scan image
3232
is loaded reports "none".
3333

34-
What: /sys/devices/virtual/misc/intel_ifs_<N>/reload
35-
Date: April 21 2022
36-
KernelVersion: 5.19
34+
What: /sys/devices/virtual/misc/intel_ifs_<N>/current_batch
35+
Date: Nov 16 2022
36+
KernelVersion: 6.2
3737
Contact: "Jithu Joseph" <[email protected]>
38-
Description: Write "1" (or "y" or "Y") to reload the IFS image from
39-
/lib/firmware/intel/ifs/ff-mm-ss.scan.
38+
Description: Write a number less than or equal to 0xff to load an IFS test image.
39+
The number written treated as the 2 digit suffix in the following file name:
40+
/lib/firmware/intel/ifs_<N>/ff-mm-ss-02x.scan
41+
Reading the file will provide the suffix of the currently loaded IFS test image.

arch/x86/include/asm/cpu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,7 @@ static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1,
9595
}
9696

9797
extern u64 x86_read_arch_cap_msr(void);
98+
int intel_find_matching_signature(void *mc, unsigned int csig, int cpf);
99+
int intel_microcode_sanity_check(void *mc, bool print_err, int hdr_type);
98100

99101
#endif /* _ASM_X86_CPU_H */

arch/x86/include/asm/microcode.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ enum ucode_state {
3333
};
3434

3535
struct microcode_ops {
36-
enum ucode_state (*request_microcode_fw) (int cpu, struct device *,
37-
bool refresh_fw);
36+
enum ucode_state (*request_microcode_fw) (int cpu, struct device *);
3837

3938
void (*microcode_fini_cpu) (int cpu);
4039

@@ -50,7 +49,6 @@ struct microcode_ops {
5049

5150
struct ucode_cpu_info {
5251
struct cpu_signature cpu_sig;
53-
int valid;
5452
void *mc;
5553
};
5654
extern struct ucode_cpu_info ucode_cpu_info[];

arch/x86/include/asm/microcode_intel.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ struct microcode_header_intel {
1414
unsigned int pf;
1515
unsigned int datasize;
1616
unsigned int totalsize;
17-
unsigned int reserved[3];
17+
unsigned int metasize;
18+
unsigned int reserved[2];
1819
};
1920

2021
struct microcode_intel {
@@ -41,6 +42,8 @@ struct extended_sigtable {
4142
#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
4243
#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable))
4344
#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature))
45+
#define MC_HEADER_TYPE_MICROCODE 1
46+
#define MC_HEADER_TYPE_IFS 2
4447

4548
#define get_totalsize(mc) \
4649
(((struct microcode_intel *)mc)->hdr.datasize ? \

arch/x86/kernel/cpu/intel.c

Lines changed: 143 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,154 @@ int intel_cpu_collect_info(struct ucode_cpu_info *uci)
210210
csig.rev = intel_get_microcode_revision();
211211

212212
uci->cpu_sig = csig;
213-
uci->valid = 1;
214213

215214
return 0;
216215
}
217216
EXPORT_SYMBOL_GPL(intel_cpu_collect_info);
218217

218+
/*
219+
* Returns 1 if update has been found, 0 otherwise.
220+
*/
221+
int intel_find_matching_signature(void *mc, unsigned int csig, int cpf)
222+
{
223+
struct microcode_header_intel *mc_hdr = mc;
224+
struct extended_sigtable *ext_hdr;
225+
struct extended_signature *ext_sig;
226+
int i;
227+
228+
if (intel_cpu_signatures_match(csig, cpf, mc_hdr->sig, mc_hdr->pf))
229+
return 1;
230+
231+
/* Look for ext. headers: */
232+
if (get_totalsize(mc_hdr) <= get_datasize(mc_hdr) + MC_HEADER_SIZE)
233+
return 0;
234+
235+
ext_hdr = mc + get_datasize(mc_hdr) + MC_HEADER_SIZE;
236+
ext_sig = (void *)ext_hdr + EXT_HEADER_SIZE;
237+
238+
for (i = 0; i < ext_hdr->count; i++) {
239+
if (intel_cpu_signatures_match(csig, cpf, ext_sig->sig, ext_sig->pf))
240+
return 1;
241+
ext_sig++;
242+
}
243+
return 0;
244+
}
245+
EXPORT_SYMBOL_GPL(intel_find_matching_signature);
246+
247+
/**
248+
* intel_microcode_sanity_check() - Sanity check microcode file.
249+
* @mc: Pointer to the microcode file contents.
250+
* @print_err: Display failure reason if true, silent if false.
251+
* @hdr_type: Type of file, i.e. normal microcode file or In Field Scan file.
252+
* Validate if the microcode header type matches with the type
253+
* specified here.
254+
*
255+
* Validate certain header fields and verify if computed checksum matches
256+
* with the one specified in the header.
257+
*
258+
* Return: 0 if the file passes all the checks, -EINVAL if any of the checks
259+
* fail.
260+
*/
261+
int intel_microcode_sanity_check(void *mc, bool print_err, int hdr_type)
262+
{
263+
unsigned long total_size, data_size, ext_table_size;
264+
struct microcode_header_intel *mc_header = mc;
265+
struct extended_sigtable *ext_header = NULL;
266+
u32 sum, orig_sum, ext_sigcount = 0, i;
267+
struct extended_signature *ext_sig;
268+
269+
total_size = get_totalsize(mc_header);
270+
data_size = get_datasize(mc_header);
271+
272+
if (data_size + MC_HEADER_SIZE > total_size) {
273+
if (print_err)
274+
pr_err("Error: bad microcode data file size.\n");
275+
return -EINVAL;
276+
}
277+
278+
if (mc_header->ldrver != 1 || mc_header->hdrver != hdr_type) {
279+
if (print_err)
280+
pr_err("Error: invalid/unknown microcode update format. Header type %d\n",
281+
mc_header->hdrver);
282+
return -EINVAL;
283+
}
284+
285+
ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
286+
if (ext_table_size) {
287+
u32 ext_table_sum = 0;
288+
u32 *ext_tablep;
289+
290+
if (ext_table_size < EXT_HEADER_SIZE ||
291+
((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
292+
if (print_err)
293+
pr_err("Error: truncated extended signature table.\n");
294+
return -EINVAL;
295+
}
296+
297+
ext_header = mc + MC_HEADER_SIZE + data_size;
298+
if (ext_table_size != exttable_size(ext_header)) {
299+
if (print_err)
300+
pr_err("Error: extended signature table size mismatch.\n");
301+
return -EFAULT;
302+
}
303+
304+
ext_sigcount = ext_header->count;
305+
306+
/*
307+
* Check extended table checksum: the sum of all dwords that
308+
* comprise a valid table must be 0.
309+
*/
310+
ext_tablep = (u32 *)ext_header;
311+
312+
i = ext_table_size / sizeof(u32);
313+
while (i--)
314+
ext_table_sum += ext_tablep[i];
315+
316+
if (ext_table_sum) {
317+
if (print_err)
318+
pr_warn("Bad extended signature table checksum, aborting.\n");
319+
return -EINVAL;
320+
}
321+
}
322+
323+
/*
324+
* Calculate the checksum of update data and header. The checksum of
325+
* valid update data and header including the extended signature table
326+
* must be 0.
327+
*/
328+
orig_sum = 0;
329+
i = (MC_HEADER_SIZE + data_size) / sizeof(u32);
330+
while (i--)
331+
orig_sum += ((u32 *)mc)[i];
332+
333+
if (orig_sum) {
334+
if (print_err)
335+
pr_err("Bad microcode data checksum, aborting.\n");
336+
return -EINVAL;
337+
}
338+
339+
if (!ext_table_size)
340+
return 0;
341+
342+
/*
343+
* Check extended signature checksum: 0 => valid.
344+
*/
345+
for (i = 0; i < ext_sigcount; i++) {
346+
ext_sig = (void *)ext_header + EXT_HEADER_SIZE +
347+
EXT_SIGNATURE_SIZE * i;
348+
349+
sum = (mc_header->sig + mc_header->pf + mc_header->cksum) -
350+
(ext_sig->sig + ext_sig->pf + ext_sig->cksum);
351+
if (sum) {
352+
if (print_err)
353+
pr_err("Bad extended signature checksum, aborting.\n");
354+
return -EINVAL;
355+
}
356+
}
357+
return 0;
358+
}
359+
EXPORT_SYMBOL_GPL(intel_microcode_sanity_check);
360+
219361
static void early_init_intel(struct cpuinfo_x86 *c)
220362
{
221363
u64 misc_enable;

arch/x86/kernel/cpu/microcode/amd.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -901,8 +901,7 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
901901
*
902902
* These might be larger than 2K.
903903
*/
904-
static enum ucode_state request_microcode_amd(int cpu, struct device *device,
905-
bool refresh_fw)
904+
static enum ucode_state request_microcode_amd(int cpu, struct device *device)
906905
{
907906
char fw_name[36] = "amd-ucode/microcode_amd.bin";
908907
struct cpuinfo_x86 *c = &cpu_data(cpu);
@@ -911,7 +910,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
911910
const struct firmware *fw;
912911

913912
/* reload ucode container only on the boot cpu */
914-
if (!refresh_fw || !bsp)
913+
if (!bsp)
915914
return UCODE_OK;
916915

917916
if (c->x86 >= 0x15)

0 commit comments

Comments
 (0)