test_firmware: prevent race conditions by a correct implementation of locking
[linux-block.git] / lib / test_firmware.c
CommitLineData
09c434b8 1// SPDX-License-Identifier: GPL-2.0-only
0a8adf58
KC
2/*
3 * This module provides an interface to trigger and test firmware loading.
4 *
5 * It is designed to be used for basic evaluation of the firmware loading
6 * subsystem (for example when validating firmware verification). It lacks
7 * any extra dependencies, and will not normally be loaded by the system
8 * unless explicitly requested by name.
9 */
10
11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/printk.h>
eb910947 16#include <linux/completion.h>
0a8adf58
KC
17#include <linux/firmware.h>
18#include <linux/device.h>
19#include <linux/fs.h>
20#include <linux/miscdevice.h>
7feebfa4 21#include <linux/sizes.h>
0a8adf58
KC
22#include <linux/slab.h>
23#include <linux/uaccess.h>
c92316bf 24#include <linux/delay.h>
f7d85515 25#include <linux/kstrtox.h>
c92316bf 26#include <linux/kthread.h>
514c6032 27#include <linux/vmalloc.h>
548193cb 28#include <linux/efi_embedded_fw.h>
c92316bf 29
baaabecf
KC
30MODULE_IMPORT_NS(TEST_FIRMWARE);
31
c92316bf
LR
32#define TEST_FIRMWARE_NAME "test-firmware.bin"
33#define TEST_FIRMWARE_NUM_REQS 4
7feebfa4 34#define TEST_FIRMWARE_BUF_SIZE SZ_1K
a31ad463
RW
35#define TEST_UPLOAD_MAX_SIZE SZ_2K
36#define TEST_UPLOAD_BLK_SIZE 37 /* Avoid powers of two in testing */
0a8adf58
KC
37
38static DEFINE_MUTEX(test_fw_mutex);
39static const struct firmware *test_firmware;
a31ad463 40static LIST_HEAD(test_upload_list);
0a8adf58 41
c92316bf
LR
42struct test_batched_req {
43 u8 idx;
44 int rc;
45 bool sent;
46 const struct firmware *fw;
47 const char *name;
48 struct completion completion;
49 struct task_struct *task;
50 struct device *dev;
51};
52
53/**
1ad5288f 54 * struct test_config - represents configuration for the test for different triggers
c92316bf
LR
55 *
56 * @name: the name of the firmware file to look for
7feebfa4
SB
57 * @into_buf: when the into_buf is used if this is true
58 * request_firmware_into_buf() will be used instead.
5d90e05c
SB
59 * @buf_size: size of buf to allocate when into_buf is true
60 * @file_offset: file offset to request when calling request_firmware_into_buf
61 * @partial: partial read opt when calling request_firmware_into_buf
c92316bf
LR
62 * @sync_direct: when the sync trigger is used if this is true
63 * request_firmware_direct() will be used instead.
64 * @send_uevent: whether or not to send a uevent for async requests
65 * @num_requests: number of requests to try per test case. This is trigger
66 * specific.
67 * @reqs: stores all requests information
68 * @read_fw_idx: index of thread from which we want to read firmware results
69 * from through the read_fw trigger.
a31ad463 70 * @upload_name: firmware name to be used with upload_read sysfs node
c92316bf
LR
71 * @test_result: a test may use this to collect the result from the call
72 * of the request_firmware*() calls used in their tests. In order of
73 * priority we always keep first any setup error. If no setup errors were
74 * found then we move on to the first error encountered while running the
75 * API. Note that for async calls this typically will be a successful
76 * result (0) unless of course you've used bogus parameters, or the system
77 * is out of memory. In the async case the callback is expected to do a
78 * bit more homework to figure out what happened, unfortunately the only
79 * information passed today on error is the fact that no firmware was
80 * found so we can only assume -ENOENT on async calls if the firmware is
81 * NULL.
82 *
83 * Errors you can expect:
84 *
85 * API specific:
86 *
87 * 0: success for sync, for async it means request was sent
88 * -EINVAL: invalid parameters or request
89 * -ENOENT: files not found
90 *
91 * System environment:
92 *
93 * -ENOMEM: memory pressure on system
94 * -ENODEV: out of number of devices to test
95 * -EINVAL: an unexpected error has occurred
96 * @req_firmware: if @sync_direct is true this is set to
97 * request_firmware_direct(), otherwise request_firmware()
98 */
99struct test_config {
100 char *name;
7feebfa4 101 bool into_buf;
5d90e05c
SB
102 size_t buf_size;
103 size_t file_offset;
104 bool partial;
c92316bf
LR
105 bool sync_direct;
106 bool send_uevent;
107 u8 num_requests;
108 u8 read_fw_idx;
a31ad463 109 char *upload_name;
c92316bf
LR
110
111 /*
112 * These below don't belong her but we'll move them once we create
113 * a struct fw_test_device and stuff the misc_dev under there later.
114 */
115 struct test_batched_req *reqs;
116 int test_result;
117 int (*req_firmware)(const struct firmware **fw, const char *name,
118 struct device *device);
119};
120
4a4e975b
RW
121struct upload_inject_err {
122 const char *prog;
123 enum fw_upload_err err_code;
124};
125
a31ad463
RW
126struct test_firmware_upload {
127 char *name;
128 struct list_head node;
129 char *buf;
130 size_t size;
131 bool cancel_request;
4a4e975b 132 struct upload_inject_err inject;
a31ad463
RW
133 struct fw_upload *fwl;
134};
135
76f8ab1b 136static struct test_config *test_fw_config;
c92316bf 137
a31ad463
RW
138static struct test_firmware_upload *upload_lookup_name(const char *name)
139{
140 struct test_firmware_upload *tst;
141
142 list_for_each_entry(tst, &test_upload_list, node)
143 if (strncmp(name, tst->name, strlen(tst->name)) == 0)
144 return tst;
145
146 return NULL;
147}
148
0a8adf58
KC
149static ssize_t test_fw_misc_read(struct file *f, char __user *buf,
150 size_t size, loff_t *offset)
151{
152 ssize_t rc = 0;
153
154 mutex_lock(&test_fw_mutex);
155 if (test_firmware)
156 rc = simple_read_from_buffer(buf, size, offset,
157 test_firmware->data,
158 test_firmware->size);
159 mutex_unlock(&test_fw_mutex);
160 return rc;
161}
162
163static const struct file_operations test_fw_fops = {
164 .owner = THIS_MODULE,
165 .read = test_fw_misc_read,
166};
167
c92316bf
LR
168static void __test_release_all_firmware(void)
169{
170 struct test_batched_req *req;
171 u8 i;
172
173 if (!test_fw_config->reqs)
174 return;
175
176 for (i = 0; i < test_fw_config->num_requests; i++) {
177 req = &test_fw_config->reqs[i];
178 if (req->fw)
179 release_firmware(req->fw);
180 }
181
182 vfree(test_fw_config->reqs);
183 test_fw_config->reqs = NULL;
184}
185
186static void test_release_all_firmware(void)
187{
188 mutex_lock(&test_fw_mutex);
189 __test_release_all_firmware();
190 mutex_unlock(&test_fw_mutex);
191}
192
193
194static void __test_firmware_config_free(void)
195{
196 __test_release_all_firmware();
197 kfree_const(test_fw_config->name);
198 test_fw_config->name = NULL;
199}
200
201/*
202 * XXX: move to kstrncpy() once merged.
203 *
204 * Users should use kfree_const() when freeing these.
205 */
206static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp)
207{
208 *dst = kstrndup(name, count, gfp);
209 if (!*dst)
210 return -ENOSPC;
211 return count;
212}
213
214static int __test_firmware_config_init(void)
215{
216 int ret;
217
218 ret = __kstrncpy(&test_fw_config->name, TEST_FIRMWARE_NAME,
219 strlen(TEST_FIRMWARE_NAME), GFP_KERNEL);
220 if (ret < 0)
221 goto out;
222
223 test_fw_config->num_requests = TEST_FIRMWARE_NUM_REQS;
224 test_fw_config->send_uevent = true;
7feebfa4 225 test_fw_config->into_buf = false;
5d90e05c
SB
226 test_fw_config->buf_size = TEST_FIRMWARE_BUF_SIZE;
227 test_fw_config->file_offset = 0;
228 test_fw_config->partial = false;
c92316bf
LR
229 test_fw_config->sync_direct = false;
230 test_fw_config->req_firmware = request_firmware;
231 test_fw_config->test_result = 0;
232 test_fw_config->reqs = NULL;
a31ad463 233 test_fw_config->upload_name = NULL;
c92316bf
LR
234
235 return 0;
236
237out:
238 __test_firmware_config_free();
239 return ret;
240}
241
242static ssize_t reset_store(struct device *dev,
243 struct device_attribute *attr,
244 const char *buf, size_t count)
245{
246 int ret;
247
248 mutex_lock(&test_fw_mutex);
249
250 __test_firmware_config_free();
251
252 ret = __test_firmware_config_init();
253 if (ret < 0) {
254 ret = -ENOMEM;
255 pr_err("could not alloc settings for config trigger: %d\n",
256 ret);
257 goto out;
258 }
259
260 pr_info("reset\n");
261 ret = count;
262
263out:
264 mutex_unlock(&test_fw_mutex);
265
266 return ret;
267}
268static DEVICE_ATTR_WO(reset);
269
270static ssize_t config_show(struct device *dev,
271 struct device_attribute *attr,
272 char *buf)
273{
274 int len = 0;
275
276 mutex_lock(&test_fw_mutex);
277
bd17cc5a 278 len += scnprintf(buf, PAGE_SIZE - len,
c92316bf
LR
279 "Custom trigger configuration for: %s\n",
280 dev_name(dev));
281
282 if (test_fw_config->name)
5d90e05c 283 len += scnprintf(buf + len, PAGE_SIZE - len,
c92316bf
LR
284 "name:\t%s\n",
285 test_fw_config->name);
286 else
5d90e05c 287 len += scnprintf(buf + len, PAGE_SIZE - len,
d88bd098 288 "name:\tEMPTY\n");
c92316bf 289
5d90e05c 290 len += scnprintf(buf + len, PAGE_SIZE - len,
c92316bf
LR
291 "num_requests:\t%u\n", test_fw_config->num_requests);
292
5d90e05c 293 len += scnprintf(buf + len, PAGE_SIZE - len,
c92316bf
LR
294 "send_uevent:\t\t%s\n",
295 test_fw_config->send_uevent ?
0733d839
SG
296 "FW_ACTION_UEVENT" :
297 "FW_ACTION_NOUEVENT");
5d90e05c 298 len += scnprintf(buf + len, PAGE_SIZE - len,
7feebfa4
SB
299 "into_buf:\t\t%s\n",
300 test_fw_config->into_buf ? "true" : "false");
5d90e05c
SB
301 len += scnprintf(buf + len, PAGE_SIZE - len,
302 "buf_size:\t%zu\n", test_fw_config->buf_size);
303 len += scnprintf(buf + len, PAGE_SIZE - len,
304 "file_offset:\t%zu\n", test_fw_config->file_offset);
305 len += scnprintf(buf + len, PAGE_SIZE - len,
306 "partial:\t\t%s\n",
307 test_fw_config->partial ? "true" : "false");
308 len += scnprintf(buf + len, PAGE_SIZE - len,
c92316bf
LR
309 "sync_direct:\t\t%s\n",
310 test_fw_config->sync_direct ? "true" : "false");
5d90e05c 311 len += scnprintf(buf + len, PAGE_SIZE - len,
c92316bf 312 "read_fw_idx:\t%u\n", test_fw_config->read_fw_idx);
a31ad463
RW
313 if (test_fw_config->upload_name)
314 len += scnprintf(buf + len, PAGE_SIZE - len,
315 "upload_name:\t%s\n",
316 test_fw_config->upload_name);
317 else
318 len += scnprintf(buf + len, PAGE_SIZE - len,
d88bd098 319 "upload_name:\tEMPTY\n");
c92316bf
LR
320
321 mutex_unlock(&test_fw_mutex);
322
323 return len;
324}
325static DEVICE_ATTR_RO(config);
326
327static ssize_t config_name_store(struct device *dev,
328 struct device_attribute *attr,
329 const char *buf, size_t count)
330{
331 int ret;
332
333 mutex_lock(&test_fw_mutex);
334 kfree_const(test_fw_config->name);
335 ret = __kstrncpy(&test_fw_config->name, buf, count, GFP_KERNEL);
336 mutex_unlock(&test_fw_mutex);
337
338 return ret;
339}
340
341/*
342 * As per sysfs_kf_seq_show() the buf is max PAGE_SIZE.
343 */
344static ssize_t config_test_show_str(char *dst,
345 char *src)
346{
347 int len;
348
349 mutex_lock(&test_fw_mutex);
350 len = snprintf(dst, PAGE_SIZE, "%s\n", src);
351 mutex_unlock(&test_fw_mutex);
352
353 return len;
354}
355
4acfe3df 356static inline int __test_dev_config_update_bool(const char *buf, size_t size,
c92316bf
LR
357 bool *cfg)
358{
359 int ret;
360
f7d85515 361 if (kstrtobool(buf, cfg) < 0)
c92316bf
LR
362 ret = -EINVAL;
363 else
364 ret = size;
4acfe3df
MGT
365
366 return ret;
367}
368
369static int test_dev_config_update_bool(const char *buf, size_t size,
370 bool *cfg)
371{
372 int ret;
373
374 mutex_lock(&test_fw_mutex);
375 ret = __test_dev_config_update_bool(buf, size, cfg);
c92316bf
LR
376 mutex_unlock(&test_fw_mutex);
377
378 return ret;
379}
380
55623260 381static ssize_t test_dev_config_show_bool(char *buf, bool val)
c92316bf 382{
c92316bf
LR
383 return snprintf(buf, PAGE_SIZE, "%d\n", val);
384}
385
4acfe3df
MGT
386static int __test_dev_config_update_size_t(
387 const char *buf,
5d90e05c
SB
388 size_t size,
389 size_t *cfg)
390{
391 int ret;
392 long new;
393
394 ret = kstrtol(buf, 10, &new);
395 if (ret)
396 return ret;
397
5d90e05c 398 *(size_t *)cfg = new;
5d90e05c
SB
399
400 /* Always return full write size even if we didn't consume all */
401 return size;
402}
403
404static ssize_t test_dev_config_show_size_t(char *buf, size_t val)
405{
406 return snprintf(buf, PAGE_SIZE, "%zu\n", val);
407}
408
55623260 409static ssize_t test_dev_config_show_int(char *buf, int val)
c92316bf 410{
c92316bf
LR
411 return snprintf(buf, PAGE_SIZE, "%d\n", val);
412}
413
4acfe3df 414static int __test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
c92316bf 415{
506dfc99 416 u8 val;
c92316bf 417 int ret;
c92316bf 418
506dfc99 419 ret = kstrtou8(buf, 10, &val);
c92316bf
LR
420 if (ret)
421 return ret;
422
506dfc99 423 *(u8 *)cfg = val;
c92316bf
LR
424
425 /* Always return full write size even if we didn't consume all */
426 return size;
427}
428
4acfe3df
MGT
429static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
430{
431 int ret;
432
433 mutex_lock(&test_fw_mutex);
434 ret = __test_dev_config_update_u8(buf, size, cfg);
435 mutex_unlock(&test_fw_mutex);
436
437 return ret;
438}
439
55623260 440static ssize_t test_dev_config_show_u8(char *buf, u8 val)
c92316bf 441{
c92316bf
LR
442 return snprintf(buf, PAGE_SIZE, "%u\n", val);
443}
444
445static ssize_t config_name_show(struct device *dev,
446 struct device_attribute *attr,
447 char *buf)
448{
449 return config_test_show_str(buf, test_fw_config->name);
450}
b6b996b6 451static DEVICE_ATTR_RW(config_name);
c92316bf 452
a31ad463
RW
453static ssize_t config_upload_name_store(struct device *dev,
454 struct device_attribute *attr,
455 const char *buf, size_t count)
456{
457 struct test_firmware_upload *tst;
458 int ret = count;
459
460 mutex_lock(&test_fw_mutex);
461 tst = upload_lookup_name(buf);
462 if (tst)
463 test_fw_config->upload_name = tst->name;
464 else
465 ret = -EINVAL;
466 mutex_unlock(&test_fw_mutex);
467
468 return ret;
469}
470
471static ssize_t config_upload_name_show(struct device *dev,
472 struct device_attribute *attr,
473 char *buf)
474{
475 return config_test_show_str(buf, test_fw_config->upload_name);
476}
477static DEVICE_ATTR_RW(config_upload_name);
478
c92316bf
LR
479static ssize_t config_num_requests_store(struct device *dev,
480 struct device_attribute *attr,
481 const char *buf, size_t count)
482{
483 int rc;
484
485 mutex_lock(&test_fw_mutex);
486 if (test_fw_config->reqs) {
487 pr_err("Must call release_all_firmware prior to changing config\n");
488 rc = -EINVAL;
a5e19233 489 mutex_unlock(&test_fw_mutex);
c92316bf
LR
490 goto out;
491 }
c92316bf 492
4acfe3df
MGT
493 rc = __test_dev_config_update_u8(buf, count,
494 &test_fw_config->num_requests);
495 mutex_unlock(&test_fw_mutex);
c92316bf
LR
496
497out:
498 return rc;
499}
500
501static ssize_t config_num_requests_show(struct device *dev,
502 struct device_attribute *attr,
503 char *buf)
504{
505 return test_dev_config_show_u8(buf, test_fw_config->num_requests);
506}
b6b996b6 507static DEVICE_ATTR_RW(config_num_requests);
c92316bf 508
7feebfa4
SB
509static ssize_t config_into_buf_store(struct device *dev,
510 struct device_attribute *attr,
511 const char *buf, size_t count)
512{
513 return test_dev_config_update_bool(buf,
514 count,
515 &test_fw_config->into_buf);
516}
517
518static ssize_t config_into_buf_show(struct device *dev,
519 struct device_attribute *attr,
520 char *buf)
521{
522 return test_dev_config_show_bool(buf, test_fw_config->into_buf);
523}
524static DEVICE_ATTR_RW(config_into_buf);
525
5d90e05c
SB
526static ssize_t config_buf_size_store(struct device *dev,
527 struct device_attribute *attr,
528 const char *buf, size_t count)
529{
530 int rc;
531
532 mutex_lock(&test_fw_mutex);
533 if (test_fw_config->reqs) {
534 pr_err("Must call release_all_firmware prior to changing config\n");
535 rc = -EINVAL;
536 mutex_unlock(&test_fw_mutex);
537 goto out;
538 }
5d90e05c 539
4acfe3df
MGT
540 rc = __test_dev_config_update_size_t(buf, count,
541 &test_fw_config->buf_size);
542 mutex_unlock(&test_fw_mutex);
5d90e05c
SB
543
544out:
545 return rc;
546}
547
548static ssize_t config_buf_size_show(struct device *dev,
549 struct device_attribute *attr,
550 char *buf)
551{
552 return test_dev_config_show_size_t(buf, test_fw_config->buf_size);
553}
554static DEVICE_ATTR_RW(config_buf_size);
555
556static ssize_t config_file_offset_store(struct device *dev,
557 struct device_attribute *attr,
558 const char *buf, size_t count)
559{
560 int rc;
561
562 mutex_lock(&test_fw_mutex);
563 if (test_fw_config->reqs) {
564 pr_err("Must call release_all_firmware prior to changing config\n");
565 rc = -EINVAL;
566 mutex_unlock(&test_fw_mutex);
567 goto out;
568 }
5d90e05c 569
4acfe3df
MGT
570 rc = __test_dev_config_update_size_t(buf, count,
571 &test_fw_config->file_offset);
572 mutex_unlock(&test_fw_mutex);
5d90e05c
SB
573
574out:
575 return rc;
576}
577
578static ssize_t config_file_offset_show(struct device *dev,
579 struct device_attribute *attr,
580 char *buf)
581{
582 return test_dev_config_show_size_t(buf, test_fw_config->file_offset);
583}
584static DEVICE_ATTR_RW(config_file_offset);
585
586static ssize_t config_partial_store(struct device *dev,
587 struct device_attribute *attr,
588 const char *buf, size_t count)
589{
590 return test_dev_config_update_bool(buf,
591 count,
592 &test_fw_config->partial);
593}
594
595static ssize_t config_partial_show(struct device *dev,
596 struct device_attribute *attr,
597 char *buf)
598{
599 return test_dev_config_show_bool(buf, test_fw_config->partial);
600}
601static DEVICE_ATTR_RW(config_partial);
602
c92316bf
LR
603static ssize_t config_sync_direct_store(struct device *dev,
604 struct device_attribute *attr,
605 const char *buf, size_t count)
606{
607 int rc = test_dev_config_update_bool(buf, count,
608 &test_fw_config->sync_direct);
609
610 if (rc == count)
611 test_fw_config->req_firmware = test_fw_config->sync_direct ?
612 request_firmware_direct :
613 request_firmware;
614 return rc;
615}
616
617static ssize_t config_sync_direct_show(struct device *dev,
618 struct device_attribute *attr,
619 char *buf)
620{
621 return test_dev_config_show_bool(buf, test_fw_config->sync_direct);
622}
b6b996b6 623static DEVICE_ATTR_RW(config_sync_direct);
c92316bf
LR
624
625static ssize_t config_send_uevent_store(struct device *dev,
626 struct device_attribute *attr,
627 const char *buf, size_t count)
628{
629 return test_dev_config_update_bool(buf, count,
630 &test_fw_config->send_uevent);
631}
632
633static ssize_t config_send_uevent_show(struct device *dev,
634 struct device_attribute *attr,
635 char *buf)
636{
637 return test_dev_config_show_bool(buf, test_fw_config->send_uevent);
638}
b6b996b6 639static DEVICE_ATTR_RW(config_send_uevent);
c92316bf
LR
640
641static ssize_t config_read_fw_idx_store(struct device *dev,
642 struct device_attribute *attr,
643 const char *buf, size_t count)
644{
645 return test_dev_config_update_u8(buf, count,
646 &test_fw_config->read_fw_idx);
647}
648
649static ssize_t config_read_fw_idx_show(struct device *dev,
650 struct device_attribute *attr,
651 char *buf)
652{
653 return test_dev_config_show_u8(buf, test_fw_config->read_fw_idx);
654}
b6b996b6 655static DEVICE_ATTR_RW(config_read_fw_idx);
c92316bf
LR
656
657
0a8adf58
KC
658static ssize_t trigger_request_store(struct device *dev,
659 struct device_attribute *attr,
660 const char *buf, size_t count)
661{
662 int rc;
663 char *name;
664
be4a1326 665 name = kstrndup(buf, count, GFP_KERNEL);
0a8adf58
KC
666 if (!name)
667 return -ENOSPC;
0a8adf58
KC
668
669 pr_info("loading '%s'\n", name);
670
671 mutex_lock(&test_fw_mutex);
672 release_firmware(test_firmware);
673 test_firmware = NULL;
674 rc = request_firmware(&test_firmware, name, dev);
47e0bbb7 675 if (rc) {
0a8adf58 676 pr_info("load of '%s' failed: %d\n", name, rc);
47e0bbb7
BN
677 goto out;
678 }
679 pr_info("loaded: %zu\n", test_firmware->size);
680 rc = count;
681
682out:
0a8adf58
KC
683 mutex_unlock(&test_fw_mutex);
684
685 kfree(name);
686
47e0bbb7 687 return rc;
0a8adf58
KC
688}
689static DEVICE_ATTR_WO(trigger_request);
690
548193cb 691#ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
baaabecf
KC
692extern struct list_head efi_embedded_fw_list;
693extern bool efi_embedded_fw_checked;
694
548193cb
HG
695static ssize_t trigger_request_platform_store(struct device *dev,
696 struct device_attribute *attr,
697 const char *buf, size_t count)
698{
699 static const u8 test_data[] = {
700 0x55, 0xaa, 0x55, 0xaa, 0x01, 0x02, 0x03, 0x04,
701 0x55, 0xaa, 0x55, 0xaa, 0x05, 0x06, 0x07, 0x08,
702 0x55, 0xaa, 0x55, 0xaa, 0x10, 0x20, 0x30, 0x40,
703 0x55, 0xaa, 0x55, 0xaa, 0x50, 0x60, 0x70, 0x80
704 };
705 struct efi_embedded_fw efi_embedded_fw;
706 const struct firmware *firmware = NULL;
baaabecf 707 bool saved_efi_embedded_fw_checked;
548193cb
HG
708 char *name;
709 int rc;
710
711 name = kstrndup(buf, count, GFP_KERNEL);
712 if (!name)
713 return -ENOSPC;
714
715 pr_info("inserting test platform fw '%s'\n", name);
716 efi_embedded_fw.name = name;
717 efi_embedded_fw.data = (void *)test_data;
718 efi_embedded_fw.length = sizeof(test_data);
719 list_add(&efi_embedded_fw.list, &efi_embedded_fw_list);
baaabecf
KC
720 saved_efi_embedded_fw_checked = efi_embedded_fw_checked;
721 efi_embedded_fw_checked = true;
548193cb
HG
722
723 pr_info("loading '%s'\n", name);
724 rc = firmware_request_platform(&firmware, name, dev);
725 if (rc) {
726 pr_info("load of '%s' failed: %d\n", name, rc);
727 goto out;
728 }
729 if (firmware->size != sizeof(test_data) ||
730 memcmp(firmware->data, test_data, sizeof(test_data)) != 0) {
731 pr_info("firmware contents mismatch for '%s'\n", name);
732 rc = -EINVAL;
733 goto out;
734 }
735 pr_info("loaded: %zu\n", firmware->size);
736 rc = count;
737
738out:
baaabecf 739 efi_embedded_fw_checked = saved_efi_embedded_fw_checked;
548193cb
HG
740 release_firmware(firmware);
741 list_del(&efi_embedded_fw.list);
742 kfree(name);
743
744 return rc;
745}
746static DEVICE_ATTR_WO(trigger_request_platform);
747#endif
748
eb910947
BN
749static DECLARE_COMPLETION(async_fw_done);
750
751static void trigger_async_request_cb(const struct firmware *fw, void *context)
752{
753 test_firmware = fw;
754 complete(&async_fw_done);
755}
756
757static ssize_t trigger_async_request_store(struct device *dev,
758 struct device_attribute *attr,
759 const char *buf, size_t count)
760{
761 int rc;
762 char *name;
763
764 name = kstrndup(buf, count, GFP_KERNEL);
765 if (!name)
766 return -ENOSPC;
767
768 pr_info("loading '%s'\n", name);
769
770 mutex_lock(&test_fw_mutex);
771 release_firmware(test_firmware);
772 test_firmware = NULL;
773 rc = request_firmware_nowait(THIS_MODULE, 1, name, dev, GFP_KERNEL,
774 NULL, trigger_async_request_cb);
775 if (rc) {
776 pr_info("async load of '%s' failed: %d\n", name, rc);
777 kfree(name);
778 goto out;
779 }
780 /* Free 'name' ASAP, to test for race conditions */
781 kfree(name);
782
783 wait_for_completion(&async_fw_done);
784
785 if (test_firmware) {
786 pr_info("loaded: %zu\n", test_firmware->size);
787 rc = count;
788 } else {
789 pr_err("failed to async load firmware\n");
7feebfa4 790 rc = -ENOMEM;
eb910947
BN
791 }
792
793out:
794 mutex_unlock(&test_fw_mutex);
795
796 return rc;
797}
798static DEVICE_ATTR_WO(trigger_async_request);
799
061132d2
LR
800static ssize_t trigger_custom_fallback_store(struct device *dev,
801 struct device_attribute *attr,
802 const char *buf, size_t count)
803{
804 int rc;
805 char *name;
806
807 name = kstrndup(buf, count, GFP_KERNEL);
808 if (!name)
809 return -ENOSPC;
810
811 pr_info("loading '%s' using custom fallback mechanism\n", name);
812
813 mutex_lock(&test_fw_mutex);
814 release_firmware(test_firmware);
815 test_firmware = NULL;
0733d839 816 rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOUEVENT, name,
061132d2
LR
817 dev, GFP_KERNEL, NULL,
818 trigger_async_request_cb);
819 if (rc) {
820 pr_info("async load of '%s' failed: %d\n", name, rc);
821 kfree(name);
822 goto out;
823 }
824 /* Free 'name' ASAP, to test for race conditions */
825 kfree(name);
826
827 wait_for_completion(&async_fw_done);
828
829 if (test_firmware) {
830 pr_info("loaded: %zu\n", test_firmware->size);
831 rc = count;
832 } else {
833 pr_err("failed to async load firmware\n");
834 rc = -ENODEV;
835 }
836
837out:
838 mutex_unlock(&test_fw_mutex);
839
840 return rc;
841}
842static DEVICE_ATTR_WO(trigger_custom_fallback);
843
c92316bf
LR
844static int test_fw_run_batch_request(void *data)
845{
846 struct test_batched_req *req = data;
847
848 if (!req) {
849 test_fw_config->test_result = -EINVAL;
850 return -EINVAL;
851 }
852
7feebfa4
SB
853 if (test_fw_config->into_buf) {
854 void *test_buf;
855
856 test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL);
857 if (!test_buf)
858 return -ENOSPC;
859
5d90e05c
SB
860 if (test_fw_config->partial)
861 req->rc = request_partial_firmware_into_buf
862 (&req->fw,
863 req->name,
864 req->dev,
865 test_buf,
866 test_fw_config->buf_size,
867 test_fw_config->file_offset);
868 else
869 req->rc = request_firmware_into_buf
870 (&req->fw,
871 req->name,
872 req->dev,
873 test_buf,
874 test_fw_config->buf_size);
7feebfa4
SB
875 if (!req->fw)
876 kfree(test_buf);
877 } else {
878 req->rc = test_fw_config->req_firmware(&req->fw,
879 req->name,
880 req->dev);
881 }
882
c92316bf
LR
883 if (req->rc) {
884 pr_info("#%u: batched sync load failed: %d\n",
885 req->idx, req->rc);
886 if (!test_fw_config->test_result)
887 test_fw_config->test_result = req->rc;
888 } else if (req->fw) {
889 req->sent = true;
890 pr_info("#%u: batched sync loaded %zu\n",
891 req->idx, req->fw->size);
892 }
893 complete(&req->completion);
894
895 req->task = NULL;
896
897 return 0;
898}
899
900/*
901 * We use a kthread as otherwise the kernel serializes all our sync requests
902 * and we would not be able to mimic batched requests on a sync call. Batched
903 * requests on a sync call can for instance happen on a device driver when
904 * multiple cards are used and firmware loading happens outside of probe.
905 */
906static ssize_t trigger_batched_requests_store(struct device *dev,
907 struct device_attribute *attr,
908 const char *buf, size_t count)
909{
910 struct test_batched_req *req;
911 int rc;
912 u8 i;
913
914 mutex_lock(&test_fw_mutex);
915
fad953ce
KC
916 test_fw_config->reqs =
917 vzalloc(array3_size(sizeof(struct test_batched_req),
918 test_fw_config->num_requests, 2));
c92316bf
LR
919 if (!test_fw_config->reqs) {
920 rc = -ENOMEM;
921 goto out_unlock;
922 }
923
924 pr_info("batched sync firmware loading '%s' %u times\n",
925 test_fw_config->name, test_fw_config->num_requests);
926
927 for (i = 0; i < test_fw_config->num_requests; i++) {
928 req = &test_fw_config->reqs[i];
c92316bf
LR
929 req->fw = NULL;
930 req->idx = i;
931 req->name = test_fw_config->name;
932 req->dev = dev;
933 init_completion(&req->completion);
934 req->task = kthread_run(test_fw_run_batch_request, req,
935 "%s-%u", KBUILD_MODNAME, req->idx);
936 if (!req->task || IS_ERR(req->task)) {
937 pr_err("Setting up thread %u failed\n", req->idx);
938 req->task = NULL;
939 rc = -ENOMEM;
940 goto out_bail;
941 }
942 }
943
944 rc = count;
945
946 /*
947 * We require an explicit release to enable more time and delay of
948 * calling release_firmware() to improve our chances of forcing a
949 * batched request. If we instead called release_firmware() right away
950 * then we might miss on an opportunity of having a successful firmware
951 * request pass on the opportunity to be come a batched request.
952 */
953
954out_bail:
955 for (i = 0; i < test_fw_config->num_requests; i++) {
956 req = &test_fw_config->reqs[i];
957 if (req->task || req->sent)
958 wait_for_completion(&req->completion);
959 }
960
961 /* Override any worker error if we had a general setup error */
962 if (rc < 0)
963 test_fw_config->test_result = rc;
964
965out_unlock:
966 mutex_unlock(&test_fw_mutex);
967
968 return rc;
969}
970static DEVICE_ATTR_WO(trigger_batched_requests);
971
972/*
973 * We wait for each callback to return with the lock held, no need to lock here
974 */
975static void trigger_batched_cb(const struct firmware *fw, void *context)
976{
977 struct test_batched_req *req = context;
978
979 if (!req) {
980 test_fw_config->test_result = -EINVAL;
981 return;
982 }
983
984 /* forces *some* batched requests to queue up */
985 if (!req->idx)
986 ssleep(2);
987
988 req->fw = fw;
989
990 /*
991 * Unfortunately the firmware API gives us nothing other than a null FW
992 * if the firmware was not found on async requests. Best we can do is
993 * just assume -ENOENT. A better API would pass the actual return
994 * value to the callback.
995 */
996 if (!fw && !test_fw_config->test_result)
997 test_fw_config->test_result = -ENOENT;
998
999 complete(&req->completion);
1000}
1001
1002static
1003ssize_t trigger_batched_requests_async_store(struct device *dev,
1004 struct device_attribute *attr,
1005 const char *buf, size_t count)
1006{
1007 struct test_batched_req *req;
1008 bool send_uevent;
1009 int rc;
1010 u8 i;
1011
1012 mutex_lock(&test_fw_mutex);
1013
fad953ce
KC
1014 test_fw_config->reqs =
1015 vzalloc(array3_size(sizeof(struct test_batched_req),
1016 test_fw_config->num_requests, 2));
c92316bf
LR
1017 if (!test_fw_config->reqs) {
1018 rc = -ENOMEM;
1019 goto out;
1020 }
1021
1022 pr_info("batched loading '%s' custom fallback mechanism %u times\n",
1023 test_fw_config->name, test_fw_config->num_requests);
1024
0733d839
SG
1025 send_uevent = test_fw_config->send_uevent ? FW_ACTION_UEVENT :
1026 FW_ACTION_NOUEVENT;
c92316bf
LR
1027
1028 for (i = 0; i < test_fw_config->num_requests; i++) {
1029 req = &test_fw_config->reqs[i];
c92316bf
LR
1030 req->name = test_fw_config->name;
1031 req->fw = NULL;
1032 req->idx = i;
1033 init_completion(&req->completion);
1034 rc = request_firmware_nowait(THIS_MODULE, send_uevent,
1035 req->name,
1036 dev, GFP_KERNEL, req,
1037 trigger_batched_cb);
1038 if (rc) {
1039 pr_info("#%u: batched async load failed setup: %d\n",
1040 i, rc);
1041 req->rc = rc;
1042 goto out_bail;
1043 } else
1044 req->sent = true;
1045 }
1046
1047 rc = count;
1048
1049out_bail:
1050
1051 /*
1052 * We require an explicit release to enable more time and delay of
1053 * calling release_firmware() to improve our chances of forcing a
1054 * batched request. If we instead called release_firmware() right away
1055 * then we might miss on an opportunity of having a successful firmware
1056 * request pass on the opportunity to be come a batched request.
1057 */
1058
1059 for (i = 0; i < test_fw_config->num_requests; i++) {
1060 req = &test_fw_config->reqs[i];
1061 if (req->sent)
1062 wait_for_completion(&req->completion);
1063 }
1064
1065 /* Override any worker error if we had a general setup error */
1066 if (rc < 0)
1067 test_fw_config->test_result = rc;
1068
1069out:
1070 mutex_unlock(&test_fw_mutex);
1071
1072 return rc;
1073}
1074static DEVICE_ATTR_WO(trigger_batched_requests_async);
1075
a31ad463
RW
1076static void upload_release(struct test_firmware_upload *tst)
1077{
1078 firmware_upload_unregister(tst->fwl);
1079 kfree(tst->buf);
1080 kfree(tst->name);
1081 kfree(tst);
1082}
1083
1084static void upload_release_all(void)
1085{
1086 struct test_firmware_upload *tst, *tmp;
1087
1088 list_for_each_entry_safe(tst, tmp, &test_upload_list, node) {
1089 list_del(&tst->node);
1090 upload_release(tst);
1091 }
1092 test_fw_config->upload_name = NULL;
1093}
1094
4a4e975b
RW
1095/*
1096 * This table is replicated from .../firmware_loader/sysfs_upload.c
1097 * and needs to be kept in sync.
1098 */
1099static const char * const fw_upload_err_str[] = {
1100 [FW_UPLOAD_ERR_NONE] = "none",
1101 [FW_UPLOAD_ERR_HW_ERROR] = "hw-error",
1102 [FW_UPLOAD_ERR_TIMEOUT] = "timeout",
1103 [FW_UPLOAD_ERR_CANCELED] = "user-abort",
1104 [FW_UPLOAD_ERR_BUSY] = "device-busy",
1105 [FW_UPLOAD_ERR_INVALID_SIZE] = "invalid-file-size",
1106 [FW_UPLOAD_ERR_RW_ERROR] = "read-write-error",
1107 [FW_UPLOAD_ERR_WEAROUT] = "flash-wearout",
1108};
1109
1110static void upload_err_inject_error(struct test_firmware_upload *tst,
1111 const u8 *p, const char *prog)
1112{
1113 enum fw_upload_err err;
1114
1115 for (err = FW_UPLOAD_ERR_NONE + 1; err < FW_UPLOAD_ERR_MAX; err++) {
1116 if (strncmp(p, fw_upload_err_str[err],
1117 strlen(fw_upload_err_str[err])) == 0) {
1118 tst->inject.prog = prog;
1119 tst->inject.err_code = err;
1120 return;
1121 }
1122 }
1123}
1124
1125static void upload_err_inject_prog(struct test_firmware_upload *tst,
1126 const u8 *p)
1127{
1128 static const char * const progs[] = {
1129 "preparing:", "transferring:", "programming:"
1130 };
1131 int i;
1132
1133 for (i = 0; i < ARRAY_SIZE(progs); i++) {
1134 if (strncmp(p, progs[i], strlen(progs[i])) == 0) {
1135 upload_err_inject_error(tst, p + strlen(progs[i]),
1136 progs[i]);
1137 return;
1138 }
1139 }
1140}
1141
1142#define FIVE_MINUTES_MS (5 * 60 * 1000)
1143static enum fw_upload_err
1144fw_upload_wait_on_cancel(struct test_firmware_upload *tst)
1145{
1146 int ms_delay;
1147
1148 for (ms_delay = 0; ms_delay < FIVE_MINUTES_MS; ms_delay += 100) {
1149 msleep(100);
1150 if (tst->cancel_request)
1151 return FW_UPLOAD_ERR_CANCELED;
1152 }
1153 return FW_UPLOAD_ERR_NONE;
1154}
1155
a31ad463
RW
1156static enum fw_upload_err test_fw_upload_prepare(struct fw_upload *fwl,
1157 const u8 *data, u32 size)
1158{
1159 struct test_firmware_upload *tst = fwl->dd_handle;
4a4e975b
RW
1160 enum fw_upload_err ret = FW_UPLOAD_ERR_NONE;
1161 const char *progress = "preparing:";
a31ad463
RW
1162
1163 tst->cancel_request = false;
1164
4a4e975b
RW
1165 if (!size || size > TEST_UPLOAD_MAX_SIZE) {
1166 ret = FW_UPLOAD_ERR_INVALID_SIZE;
1167 goto err_out;
1168 }
1169
1170 if (strncmp(data, "inject:", strlen("inject:")) == 0)
1171 upload_err_inject_prog(tst, data + strlen("inject:"));
a31ad463
RW
1172
1173 memset(tst->buf, 0, TEST_UPLOAD_MAX_SIZE);
1174 tst->size = size;
1175
4a4e975b
RW
1176 if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
1177 strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
1178 return FW_UPLOAD_ERR_NONE;
1179
1180 if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
1181 ret = fw_upload_wait_on_cancel(tst);
1182 else
1183 ret = tst->inject.err_code;
1184
1185err_out:
1186 /*
1187 * The cleanup op only executes if the prepare op succeeds.
1188 * If the prepare op fails, it must do it's own clean-up.
1189 */
1190 tst->inject.err_code = FW_UPLOAD_ERR_NONE;
1191 tst->inject.prog = NULL;
1192
1193 return ret;
a31ad463
RW
1194}
1195
1196static enum fw_upload_err test_fw_upload_write(struct fw_upload *fwl,
1197 const u8 *data, u32 offset,
1198 u32 size, u32 *written)
1199{
1200 struct test_firmware_upload *tst = fwl->dd_handle;
4a4e975b 1201 const char *progress = "transferring:";
a31ad463
RW
1202 u32 blk_size;
1203
1204 if (tst->cancel_request)
1205 return FW_UPLOAD_ERR_CANCELED;
1206
1207 blk_size = min_t(u32, TEST_UPLOAD_BLK_SIZE, size);
1208 memcpy(tst->buf + offset, data + offset, blk_size);
1209
1210 *written = blk_size;
4a4e975b
RW
1211
1212 if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
1213 strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
1214 return FW_UPLOAD_ERR_NONE;
1215
1216 if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
1217 return fw_upload_wait_on_cancel(tst);
1218
1219 return tst->inject.err_code;
a31ad463
RW
1220}
1221
1222static enum fw_upload_err test_fw_upload_complete(struct fw_upload *fwl)
1223{
1224 struct test_firmware_upload *tst = fwl->dd_handle;
4a4e975b 1225 const char *progress = "programming:";
a31ad463
RW
1226
1227 if (tst->cancel_request)
1228 return FW_UPLOAD_ERR_CANCELED;
1229
4a4e975b
RW
1230 if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
1231 strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
1232 return FW_UPLOAD_ERR_NONE;
1233
1234 if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
1235 return fw_upload_wait_on_cancel(tst);
1236
1237 return tst->inject.err_code;
a31ad463
RW
1238}
1239
1240static void test_fw_upload_cancel(struct fw_upload *fwl)
1241{
1242 struct test_firmware_upload *tst = fwl->dd_handle;
1243
1244 tst->cancel_request = true;
1245}
1246
4a4e975b
RW
1247static void test_fw_cleanup(struct fw_upload *fwl)
1248{
1249 struct test_firmware_upload *tst = fwl->dd_handle;
1250
1251 tst->inject.err_code = FW_UPLOAD_ERR_NONE;
1252 tst->inject.prog = NULL;
1253}
1254
a31ad463
RW
1255static const struct fw_upload_ops upload_test_ops = {
1256 .prepare = test_fw_upload_prepare,
1257 .write = test_fw_upload_write,
1258 .poll_complete = test_fw_upload_complete,
1259 .cancel = test_fw_upload_cancel,
4a4e975b 1260 .cleanup = test_fw_cleanup
a31ad463
RW
1261};
1262
1263static ssize_t upload_register_store(struct device *dev,
1264 struct device_attribute *attr,
1265 const char *buf, size_t count)
1266{
1267 struct test_firmware_upload *tst;
1268 struct fw_upload *fwl;
1269 char *name;
1270 int ret;
1271
1272 name = kstrndup(buf, count, GFP_KERNEL);
1273 if (!name)
1274 return -ENOMEM;
1275
1276 mutex_lock(&test_fw_mutex);
1277 tst = upload_lookup_name(name);
1278 if (tst) {
1279 ret = -EEXIST;
1280 goto free_name;
1281 }
1282
1283 tst = kzalloc(sizeof(*tst), GFP_KERNEL);
1284 if (!tst) {
1285 ret = -ENOMEM;
1286 goto free_name;
1287 }
1288
1289 tst->name = name;
1290 tst->buf = kzalloc(TEST_UPLOAD_MAX_SIZE, GFP_KERNEL);
1291 if (!tst->buf) {
1292 ret = -ENOMEM;
1293 goto free_tst;
1294 }
1295
1296 fwl = firmware_upload_register(THIS_MODULE, dev, tst->name,
1297 &upload_test_ops, tst);
1298 if (IS_ERR(fwl)) {
1299 ret = PTR_ERR(fwl);
1300 goto free_buf;
1301 }
1302
1303 tst->fwl = fwl;
1304 list_add_tail(&tst->node, &test_upload_list);
1305 mutex_unlock(&test_fw_mutex);
1306 return count;
1307
1308free_buf:
1309 kfree(tst->buf);
1310
1311free_tst:
1312 kfree(tst);
1313
1314free_name:
1315 mutex_unlock(&test_fw_mutex);
1316 kfree(name);
1317
1318 return ret;
1319}
1320static DEVICE_ATTR_WO(upload_register);
1321
1322static ssize_t upload_unregister_store(struct device *dev,
1323 struct device_attribute *attr,
1324 const char *buf, size_t count)
1325{
1326 struct test_firmware_upload *tst;
1327 int ret = count;
1328
1329 mutex_lock(&test_fw_mutex);
1330 tst = upload_lookup_name(buf);
1331 if (!tst) {
1332 ret = -EINVAL;
1333 goto out;
1334 }
1335
1336 if (test_fw_config->upload_name == tst->name)
1337 test_fw_config->upload_name = NULL;
1338
1339 list_del(&tst->node);
1340 upload_release(tst);
1341
1342out:
1343 mutex_unlock(&test_fw_mutex);
1344 return ret;
1345}
1346static DEVICE_ATTR_WO(upload_unregister);
1347
c92316bf
LR
1348static ssize_t test_result_show(struct device *dev,
1349 struct device_attribute *attr,
1350 char *buf)
1351{
1352 return test_dev_config_show_int(buf, test_fw_config->test_result);
1353}
1354static DEVICE_ATTR_RO(test_result);
1355
1356static ssize_t release_all_firmware_store(struct device *dev,
1357 struct device_attribute *attr,
1358 const char *buf, size_t count)
1359{
1360 test_release_all_firmware();
1361 return count;
1362}
1363static DEVICE_ATTR_WO(release_all_firmware);
1364
1365static ssize_t read_firmware_show(struct device *dev,
1366 struct device_attribute *attr,
1367 char *buf)
1368{
1369 struct test_batched_req *req;
1370 u8 idx;
1371 ssize_t rc = 0;
1372
1373 mutex_lock(&test_fw_mutex);
1374
1375 idx = test_fw_config->read_fw_idx;
1376 if (idx >= test_fw_config->num_requests) {
1377 rc = -ERANGE;
1378 goto out;
1379 }
1380
1381 if (!test_fw_config->reqs) {
1382 rc = -EINVAL;
1383 goto out;
1384 }
1385
1386 req = &test_fw_config->reqs[idx];
1387 if (!req->fw) {
1388 pr_err("#%u: failed to async load firmware\n", idx);
1389 rc = -ENOENT;
1390 goto out;
1391 }
1392
1393 pr_info("#%u: loaded %zu\n", idx, req->fw->size);
1394
1395 if (req->fw->size > PAGE_SIZE) {
1396 pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
1397 rc = -EINVAL;
8bb0a886 1398 goto out;
c92316bf
LR
1399 }
1400 memcpy(buf, req->fw->data, req->fw->size);
1401
1402 rc = req->fw->size;
1403out:
1404 mutex_unlock(&test_fw_mutex);
1405
1406 return rc;
1407}
1408static DEVICE_ATTR_RO(read_firmware);
1409
a31ad463
RW
1410static ssize_t upload_read_show(struct device *dev,
1411 struct device_attribute *attr,
1412 char *buf)
1413{
185b29c6
DC
1414 struct test_firmware_upload *tst = NULL;
1415 struct test_firmware_upload *tst_iter;
a31ad463
RW
1416 int ret = -EINVAL;
1417
1418 if (!test_fw_config->upload_name) {
1419 pr_err("Set config_upload_name before using upload_read\n");
1420 return -EINVAL;
1421 }
1422
1423 mutex_lock(&test_fw_mutex);
185b29c6
DC
1424 list_for_each_entry(tst_iter, &test_upload_list, node)
1425 if (tst_iter->name == test_fw_config->upload_name) {
1426 tst = tst_iter;
a31ad463 1427 break;
185b29c6 1428 }
a31ad463 1429
185b29c6 1430 if (!tst) {
a31ad463
RW
1431 pr_err("Firmware name not found: %s\n",
1432 test_fw_config->upload_name);
1433 goto out;
1434 }
1435
1436 if (tst->size > PAGE_SIZE) {
1437 pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
1438 goto out;
1439 }
1440
1441 memcpy(buf, tst->buf, tst->size);
1442 ret = tst->size;
1443out:
1444 mutex_unlock(&test_fw_mutex);
1445 return ret;
1446}
1447static DEVICE_ATTR_RO(upload_read);
1448
083a93b0
LR
1449#define TEST_FW_DEV_ATTR(name) &dev_attr_##name.attr
1450
1451static struct attribute *test_dev_attrs[] = {
c92316bf
LR
1452 TEST_FW_DEV_ATTR(reset),
1453
1454 TEST_FW_DEV_ATTR(config),
1455 TEST_FW_DEV_ATTR(config_name),
1456 TEST_FW_DEV_ATTR(config_num_requests),
7feebfa4 1457 TEST_FW_DEV_ATTR(config_into_buf),
5d90e05c
SB
1458 TEST_FW_DEV_ATTR(config_buf_size),
1459 TEST_FW_DEV_ATTR(config_file_offset),
1460 TEST_FW_DEV_ATTR(config_partial),
c92316bf
LR
1461 TEST_FW_DEV_ATTR(config_sync_direct),
1462 TEST_FW_DEV_ATTR(config_send_uevent),
1463 TEST_FW_DEV_ATTR(config_read_fw_idx),
a31ad463 1464 TEST_FW_DEV_ATTR(config_upload_name),
c92316bf
LR
1465
1466 /* These don't use the config at all - they could be ported! */
083a93b0
LR
1467 TEST_FW_DEV_ATTR(trigger_request),
1468 TEST_FW_DEV_ATTR(trigger_async_request),
061132d2 1469 TEST_FW_DEV_ATTR(trigger_custom_fallback),
548193cb
HG
1470#ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
1471 TEST_FW_DEV_ATTR(trigger_request_platform),
1472#endif
c92316bf
LR
1473
1474 /* These use the config and can use the test_result */
1475 TEST_FW_DEV_ATTR(trigger_batched_requests),
1476 TEST_FW_DEV_ATTR(trigger_batched_requests_async),
1477
1478 TEST_FW_DEV_ATTR(release_all_firmware),
1479 TEST_FW_DEV_ATTR(test_result),
1480 TEST_FW_DEV_ATTR(read_firmware),
a31ad463
RW
1481 TEST_FW_DEV_ATTR(upload_read),
1482 TEST_FW_DEV_ATTR(upload_register),
1483 TEST_FW_DEV_ATTR(upload_unregister),
083a93b0
LR
1484 NULL,
1485};
1486
1487ATTRIBUTE_GROUPS(test_dev);
1488
67fd553c
LR
1489static struct miscdevice test_fw_misc_device = {
1490 .minor = MISC_DYNAMIC_MINOR,
1491 .name = "test_firmware",
1492 .fops = &test_fw_fops,
083a93b0 1493 .groups = test_dev_groups,
67fd553c
LR
1494};
1495
0a8adf58
KC
1496static int __init test_firmware_init(void)
1497{
1498 int rc;
1499
c92316bf
LR
1500 test_fw_config = kzalloc(sizeof(struct test_config), GFP_KERNEL);
1501 if (!test_fw_config)
1502 return -ENOMEM;
1503
1504 rc = __test_firmware_config_init();
d4fddac5
WW
1505 if (rc) {
1506 kfree(test_fw_config);
1507 pr_err("could not init firmware test config: %d\n", rc);
c92316bf 1508 return rc;
d4fddac5 1509 }
c92316bf 1510
0a8adf58
KC
1511 rc = misc_register(&test_fw_misc_device);
1512 if (rc) {
7610615e 1513 __test_firmware_config_free();
c92316bf 1514 kfree(test_fw_config);
0a8adf58
KC
1515 pr_err("could not register misc device: %d\n", rc);
1516 return rc;
1517 }
eb910947 1518
0a8adf58
KC
1519 pr_warn("interface ready\n");
1520
1521 return 0;
0a8adf58
KC
1522}
1523
1524module_init(test_firmware_init);
1525
1526static void __exit test_firmware_exit(void)
1527{
c92316bf 1528 mutex_lock(&test_fw_mutex);
0a8adf58 1529 release_firmware(test_firmware);
0a8adf58 1530 misc_deregister(&test_fw_misc_device);
a31ad463 1531 upload_release_all();
c92316bf
LR
1532 __test_firmware_config_free();
1533 kfree(test_fw_config);
1534 mutex_unlock(&test_fw_mutex);
1535
0a8adf58
KC
1536 pr_warn("removed interface\n");
1537}
1538
1539module_exit(test_firmware_exit);
1540
1541MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
1542MODULE_LICENSE("GPL");