Skip to content

Commit 4fb858f

Browse files
jithu83suryasaimadhu
authored andcommitted
platform/x86/intel/ifs: Add current_batch sysfs entry
Initial implementation assumed a single IFS test image file with a fixed name ff-mm-ss.scan. (where ff, mm, ss refers to family, model and stepping of the core). Subsequently, it became evident that supporting more than one test image file is needed to provide more comprehensive test coverage. (Test coverage in this scenario refers to testing more transistors in the core to identify faults). The other alternative of increasing the size of a single scan test image file would not work as the upper bound is limited by the size of memory area reserved by BIOS for loading IFS test image. Introduce "current_batch" file which accepts a number. Writing a number to the current_batch file would load the test image file by name ff-mm-ss-<xy>.scan, where <xy> is the number written to the "current_batch" file in hex. Range check of the input is done to verify it not greater than 0xff. For e.g if the scan test image comprises of 6 files, they would be named: 06-8f-06-01.scan 06-8f-06-02.scan 06-8f-06-03.scan 06-8f-06-04.scan 06-8f-06-05.scan 06-8f-06-06.scan And writing 3 to current_batch would result in loading 06-8f-06-03.scan above. The file can also be read to know the currently loaded file. And testing a system looks like: for each scan file do load the IFS test image file (write to the batch file) for each core do test the core with this set of tests done done Qualify few error messages with the test image file suffix to provide better context. [ bp: Massage commit message. Add link to the discussion. ] Signed-off-by: Jithu Joseph <jithu.joseph@intel.com> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Tony Luck <tony.luck@intel.com> Reviewed-by: Sohil Mehta <sohil.mehta@intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Link: https://lore.kernel.org/r/20221107225323.2733518-13-jithu.joseph@intel.com
1 parent bf835ee commit 4fb858f

File tree

5 files changed

+74
-16
lines changed

5 files changed

