]> Git Repo - J-linux.git/blob - drivers/platform/x86/intel/ifs/ifs.h
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / platform / x86 / intel / ifs / ifs.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /* Copyright(c) 2022 Intel Corporation. */
3
4 #ifndef _IFS_H_
5 #define _IFS_H_
6
7 /**
8  * DOC: In-Field Scan
9  *
10  * =============
11  * In-Field Scan
12  * =============
13  *
14  * Introduction
15  * ------------
16  *
17  * In Field Scan (IFS) is a hardware feature to run circuit level tests on
18  * a CPU core to detect problems that are not caught by parity or ECC checks.
19  * Future CPUs will support more than one type of test which will show up
20  * with a new platform-device instance-id.
21  *
22  *
23  * IFS Image
24  * ---------
25  *
26  * Intel provides a firmware file containing the scan tests via
27  * github [#f1]_.  Similar to microcode there is a separate file for each
28  * family-model-stepping. IFS Images are not applicable for some test types.
29  * Wherever applicable the sysfs directory would provide a "current_batch" file
30  * (see below) for loading the image.
31  *
32  *
33  * IFS Image Loading
34  * -----------------
35  *
36  * The driver loads the tests into memory reserved BIOS local to each CPU
37  * socket in a two step process using writes to MSRs to first load the
38  * SHA hashes for the test. Then the tests themselves. Status MSRs provide
39  * feedback on the success/failure of these steps.
40  *
41  * The test files are kept in a fixed location: /lib/firmware/intel/ifs_<n>/
42  * For e.g if there are 3 test files, they would be named in the following
43  * fashion:
44  * ff-mm-ss-01.scan
45  * ff-mm-ss-02.scan
46  * ff-mm-ss-03.scan
47  * (where ff refers to family, mm indicates model and ss indicates stepping)
48  *
49  * A different test file can be loaded by writing the numerical portion
50  * (e.g 1, 2 or 3 in the above scenario) into the curent_batch file.
51  * To load ff-mm-ss-02.scan, the following command can be used::
52  *
53  *   # echo 2 > /sys/devices/virtual/misc/intel_ifs_<n>/current_batch
54  *
55  * The above file can also be read to know the currently loaded image.
56  *
57  * Running tests
58  * -------------
59  *
60  * Tests are run by the driver synchronizing execution of all threads on a
61  * core and then writing to the ACTIVATE_SCAN MSR on all threads. Instruction
62  * execution continues when:
63  *
64  * 1) All tests have completed.
65  * 2) Execution was interrupted.
66  * 3) A test detected a problem.
67  *
68  * Note that ALL THREADS ON THE CORE ARE EFFECTIVELY OFFLINE FOR THE
69  * DURATION OF THE TEST. This can be up to 200 milliseconds. If the system
70  * is running latency sensitive applications that cannot tolerate an
71  * interruption of this magnitude, the system administrator must arrange
72  * to migrate those applications to other cores before running a core test.
73  * It may also be necessary to redirect interrupts to other CPUs.
74  *
75  * In all cases reading the corresponding test's STATUS MSR provides details on what
76  * happened. The driver makes the value of this MSR visible to applications
77  * via the "details" file (see below). Interrupted tests may be restarted.
78  *
79  * The IFS driver provides sysfs interfaces via /sys/devices/virtual/misc/intel_ifs_<n>/
80  * to control execution:
81  *
82  * Test a specific core::
83  *
84  *   # echo <cpu#> > /sys/devices/virtual/misc/intel_ifs_<n>/run_test
85  *
86  * when HT is enabled any of the sibling cpu# can be specified to test
87  * its corresponding physical core. Since the tests are per physical core,
88  * the result of testing any thread is same. All siblings must be online
89  * to run a core test. It is only necessary to test one thread.
90  *
91  * For e.g. to test core corresponding to cpu5
92  *
93  *   # echo 5 > /sys/devices/virtual/misc/intel_ifs_<n>/run_test
94  *
95  * Results of the last test is provided in /sys::
96  *
97  *   $ cat /sys/devices/virtual/misc/intel_ifs_<n>/status
98  *   pass
99  *
100  * Status can be one of pass, fail, untested
101  *
102  * Additional details of the last test is provided by the details file::
103  *
104  *   $ cat /sys/devices/virtual/misc/intel_ifs_<n>/details
105  *   0x8081
106  *
107  * The details file reports the hex value of the test specific status MSR.
108  * Hardware defined error codes are documented in volume 4 of the Intel
109  * Software Developer's Manual but the error_code field may contain one of
110  * the following driver defined software codes:
111  *
112  * +------+--------------------+
113  * | 0xFD | Software timeout   |
114  * +------+--------------------+
115  * | 0xFE | Partial completion |
116  * +------+--------------------+
117  *
118  * Driver design choices
119  * ---------------------
120  *
121  * 1) The ACTIVATE_SCAN MSR allows for running any consecutive subrange of
122  * available tests. But the driver always tries to run all tests and only
123  * uses the subrange feature to restart an interrupted test.
124  *
125  * 2) Hardware allows for some number of cores to be tested in parallel.
126  * The driver does not make use of this, it only tests one core at a time.
127  *
128  * .. [#f1] https://github.com/intel/TBD
129  *
130  *
131  * Structural Based Functional Test at Field (SBAF):
132  * -------------------------------------------------
133  *
134  * SBAF is a new type of testing that provides comprehensive core test
135  * coverage complementing Scan at Field (SAF) testing. SBAF mimics the
136  * manufacturing screening environment and leverages the same test suite.
137  * It makes use of Design For Test (DFT) observation sites and features
138  * to maximize coverage in minimum time.
139  *
140  * Similar to the SAF test, SBAF isolates the core under test from the
141  * rest of the system during execution. Upon completion, the core
142  * seamlessly resets to its pre-test state and resumes normal operation.
143  * Any machine checks or hangs encountered during the test are confined to
144  * the isolated core, preventing disruption to the overall system.
145  *
146  * Like the SAF test, the SBAF test is also divided into multiple batches,
147  * and each batch test can take hundreds of milliseconds (100-200 ms) to
148  * complete. If such a lengthy interruption is undesirable, it is
149  * recommended to relocate the time-sensitive applications to other cores.
150  */
151 #include <linux/device.h>
152 #include <linux/miscdevice.h>
153
154 #define MSR_ARRAY_BIST                          0x00000105
155
156 #define MSR_COPY_SBAF_HASHES                    0x000002b8
157 #define MSR_SBAF_HASHES_STATUS                  0x000002b9
158 #define MSR_AUTHENTICATE_AND_COPY_SBAF_CHUNK    0x000002ba
159 #define MSR_SBAF_CHUNKS_AUTHENTICATION_STATUS   0x000002bb
160 #define MSR_ACTIVATE_SBAF                       0x000002bc
161 #define MSR_SBAF_STATUS                         0x000002bd
162
163 #define MSR_COPY_SCAN_HASHES                    0x000002c2
164 #define MSR_SCAN_HASHES_STATUS                  0x000002c3
165 #define MSR_AUTHENTICATE_AND_COPY_CHUNK         0x000002c4
166 #define MSR_CHUNKS_AUTHENTICATION_STATUS        0x000002c5
167 #define MSR_ACTIVATE_SCAN                       0x000002c6
168 #define MSR_SCAN_STATUS                         0x000002c7
169 #define MSR_ARRAY_TRIGGER                       0x000002d6
170 #define MSR_ARRAY_STATUS                        0x000002d7
171 #define MSR_SAF_CTRL                            0x000004f0
172 #define MSR_SBAF_CTRL                           0x000004f8
173
174 #define SCAN_NOT_TESTED                         0
175 #define SCAN_TEST_PASS                          1
176 #define SCAN_TEST_FAIL                          2
177
178 #define IFS_TYPE_SAF                    0
179 #define IFS_TYPE_ARRAY_BIST             1
180 #define IFS_TYPE_SBAF                   2
181
182 #define ARRAY_GEN0                      0
183 #define ARRAY_GEN1                      1
184
185 /* MSR_SCAN_HASHES_STATUS bit fields */
186 union ifs_scan_hashes_status {
187         u64     data;
188         struct {
189                 u32     chunk_size      :16;
190                 u32     num_chunks      :8;
191                 u32     rsvd1           :8;
192                 u32     error_code      :8;
193                 u32     rsvd2           :11;
194                 u32     max_core_limit  :12;
195                 u32     valid           :1;
196         };
197 };
198
199 union ifs_scan_hashes_status_gen2 {
200         u64     data;
201         struct {
202                 u16     chunk_size;
203                 u16     num_chunks;
204                 u32     error_code              :8;
205                 u32     chunks_in_stride        :9;
206                 u32     rsvd                    :2;
207                 u32     max_core_limit          :12;
208                 u32     valid                   :1;
209         };
210 };
211
212 /* MSR_CHUNKS_AUTH_STATUS bit fields */
213 union ifs_chunks_auth_status {
214         u64     data;
215         struct {
216                 u32     valid_chunks    :8;
217                 u32     total_chunks    :8;
218                 u32     rsvd1           :16;
219                 u32     error_code      :8;
220                 u32     rsvd2           :24;
221         };
222 };
223
224 union ifs_chunks_auth_status_gen2 {
225         u64     data;
226         struct {
227                 u16     valid_chunks;
228                 u16     total_chunks;
229                 u32     error_code      :8;
230                 u32     rsvd2           :8;
231                 u32     max_bundle      :16;
232         };
233 };
234
235 /* MSR_ACTIVATE_SCAN bit fields */
236 union ifs_scan {
237         u64     data;
238         struct {
239                 union {
240                         struct {
241                                 u8      start;
242                                 u8      stop;
243                                 u16     rsvd;
244                         } gen0;
245                         struct {
246                                 u16     start;
247                                 u16     stop;
248                         } gen2;
249                 };
250                 u32     delay   :31;
251                 u32     sigmce  :1;
252         };
253 };
254
255 /* MSR_SCAN_STATUS bit fields */
256 union ifs_status {
257         u64     data;
258         struct {
259                 union {
260                         struct {
261                                 u8      chunk_num;
262                                 u8      chunk_stop_index;
263                                 u16     rsvd1;
264                         } gen0;
265                         struct {
266                                 u16     chunk_num;
267                                 u16     chunk_stop_index;
268                         } gen2;
269                 };
270                 u32     error_code              :8;
271                 u32     rsvd2                   :22;
272                 u32     control_error           :1;
273                 u32     signature_error         :1;
274         };
275 };
276
277 /* MSR_ARRAY_BIST bit fields */
278 union ifs_array {
279         u64     data;
280         struct {
281                 u32     array_bitmask;
282                 u16     array_bank;
283                 u16     rsvd                    :15;
284                 u16     ctrl_result             :1;
285         };
286 };
287
288 /* MSR_ACTIVATE_SBAF bit fields */
289 union ifs_sbaf {
290         u64     data;
291         struct {
292                 u32     bundle_idx      :9;
293                 u32     rsvd1           :5;
294                 u32     pgm_idx         :2;
295                 u32     rsvd2           :16;
296                 u32     delay           :31;
297                 u32     sigmce          :1;
298         };
299 };
300
301 /* MSR_SBAF_STATUS bit fields */
302 union ifs_sbaf_status {
303         u64     data;
304         struct {
305                 u32     bundle_idx      :9;
306                 u32     rsvd1           :5;
307                 u32     pgm_idx         :2;
308                 u32     rsvd2           :16;
309                 u32     error_code      :8;
310                 u32     rsvd3           :21;
311                 u32     test_fail       :1;
312                 u32     sbaf_status     :2;
313         };
314 };
315
316 /*
317  * Driver populated error-codes
318  * 0xFD: Test timed out before completing all the chunks.
319  * 0xFE: not all scan chunks were executed. Maximum forward progress retries exceeded.
320  */
321 #define IFS_SW_TIMEOUT                          0xFD
322 #define IFS_SW_PARTIAL_COMPLETION               0xFE
323
324 #define IFS_SUFFIX_SZ           5
325
326 struct ifs_test_caps {
327         int     integrity_cap_bit;
328         int     test_num;
329         char    image_suffix[IFS_SUFFIX_SZ];
330 };
331
332 /**
333  * struct ifs_test_msrs - MSRs used in IFS tests
334  * @copy_hashes: Copy test hash data
335  * @copy_hashes_status: Status of copied test hash data
336  * @copy_chunks: Copy chunks of the test data
337  * @copy_chunks_status: Status of the copied test data chunks
338  * @test_ctrl: Control the test attributes
339  */
340 struct ifs_test_msrs {
341         u32     copy_hashes;
342         u32     copy_hashes_status;
343         u32     copy_chunks;
344         u32     copy_chunks_status;
345         u32     test_ctrl;
346 };
347
348 /**
349  * struct ifs_data - attributes related to intel IFS driver
350  * @loaded_version: stores the currently loaded ifs image version.
351  * @loaded: If a valid test binary has been loaded into the memory
352  * @loading_error: Error occurred on another CPU while loading image
353  * @valid_chunks: number of chunks which could be validated.
354  * @status: it holds simple status pass/fail/untested
355  * @scan_details: opaque scan status code from h/w
356  * @cur_batch: number indicating the currently loaded test file
357  * @generation: IFS test generation enumerated by hardware
358  * @chunk_size: size of a test chunk
359  * @array_gen: test generation of array test
360  * @max_bundle: maximum bundle index
361  */
362 struct ifs_data {
363         int     loaded_version;
364         bool    loaded;
365         bool    loading_error;
366         int     valid_chunks;
367         int     status;
368         u64     scan_details;
369         u32     cur_batch;
370         u32     generation;
371         u32     chunk_size;
372         u32     array_gen;
373         u32     max_bundle;
374 };
375
376 struct ifs_work {
377         struct work_struct w;
378         struct device *dev;
379 };
380
381 struct ifs_device {
382         const struct ifs_test_caps *test_caps;
383         const struct ifs_test_msrs *test_msrs;
384         struct ifs_data rw_data;
385         struct miscdevice misc;
386 };
387
388 static inline struct ifs_data *ifs_get_data(struct device *dev)
389 {
390         struct miscdevice *m = dev_get_drvdata(dev);
391         struct ifs_device *d = container_of(m, struct ifs_device, misc);
392
393         return &d->rw_data;
394 }
395
396 static inline const struct ifs_test_caps *ifs_get_test_caps(struct device *dev)
397 {
398         struct miscdevice *m = dev_get_drvdata(dev);
399         struct ifs_device *d = container_of(m, struct ifs_device, misc);
400
401         return d->test_caps;
402 }
403
404 static inline const struct ifs_test_msrs *ifs_get_test_msrs(struct device *dev)
405 {
406         struct miscdevice *m = dev_get_drvdata(dev);
407         struct ifs_device *d = container_of(m, struct ifs_device, misc);
408
409         return d->test_msrs;
410 }
411
412 extern bool *ifs_pkg_auth;
413 int ifs_load_firmware(struct device *dev);
414 int do_core_test(int cpu, struct device *dev);
415 extern struct attribute *plat_ifs_attrs[];
416 extern struct attribute *plat_ifs_array_attrs[];
417
418 #endif
This page took 0.049856 seconds and 4 git commands to generate.