1 // SPDX-License-Identifier: GPL-2.0-only
3 * This module provides an interface to trigger and test firmware loading.
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.
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/printk.h>
16 #include <linux/completion.h>
17 #include <linux/firmware.h>
18 #include <linux/device.h>
20 #include <linux/miscdevice.h>
21 #include <linux/sizes.h>
22 #include <linux/slab.h>
23 #include <linux/uaccess.h>
24 #include <linux/delay.h>
25 #include <linux/kstrtox.h>
26 #include <linux/kthread.h>
27 #include <linux/vmalloc.h>
28 #include <linux/efi_embedded_fw.h>
30 MODULE_IMPORT_NS(TEST_FIRMWARE);
32 #define TEST_FIRMWARE_NAME "test-firmware.bin"
33 #define TEST_FIRMWARE_NUM_REQS 4
34 #define TEST_FIRMWARE_BUF_SIZE SZ_1K
36 static DEFINE_MUTEX(test_fw_mutex);
37 static const struct firmware *test_firmware;
39 struct test_batched_req {
43 const struct firmware *fw;
46 struct completion completion;
47 struct task_struct *task;
52 * test_config - represents configuration for the test for different triggers
54 * @name: the name of the firmware file to look for
55 * @into_buf: when the into_buf is used if this is true
56 * request_firmware_into_buf() will be used instead.
57 * @buf_size: size of buf to allocate when into_buf is true
58 * @file_offset: file offset to request when calling request_firmware_into_buf
59 * @partial: partial read opt when calling request_firmware_into_buf
60 * @sync_direct: when the sync trigger is used if this is true
61 * request_firmware_direct() will be used instead.
62 * @send_uevent: whether or not to send a uevent for async requests
63 * @num_requests: number of requests to try per test case. This is trigger
65 * @reqs: stores all requests information
66 * @read_fw_idx: index of thread from which we want to read firmware results
67 * from through the read_fw trigger.
68 * @test_result: a test may use this to collect the result from the call
69 * of the request_firmware*() calls used in their tests. In order of
70 * priority we always keep first any setup error. If no setup errors were
71 * found then we move on to the first error encountered while running the
72 * API. Note that for async calls this typically will be a successful
73 * result (0) unless of course you've used bogus parameters, or the system
74 * is out of memory. In the async case the callback is expected to do a
75 * bit more homework to figure out what happened, unfortunately the only
76 * information passed today on error is the fact that no firmware was
77 * found so we can only assume -ENOENT on async calls if the firmware is
80 * Errors you can expect:
84 * 0: success for sync, for async it means request was sent
85 * -EINVAL: invalid parameters or request
86 * -ENOENT: files not found
90 * -ENOMEM: memory pressure on system
91 * -ENODEV: out of number of devices to test
92 * -EINVAL: an unexpected error has occurred
93 * @req_firmware: if @sync_direct is true this is set to
94 * request_firmware_direct(), otherwise request_firmware()
108 * These below don't belong her but we'll move them once we create
109 * a struct fw_test_device and stuff the misc_dev under there later.
111 struct test_batched_req *reqs;
113 int (*req_firmware)(const struct firmware **fw, const char *name,
114 struct device *device);
117 static struct test_config *test_fw_config;
119 static ssize_t test_fw_misc_read(struct file *f, char __user *buf,
120 size_t size, loff_t *offset)
124 mutex_lock(&test_fw_mutex);
126 rc = simple_read_from_buffer(buf, size, offset,
128 test_firmware->size);
129 mutex_unlock(&test_fw_mutex);
133 static const struct file_operations test_fw_fops = {
134 .owner = THIS_MODULE,
135 .read = test_fw_misc_read,
138 static void __test_release_all_firmware(void)
140 struct test_batched_req *req;
143 if (!test_fw_config->reqs)
146 for (i = 0; i < test_fw_config->num_requests; i++) {
147 req = &test_fw_config->reqs[i];
150 kfree_const(req->fw_buf);
153 release_firmware(req->fw);
158 vfree(test_fw_config->reqs);
159 test_fw_config->reqs = NULL;
162 static void test_release_all_firmware(void)
164 mutex_lock(&test_fw_mutex);
165 __test_release_all_firmware();
166 mutex_unlock(&test_fw_mutex);
170 static void __test_firmware_config_free(void)
172 __test_release_all_firmware();
173 kfree_const(test_fw_config->name);
174 test_fw_config->name = NULL;
178 * XXX: move to kstrncpy() once merged.
180 * Users should use kfree_const() when freeing these.
182 static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp)
184 *dst = kstrndup(name, count, gfp);
190 static int __test_firmware_config_init(void)
194 ret = __kstrncpy(&test_fw_config->name, TEST_FIRMWARE_NAME,
195 strlen(TEST_FIRMWARE_NAME), GFP_KERNEL);
199 test_fw_config->num_requests = TEST_FIRMWARE_NUM_REQS;
200 test_fw_config->send_uevent = true;
201 test_fw_config->into_buf = false;
202 test_fw_config->buf_size = TEST_FIRMWARE_BUF_SIZE;
203 test_fw_config->file_offset = 0;
204 test_fw_config->partial = false;
205 test_fw_config->sync_direct = false;
206 test_fw_config->req_firmware = request_firmware;
207 test_fw_config->test_result = 0;
208 test_fw_config->reqs = NULL;
213 __test_firmware_config_free();
217 static ssize_t reset_store(struct device *dev,
218 struct device_attribute *attr,
219 const char *buf, size_t count)
223 mutex_lock(&test_fw_mutex);
225 __test_firmware_config_free();
227 ret = __test_firmware_config_init();
230 pr_err("could not alloc settings for config trigger: %d\n",
239 mutex_unlock(&test_fw_mutex);
243 static DEVICE_ATTR_WO(reset);
245 static ssize_t config_show(struct device *dev,
246 struct device_attribute *attr,
251 mutex_lock(&test_fw_mutex);
253 len += scnprintf(buf, PAGE_SIZE - len,
254 "Custom trigger configuration for: %s\n",
257 if (test_fw_config->name)
258 len += scnprintf(buf + len, PAGE_SIZE - len,
260 test_fw_config->name);
262 len += scnprintf(buf + len, PAGE_SIZE - len,
265 len += scnprintf(buf + len, PAGE_SIZE - len,
266 "num_requests:\t%u\n", test_fw_config->num_requests);
268 len += scnprintf(buf + len, PAGE_SIZE - len,
269 "send_uevent:\t\t%s\n",
270 test_fw_config->send_uevent ?
271 "FW_ACTION_HOTPLUG" :
272 "FW_ACTION_NOHOTPLUG");
273 len += scnprintf(buf + len, PAGE_SIZE - len,
275 test_fw_config->into_buf ? "true" : "false");
276 len += scnprintf(buf + len, PAGE_SIZE - len,
277 "buf_size:\t%zu\n", test_fw_config->buf_size);
278 len += scnprintf(buf + len, PAGE_SIZE - len,
279 "file_offset:\t%zu\n", test_fw_config->file_offset);
280 len += scnprintf(buf + len, PAGE_SIZE - len,
282 test_fw_config->partial ? "true" : "false");
283 len += scnprintf(buf + len, PAGE_SIZE - len,
284 "sync_direct:\t\t%s\n",
285 test_fw_config->sync_direct ? "true" : "false");
286 len += scnprintf(buf + len, PAGE_SIZE - len,
287 "read_fw_idx:\t%u\n", test_fw_config->read_fw_idx);
289 mutex_unlock(&test_fw_mutex);
293 static DEVICE_ATTR_RO(config);
295 static ssize_t config_name_store(struct device *dev,
296 struct device_attribute *attr,
297 const char *buf, size_t count)
301 mutex_lock(&test_fw_mutex);
302 kfree_const(test_fw_config->name);
303 ret = __kstrncpy(&test_fw_config->name, buf, count, GFP_KERNEL);
304 mutex_unlock(&test_fw_mutex);
310 * As per sysfs_kf_seq_show() the buf is max PAGE_SIZE.
312 static ssize_t config_test_show_str(char *dst,
317 mutex_lock(&test_fw_mutex);
318 len = snprintf(dst, PAGE_SIZE, "%s\n", src);
319 mutex_unlock(&test_fw_mutex);
324 static inline int __test_dev_config_update_bool(const char *buf, size_t size,
329 if (kstrtobool(buf, cfg) < 0)
337 static int test_dev_config_update_bool(const char *buf, size_t size,
342 mutex_lock(&test_fw_mutex);
343 ret = __test_dev_config_update_bool(buf, size, cfg);
344 mutex_unlock(&test_fw_mutex);
349 static ssize_t test_dev_config_show_bool(char *buf, bool val)
351 return snprintf(buf, PAGE_SIZE, "%d\n", val);
354 static int __test_dev_config_update_size_t(
362 ret = kstrtol(buf, 10, &new);
366 *(size_t *)cfg = new;
368 /* Always return full write size even if we didn't consume all */
372 static ssize_t test_dev_config_show_size_t(char *buf, size_t val)
374 return snprintf(buf, PAGE_SIZE, "%zu\n", val);
377 static ssize_t test_dev_config_show_int(char *buf, int val)
379 return snprintf(buf, PAGE_SIZE, "%d\n", val);
382 static int __test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
387 ret = kstrtou8(buf, 10, &val);
393 /* Always return full write size even if we didn't consume all */
397 static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
401 mutex_lock(&test_fw_mutex);
402 ret = __test_dev_config_update_u8(buf, size, cfg);
403 mutex_unlock(&test_fw_mutex);
408 static ssize_t test_dev_config_show_u8(char *buf, u8 val)
410 return snprintf(buf, PAGE_SIZE, "%u\n", val);
413 static ssize_t config_name_show(struct device *dev,
414 struct device_attribute *attr,
417 return config_test_show_str(buf, test_fw_config->name);
419 static DEVICE_ATTR_RW(config_name);
421 static ssize_t config_num_requests_store(struct device *dev,
422 struct device_attribute *attr,
423 const char *buf, size_t count)
427 mutex_lock(&test_fw_mutex);
428 if (test_fw_config->reqs) {
429 pr_err("Must call release_all_firmware prior to changing config\n");
431 mutex_unlock(&test_fw_mutex);
435 rc = __test_dev_config_update_u8(buf, count,
436 &test_fw_config->num_requests);
437 mutex_unlock(&test_fw_mutex);
443 static ssize_t config_num_requests_show(struct device *dev,
444 struct device_attribute *attr,
447 return test_dev_config_show_u8(buf, test_fw_config->num_requests);
449 static DEVICE_ATTR_RW(config_num_requests);
451 static ssize_t config_into_buf_store(struct device *dev,
452 struct device_attribute *attr,
453 const char *buf, size_t count)
455 return test_dev_config_update_bool(buf,
457 &test_fw_config->into_buf);
460 static ssize_t config_into_buf_show(struct device *dev,
461 struct device_attribute *attr,
464 return test_dev_config_show_bool(buf, test_fw_config->into_buf);
466 static DEVICE_ATTR_RW(config_into_buf);
468 static ssize_t config_buf_size_store(struct device *dev,
469 struct device_attribute *attr,
470 const char *buf, size_t count)
474 mutex_lock(&test_fw_mutex);
475 if (test_fw_config->reqs) {
476 pr_err("Must call release_all_firmware prior to changing config\n");
478 mutex_unlock(&test_fw_mutex);
482 rc = __test_dev_config_update_size_t(buf, count,
483 &test_fw_config->buf_size);
484 mutex_unlock(&test_fw_mutex);
490 static ssize_t config_buf_size_show(struct device *dev,
491 struct device_attribute *attr,
494 return test_dev_config_show_size_t(buf, test_fw_config->buf_size);
496 static DEVICE_ATTR_RW(config_buf_size);
498 static ssize_t config_file_offset_store(struct device *dev,
499 struct device_attribute *attr,
500 const char *buf, size_t count)
504 mutex_lock(&test_fw_mutex);
505 if (test_fw_config->reqs) {
506 pr_err("Must call release_all_firmware prior to changing config\n");
508 mutex_unlock(&test_fw_mutex);
512 rc = __test_dev_config_update_size_t(buf, count,
513 &test_fw_config->file_offset);
514 mutex_unlock(&test_fw_mutex);
520 static ssize_t config_file_offset_show(struct device *dev,
521 struct device_attribute *attr,
524 return test_dev_config_show_size_t(buf, test_fw_config->file_offset);
526 static DEVICE_ATTR_RW(config_file_offset);
528 static ssize_t config_partial_store(struct device *dev,
529 struct device_attribute *attr,
530 const char *buf, size_t count)
532 return test_dev_config_update_bool(buf,
534 &test_fw_config->partial);
537 static ssize_t config_partial_show(struct device *dev,
538 struct device_attribute *attr,
541 return test_dev_config_show_bool(buf, test_fw_config->partial);
543 static DEVICE_ATTR_RW(config_partial);
545 static ssize_t config_sync_direct_store(struct device *dev,
546 struct device_attribute *attr,
547 const char *buf, size_t count)
549 int rc = test_dev_config_update_bool(buf, count,
550 &test_fw_config->sync_direct);
553 test_fw_config->req_firmware = test_fw_config->sync_direct ?
554 request_firmware_direct :
559 static ssize_t config_sync_direct_show(struct device *dev,
560 struct device_attribute *attr,
563 return test_dev_config_show_bool(buf, test_fw_config->sync_direct);
565 static DEVICE_ATTR_RW(config_sync_direct);
567 static ssize_t config_send_uevent_store(struct device *dev,
568 struct device_attribute *attr,
569 const char *buf, size_t count)
571 return test_dev_config_update_bool(buf, count,
572 &test_fw_config->send_uevent);
575 static ssize_t config_send_uevent_show(struct device *dev,
576 struct device_attribute *attr,
579 return test_dev_config_show_bool(buf, test_fw_config->send_uevent);
581 static DEVICE_ATTR_RW(config_send_uevent);
583 static ssize_t config_read_fw_idx_store(struct device *dev,
584 struct device_attribute *attr,
585 const char *buf, size_t count)
587 return test_dev_config_update_u8(buf, count,
588 &test_fw_config->read_fw_idx);
591 static ssize_t config_read_fw_idx_show(struct device *dev,
592 struct device_attribute *attr,
595 return test_dev_config_show_u8(buf, test_fw_config->read_fw_idx);
597 static DEVICE_ATTR_RW(config_read_fw_idx);
600 static ssize_t trigger_request_store(struct device *dev,
601 struct device_attribute *attr,
602 const char *buf, size_t count)
607 name = kstrndup(buf, count, GFP_KERNEL);
611 pr_info("loading '%s'\n", name);
613 mutex_lock(&test_fw_mutex);
614 release_firmware(test_firmware);
615 if (test_fw_config->reqs)
616 __test_release_all_firmware();
617 test_firmware = NULL;
618 rc = request_firmware(&test_firmware, name, dev);
620 pr_info("load of '%s' failed: %d\n", name, rc);
623 pr_info("loaded: %zu\n", test_firmware->size);
627 mutex_unlock(&test_fw_mutex);
633 static DEVICE_ATTR_WO(trigger_request);
635 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
636 extern struct list_head efi_embedded_fw_list;
637 extern bool efi_embedded_fw_checked;
639 static ssize_t trigger_request_platform_store(struct device *dev,
640 struct device_attribute *attr,
641 const char *buf, size_t count)
643 static const u8 test_data[] = {
644 0x55, 0xaa, 0x55, 0xaa, 0x01, 0x02, 0x03, 0x04,
645 0x55, 0xaa, 0x55, 0xaa, 0x05, 0x06, 0x07, 0x08,
646 0x55, 0xaa, 0x55, 0xaa, 0x10, 0x20, 0x30, 0x40,
647 0x55, 0xaa, 0x55, 0xaa, 0x50, 0x60, 0x70, 0x80
649 struct efi_embedded_fw efi_embedded_fw;
650 const struct firmware *firmware = NULL;
651 bool saved_efi_embedded_fw_checked;
655 name = kstrndup(buf, count, GFP_KERNEL);
659 pr_info("inserting test platform fw '%s'\n", name);
660 efi_embedded_fw.name = name;
661 efi_embedded_fw.data = (void *)test_data;
662 efi_embedded_fw.length = sizeof(test_data);
663 list_add(&efi_embedded_fw.list, &efi_embedded_fw_list);
664 saved_efi_embedded_fw_checked = efi_embedded_fw_checked;
665 efi_embedded_fw_checked = true;
667 pr_info("loading '%s'\n", name);
668 rc = firmware_request_platform(&firmware, name, dev);
670 pr_info("load of '%s' failed: %d\n", name, rc);
673 if (firmware->size != sizeof(test_data) ||
674 memcmp(firmware->data, test_data, sizeof(test_data)) != 0) {
675 pr_info("firmware contents mismatch for '%s'\n", name);
679 pr_info("loaded: %zu\n", firmware->size);
683 efi_embedded_fw_checked = saved_efi_embedded_fw_checked;
684 release_firmware(firmware);
685 list_del(&efi_embedded_fw.list);
690 static DEVICE_ATTR_WO(trigger_request_platform);
693 static DECLARE_COMPLETION(async_fw_done);
695 static void trigger_async_request_cb(const struct firmware *fw, void *context)
698 complete(&async_fw_done);
701 static ssize_t trigger_async_request_store(struct device *dev,
702 struct device_attribute *attr,
703 const char *buf, size_t count)
708 name = kstrndup(buf, count, GFP_KERNEL);
712 pr_info("loading '%s'\n", name);
714 mutex_lock(&test_fw_mutex);
715 release_firmware(test_firmware);
716 test_firmware = NULL;
717 if (test_fw_config->reqs)
718 __test_release_all_firmware();
719 rc = request_firmware_nowait(THIS_MODULE, 1, name, dev, GFP_KERNEL,
720 NULL, trigger_async_request_cb);
722 pr_info("async load of '%s' failed: %d\n", name, rc);
726 /* Free 'name' ASAP, to test for race conditions */
729 wait_for_completion(&async_fw_done);
732 pr_info("loaded: %zu\n", test_firmware->size);
735 pr_err("failed to async load firmware\n");
740 mutex_unlock(&test_fw_mutex);
744 static DEVICE_ATTR_WO(trigger_async_request);
746 static ssize_t trigger_custom_fallback_store(struct device *dev,
747 struct device_attribute *attr,
748 const char *buf, size_t count)
753 name = kstrndup(buf, count, GFP_KERNEL);
757 pr_info("loading '%s' using custom fallback mechanism\n", name);
759 mutex_lock(&test_fw_mutex);
760 release_firmware(test_firmware);
761 if (test_fw_config->reqs)
762 __test_release_all_firmware();
763 test_firmware = NULL;
764 rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, name,
765 dev, GFP_KERNEL, NULL,
766 trigger_async_request_cb);
768 pr_info("async load of '%s' failed: %d\n", name, rc);
772 /* Free 'name' ASAP, to test for race conditions */
775 wait_for_completion(&async_fw_done);
778 pr_info("loaded: %zu\n", test_firmware->size);
781 pr_err("failed to async load firmware\n");
786 mutex_unlock(&test_fw_mutex);
790 static DEVICE_ATTR_WO(trigger_custom_fallback);
792 static int test_fw_run_batch_request(void *data)
794 struct test_batched_req *req = data;
797 test_fw_config->test_result = -EINVAL;
801 if (test_fw_config->into_buf) {
804 test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL);
808 if (test_fw_config->partial)
809 req->rc = request_partial_firmware_into_buf
814 test_fw_config->buf_size,
815 test_fw_config->file_offset);
817 req->rc = request_firmware_into_buf
822 test_fw_config->buf_size);
826 req->fw_buf = test_buf;
828 req->rc = test_fw_config->req_firmware(&req->fw,
834 pr_info("#%u: batched sync load failed: %d\n",
836 if (!test_fw_config->test_result)
837 test_fw_config->test_result = req->rc;
838 } else if (req->fw) {
840 pr_info("#%u: batched sync loaded %zu\n",
841 req->idx, req->fw->size);
843 complete(&req->completion);
851 * We use a kthread as otherwise the kernel serializes all our sync requests
852 * and we would not be able to mimic batched requests on a sync call. Batched
853 * requests on a sync call can for instance happen on a device driver when
854 * multiple cards are used and firmware loading happens outside of probe.
856 static ssize_t trigger_batched_requests_store(struct device *dev,
857 struct device_attribute *attr,
858 const char *buf, size_t count)
860 struct test_batched_req *req;
864 mutex_lock(&test_fw_mutex);
866 if (test_fw_config->reqs) {
871 test_fw_config->reqs =
872 vzalloc(array3_size(sizeof(struct test_batched_req),
873 test_fw_config->num_requests, 2));
874 if (!test_fw_config->reqs) {
879 pr_info("batched sync firmware loading '%s' %u times\n",
880 test_fw_config->name, test_fw_config->num_requests);
882 for (i = 0; i < test_fw_config->num_requests; i++) {
883 req = &test_fw_config->reqs[i];
886 req->name = test_fw_config->name;
889 init_completion(&req->completion);
890 req->task = kthread_run(test_fw_run_batch_request, req,
891 "%s-%u", KBUILD_MODNAME, req->idx);
892 if (!req->task || IS_ERR(req->task)) {
893 pr_err("Setting up thread %u failed\n", req->idx);
903 * We require an explicit release to enable more time and delay of
904 * calling release_firmware() to improve our chances of forcing a
905 * batched request. If we instead called release_firmware() right away
906 * then we might miss on an opportunity of having a successful firmware
907 * request pass on the opportunity to be come a batched request.
911 for (i = 0; i < test_fw_config->num_requests; i++) {
912 req = &test_fw_config->reqs[i];
913 if (req->task || req->sent)
914 wait_for_completion(&req->completion);
917 /* Override any worker error if we had a general setup error */
919 test_fw_config->test_result = rc;
922 mutex_unlock(&test_fw_mutex);
926 static DEVICE_ATTR_WO(trigger_batched_requests);
929 * We wait for each callback to return with the lock held, no need to lock here
931 static void trigger_batched_cb(const struct firmware *fw, void *context)
933 struct test_batched_req *req = context;
936 test_fw_config->test_result = -EINVAL;
940 /* forces *some* batched requests to queue up */
947 * Unfortunately the firmware API gives us nothing other than a null FW
948 * if the firmware was not found on async requests. Best we can do is
949 * just assume -ENOENT. A better API would pass the actual return
950 * value to the callback.
952 if (!fw && !test_fw_config->test_result)
953 test_fw_config->test_result = -ENOENT;
955 complete(&req->completion);
959 ssize_t trigger_batched_requests_async_store(struct device *dev,
960 struct device_attribute *attr,
961 const char *buf, size_t count)
963 struct test_batched_req *req;
968 mutex_lock(&test_fw_mutex);
970 if (test_fw_config->reqs) {
975 test_fw_config->reqs =
976 vzalloc(array3_size(sizeof(struct test_batched_req),
977 test_fw_config->num_requests, 2));
978 if (!test_fw_config->reqs) {
983 pr_info("batched loading '%s' custom fallback mechanism %u times\n",
984 test_fw_config->name, test_fw_config->num_requests);
986 send_uevent = test_fw_config->send_uevent ? FW_ACTION_HOTPLUG :
989 for (i = 0; i < test_fw_config->num_requests; i++) {
990 req = &test_fw_config->reqs[i];
991 req->name = test_fw_config->name;
995 init_completion(&req->completion);
996 rc = request_firmware_nowait(THIS_MODULE, send_uevent,
998 dev, GFP_KERNEL, req,
1001 pr_info("#%u: batched async load failed setup: %d\n",
1014 * We require an explicit release to enable more time and delay of
1015 * calling release_firmware() to improve our chances of forcing a
1016 * batched request. If we instead called release_firmware() right away
1017 * then we might miss on an opportunity of having a successful firmware
1018 * request pass on the opportunity to be come a batched request.
1021 for (i = 0; i < test_fw_config->num_requests; i++) {
1022 req = &test_fw_config->reqs[i];
1024 wait_for_completion(&req->completion);
1027 /* Override any worker error if we had a general setup error */
1029 test_fw_config->test_result = rc;
1032 mutex_unlock(&test_fw_mutex);
1036 static DEVICE_ATTR_WO(trigger_batched_requests_async);
1038 static ssize_t test_result_show(struct device *dev,
1039 struct device_attribute *attr,
1042 return test_dev_config_show_int(buf, test_fw_config->test_result);
1044 static DEVICE_ATTR_RO(test_result);
1046 static ssize_t release_all_firmware_store(struct device *dev,
1047 struct device_attribute *attr,
1048 const char *buf, size_t count)
1050 test_release_all_firmware();
1053 static DEVICE_ATTR_WO(release_all_firmware);
1055 static ssize_t read_firmware_show(struct device *dev,
1056 struct device_attribute *attr,
1059 struct test_batched_req *req;
1063 mutex_lock(&test_fw_mutex);
1065 idx = test_fw_config->read_fw_idx;
1066 if (idx >= test_fw_config->num_requests) {
1071 if (!test_fw_config->reqs) {
1076 req = &test_fw_config->reqs[idx];
1078 pr_err("#%u: failed to async load firmware\n", idx);
1083 pr_info("#%u: loaded %zu\n", idx, req->fw->size);
1085 if (req->fw->size > PAGE_SIZE) {
1086 pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
1090 memcpy(buf, req->fw->data, req->fw->size);
1094 mutex_unlock(&test_fw_mutex);
1098 static DEVICE_ATTR_RO(read_firmware);
1100 #define TEST_FW_DEV_ATTR(name) &dev_attr_##name.attr
1102 static struct attribute *test_dev_attrs[] = {
1103 TEST_FW_DEV_ATTR(reset),
1105 TEST_FW_DEV_ATTR(config),
1106 TEST_FW_DEV_ATTR(config_name),
1107 TEST_FW_DEV_ATTR(config_num_requests),
1108 TEST_FW_DEV_ATTR(config_into_buf),
1109 TEST_FW_DEV_ATTR(config_buf_size),
1110 TEST_FW_DEV_ATTR(config_file_offset),
1111 TEST_FW_DEV_ATTR(config_partial),
1112 TEST_FW_DEV_ATTR(config_sync_direct),
1113 TEST_FW_DEV_ATTR(config_send_uevent),
1114 TEST_FW_DEV_ATTR(config_read_fw_idx),
1116 /* These don't use the config at all - they could be ported! */
1117 TEST_FW_DEV_ATTR(trigger_request),
1118 TEST_FW_DEV_ATTR(trigger_async_request),
1119 TEST_FW_DEV_ATTR(trigger_custom_fallback),
1120 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
1121 TEST_FW_DEV_ATTR(trigger_request_platform),
1124 /* These use the config and can use the test_result */
1125 TEST_FW_DEV_ATTR(trigger_batched_requests),
1126 TEST_FW_DEV_ATTR(trigger_batched_requests_async),
1128 TEST_FW_DEV_ATTR(release_all_firmware),
1129 TEST_FW_DEV_ATTR(test_result),
1130 TEST_FW_DEV_ATTR(read_firmware),
1134 ATTRIBUTE_GROUPS(test_dev);
1136 static struct miscdevice test_fw_misc_device = {
1137 .minor = MISC_DYNAMIC_MINOR,
1138 .name = "test_firmware",
1139 .fops = &test_fw_fops,
1140 .groups = test_dev_groups,
1143 static int __init test_firmware_init(void)
1147 test_fw_config = kzalloc(sizeof(struct test_config), GFP_KERNEL);
1148 if (!test_fw_config)
1151 rc = __test_firmware_config_init();
1153 kfree(test_fw_config);
1154 pr_err("could not init firmware test config: %d\n", rc);
1158 rc = misc_register(&test_fw_misc_device);
1160 __test_firmware_config_free();
1161 kfree(test_fw_config);
1162 pr_err("could not register misc device: %d\n", rc);
1166 pr_warn("interface ready\n");
1171 module_init(test_firmware_init);
1173 static void __exit test_firmware_exit(void)
1175 mutex_lock(&test_fw_mutex);
1176 release_firmware(test_firmware);
1177 misc_deregister(&test_fw_misc_device);
1178 __test_firmware_config_free();
1179 kfree(test_fw_config);
1180 mutex_unlock(&test_fw_mutex);
1182 pr_warn("removed interface\n");
1185 module_exit(test_firmware_exit);
1187 MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
1188 MODULE_LICENSE("GPL");