+74
-16
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids);
2323
static struct ifs_device ifs_device = {
2424
.data = {
2525
.integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT,
26+
.test_num = 0,
2627
},
2728
.misc = {
2829
.name = "intel_ifs_0",

drivers/platform/x86/intel/ifs/ifs.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,23 @@
3333
* The driver loads the tests into memory reserved BIOS local to each CPU
3434
* socket in a two step process using writes to MSRs to first load the
3535
* SHA hashes for the test. Then the tests themselves. Status MSRs provide
36-
* feedback on the success/failure of these steps. When a new test file
37-
* is installed it can be loaded by writing to the driver reload file::
36+
* feedback on the success/failure of these steps.
3837
*
39-
* # echo 1 > /sys/devices/virtual/misc/intel_ifs_0/reload
38+
* The test files are kept in a fixed location: /lib/firmware/intel/ifs_0/
39+
* For e.g if there are 3 test files, they would be named in the following
40+
* fashion:
41+
* ff-mm-ss-01.scan
42+
* ff-mm-ss-02.scan
43+
* ff-mm-ss-03.scan
44+
* (where ff refers to family, mm indicates model and ss indicates stepping)
4045
*
41-
* Similar to microcode, the current version of the scan tests is stored
42-
* in a fixed location: /lib/firmware/intel/ifs.0/family-model-stepping.scan
46+
* A different test file can be loaded by writing the numerical portion
47+
* (e.g 1, 2 or 3 in the above scenario) into the curent_batch file.
48+
* To load ff-mm-ss-02.scan, the following command can be used::
49+
*
50+
* # echo 2 > /sys/devices/virtual/misc/intel_ifs_0/current_batch
51+
*
52+
* The above file can also be read to know the currently loaded image.
4353
*
4454
* Running tests
4555
* -------------
@@ -209,6 +219,7 @@ struct ifs_data {
209219
int status;
210220
u64 scan_details;
211221
u32 cur_batch;
222+
int test_num;
212223
};
213224

214225
struct ifs_work {
@@ -229,7 +240,7 @@ static inline struct ifs_data *ifs_get_data(struct device *dev)
229240
return &d->data;
230241
}
231242

232-
void ifs_load_firmware(struct device *dev);
243+
int ifs_load_firmware(struct device *dev);
233244
int do_core_test(int cpu, struct device *dev);
234245
const struct attribute_group **ifs_get_groups(void);
235246

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -253,17 +253,18 @@ static int image_sanity_check(struct device *dev, const struct microcode_header_
253253

254254
/*
255255
* Load ifs image. Before loading ifs module, the ifs image must be located
256-
* in /lib/firmware/intel/ifs and named as {family/model/stepping}.{testname}.
256+
* in /lib/firmware/intel/ifs_x/ and named as family-model-stepping-02x.{testname}.
257257
*/
258-
void ifs_load_firmware(struct device *dev)
258+
int ifs_load_firmware(struct device *dev)
259259
{
260260
struct ifs_data *ifsd = ifs_get_data(dev);
261261
const struct firmware *fw;
262-
char scan_path[32];
263-
int ret;
262+
char scan_path[64];
263+
int ret = -EINVAL;
264264

265-
snprintf(scan_path, sizeof(scan_path), "intel/ifs/%02x-%02x-%02x.scan",
266-
boot_cpu_data.x86, boot_cpu_data.x86_model, boot_cpu_data.x86_stepping);
265+
snprintf(scan_path, sizeof(scan_path), "intel/ifs_%d/%02x-%02x-%02x-%02x.scan",
266+
ifsd->test_num, boot_cpu_data.x86, boot_cpu_data.x86_model,
267+
boot_cpu_data.x86_stepping, ifsd->cur_batch);
267268

268269
ret = request_firmware_direct(&fw, scan_path, dev);
269270
if (ret) {
@@ -279,8 +280,13 @@ void ifs_load_firmware(struct device *dev)
279280
ifs_hash_ptr = (u64)(ifs_header_ptr + 1);
280281

281282
ret = scan_chunks_sanity_check(dev);
283+
if (ret)
284+
dev_err(dev, "Load failure for batch: %02x\n", ifsd->cur_batch);
285+
282286
release:
283287
release_firmware(fw);
284288
done:
285289
ifsd->loaded = (ret == 0);
290+
291+
return ret;
286292
}

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,16 @@ static void message_not_tested(struct device *dev, int cpu, union ifs_status sta
7878

7979
static void message_fail(struct device *dev, int cpu, union ifs_status status)
8080
{
81+
struct ifs_data *ifsd = ifs_get_data(dev);
82+
8183
/*
8284
* control_error is set when the microcode runs into a problem
8385
* loading the image from the reserved BIOS memory, or it has
8486
* been corrupted. Reloading the image may fix this issue.
8587
*/
8688
if (status.control_error) {
87-
dev_err(dev, "CPU(s) %*pbl: could not execute from loaded scan image\n",
88-
cpumask_pr_args(cpu_smt_mask(cpu)));
89+
dev_err(dev, "CPU(s) %*pbl: could not execute from loaded scan image. Batch: %02x version: 0x%x\n",
90+
cpumask_pr_args(cpu_smt_mask(cpu)), ifsd->cur_batch, ifsd->loaded_version);
8991
}
9092

9193
/*
@@ -96,8 +98,8 @@ static void message_fail(struct device *dev, int cpu, union ifs_status status)
9698
* the core being tested.
9799
*/
98100
if (status.signature_error) {
99-
dev_err(dev, "CPU(s) %*pbl: test signature incorrect.\n",
100-
cpumask_pr_args(cpu_smt_mask(cpu)));
101+
dev_err(dev, "CPU(s) %*pbl: test signature incorrect. Batch: %02x version: 0x%x\n",
102+
cpumask_pr_args(cpu_smt_mask(cpu)), ifsd->cur_batch, ifsd->loaded_version);
101103
}
102104
}
103105

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,43 @@ static ssize_t run_test_store(struct device *dev,
8787

8888
static DEVICE_ATTR_WO(run_test);
8989

90+
static ssize_t current_batch_store(struct device *dev,
91+
struct device_attribute *attr,
92+
const char *buf, size_t count)
93+
{
94+
struct ifs_data *ifsd = ifs_get_data(dev);
95+
unsigned int cur_batch;
96+
int rc;
97+
98+
rc = kstrtouint(buf, 0, &cur_batch);
99+
if (rc < 0 || cur_batch > 0xff)
100+
return -EINVAL;
101+
102+
if (down_interruptible(&ifs_sem))
103+
return -EINTR;
104+
105+
ifsd->cur_batch = cur_batch;
106+
107+
rc = ifs_load_firmware(dev);
108+
109+
up(&ifs_sem);
110+
111+
return (rc == 0) ? count : rc;
112+
}
113+
114+
static ssize_t current_batch_show(struct device *dev,
115+
struct device_attribute *attr, char *buf)
116+
{
117+
struct ifs_data *ifsd = ifs_get_data(dev);
118+
119+
if (!ifsd->loaded)
120+
return sysfs_emit(buf, "none\n");
121+
else
122+
return sysfs_emit(buf, "0x%02x\n", ifsd->cur_batch);
123+
}
124+
125+
static DEVICE_ATTR_RW(current_batch);
126+
90127
/*
91128
* Display currently loaded IFS image version.
92129
*/
@@ -108,6 +145,7 @@ static struct attribute *plat_ifs_attrs[] = {
108145
&dev_attr_details.attr,
109146
&dev_attr_status.attr,
110147
&dev_attr_run_test.attr,
148+
&dev_attr_current_batch.attr,
111149
&dev_attr_image_version.attr,
112150
NULL
113151
};

0 commit comments

Comments
 (0)