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/kthread.h>
26 #include <linux/vmalloc.h>
27 #include <linux/efi_embedded_fw.h>
29 MODULE_IMPORT_NS(TEST_FIRMWARE
);
31 #define TEST_FIRMWARE_NAME "test-firmware.bin"
32 #define TEST_FIRMWARE_NUM_REQS 4
33 #define TEST_FIRMWARE_BUF_SIZE SZ_1K
35 static DEFINE_MUTEX(test_fw_mutex
);
36 static const struct firmware
*test_firmware
;
38 struct test_batched_req
{
42 const struct firmware
*fw
;
44 struct completion completion
;
45 struct task_struct
*task
;
50 * test_config - represents configuration for the test for different triggers
52 * @name: the name of the firmware file to look for
53 * @into_buf: when the into_buf is used if this is true
54 * request_firmware_into_buf() will be used instead.
55 * @buf_size: size of buf to allocate when into_buf is true
56 * @file_offset: file offset to request when calling request_firmware_into_buf
57 * @partial: partial read opt when calling request_firmware_into_buf
58 * @sync_direct: when the sync trigger is used if this is true
59 * request_firmware_direct() will be used instead.
60 * @send_uevent: whether or not to send a uevent for async requests
61 * @num_requests: number of requests to try per test case. This is trigger
63 * @reqs: stores all requests information
64 * @read_fw_idx: index of thread from which we want to read firmware results
65 * from through the read_fw trigger.
66 * @test_result: a test may use this to collect the result from the call
67 * of the request_firmware*() calls used in their tests. In order of
68 * priority we always keep first any setup error. If no setup errors were
69 * found then we move on to the first error encountered while running the
70 * API. Note that for async calls this typically will be a successful
71 * result (0) unless of course you've used bogus parameters, or the system
72 * is out of memory. In the async case the callback is expected to do a
73 * bit more homework to figure out what happened, unfortunately the only
74 * information passed today on error is the fact that no firmware was
75 * found so we can only assume -ENOENT on async calls if the firmware is
78 * Errors you can expect:
82 * 0: success for sync, for async it means request was sent
83 * -EINVAL: invalid parameters or request
84 * -ENOENT: files not found
88 * -ENOMEM: memory pressure on system
89 * -ENODEV: out of number of devices to test
90 * -EINVAL: an unexpected error has occurred
91 * @req_firmware: if @sync_direct is true this is set to
92 * request_firmware_direct(), otherwise request_firmware()
106 * These below don't belong her but we'll move them once we create
107 * a struct fw_test_device and stuff the misc_dev under there later.
109 struct test_batched_req
*reqs
;
111 int (*req_firmware
)(const struct firmware
**fw
, const char *name
,
112 struct device
*device
);
115 static struct test_config
*test_fw_config
;
117 static ssize_t
test_fw_misc_read(struct file
*f
, char __user
*buf
,
118 size_t size
, loff_t
*offset
)
122 mutex_lock(&test_fw_mutex
);
124 rc
= simple_read_from_buffer(buf
, size
, offset
,
126 test_firmware
->size
);
127 mutex_unlock(&test_fw_mutex
);
131 static const struct file_operations test_fw_fops
= {
132 .owner
= THIS_MODULE
,
133 .read
= test_fw_misc_read
,
136 static void __test_release_all_firmware(void)
138 struct test_batched_req
*req
;
141 if (!test_fw_config
->reqs
)
144 for (i
= 0; i
< test_fw_config
->num_requests
; i
++) {
145 req
= &test_fw_config
->reqs
[i
];
147 release_firmware(req
->fw
);
150 vfree(test_fw_config
->reqs
);
151 test_fw_config
->reqs
= NULL
;
154 static void test_release_all_firmware(void)
156 mutex_lock(&test_fw_mutex
);
157 __test_release_all_firmware();
158 mutex_unlock(&test_fw_mutex
);
162 static void __test_firmware_config_free(void)
164 __test_release_all_firmware();
165 kfree_const(test_fw_config
->name
);
166 test_fw_config
->name
= NULL
;
170 * XXX: move to kstrncpy() once merged.
172 * Users should use kfree_const() when freeing these.
174 static int __kstrncpy(char **dst
, const char *name
, size_t count
, gfp_t gfp
)
176 *dst
= kstrndup(name
, count
, gfp
);
182 static int __test_firmware_config_init(void)
186 ret
= __kstrncpy(&test_fw_config
->name
, TEST_FIRMWARE_NAME
,
187 strlen(TEST_FIRMWARE_NAME
), GFP_KERNEL
);
191 test_fw_config
->num_requests
= TEST_FIRMWARE_NUM_REQS
;
192 test_fw_config
->send_uevent
= true;
193 test_fw_config
->into_buf
= false;
194 test_fw_config
->buf_size
= TEST_FIRMWARE_BUF_SIZE
;
195 test_fw_config
->file_offset
= 0;
196 test_fw_config
->partial
= false;
197 test_fw_config
->sync_direct
= false;
198 test_fw_config
->req_firmware
= request_firmware
;
199 test_fw_config
->test_result
= 0;
200 test_fw_config
->reqs
= NULL
;
205 __test_firmware_config_free();
209 static ssize_t
reset_store(struct device
*dev
,
210 struct device_attribute
*attr
,
211 const char *buf
, size_t count
)
215 mutex_lock(&test_fw_mutex
);
217 __test_firmware_config_free();
219 ret
= __test_firmware_config_init();
222 pr_err("could not alloc settings for config trigger: %d\n",
231 mutex_unlock(&test_fw_mutex
);
235 static DEVICE_ATTR_WO(reset
);
237 static ssize_t
config_show(struct device
*dev
,
238 struct device_attribute
*attr
,
243 mutex_lock(&test_fw_mutex
);
245 len
+= scnprintf(buf
, PAGE_SIZE
- len
,
246 "Custom trigger configuration for: %s\n",
249 if (test_fw_config
->name
)
250 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
252 test_fw_config
->name
);
254 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
257 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
258 "num_requests:\t%u\n", test_fw_config
->num_requests
);
260 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
261 "send_uevent:\t\t%s\n",
262 test_fw_config
->send_uevent
?
263 "FW_ACTION_HOTPLUG" :
264 "FW_ACTION_NOHOTPLUG");
265 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
267 test_fw_config
->into_buf
? "true" : "false");
268 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
269 "buf_size:\t%zu\n", test_fw_config
->buf_size
);
270 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
271 "file_offset:\t%zu\n", test_fw_config
->file_offset
);
272 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
274 test_fw_config
->partial
? "true" : "false");
275 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
276 "sync_direct:\t\t%s\n",
277 test_fw_config
->sync_direct
? "true" : "false");
278 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
279 "read_fw_idx:\t%u\n", test_fw_config
->read_fw_idx
);
281 mutex_unlock(&test_fw_mutex
);
285 static DEVICE_ATTR_RO(config
);
287 static ssize_t
config_name_store(struct device
*dev
,
288 struct device_attribute
*attr
,
289 const char *buf
, size_t count
)
293 mutex_lock(&test_fw_mutex
);
294 kfree_const(test_fw_config
->name
);
295 ret
= __kstrncpy(&test_fw_config
->name
, buf
, count
, GFP_KERNEL
);
296 mutex_unlock(&test_fw_mutex
);
302 * As per sysfs_kf_seq_show() the buf is max PAGE_SIZE.
304 static ssize_t
config_test_show_str(char *dst
,
309 mutex_lock(&test_fw_mutex
);
310 len
= snprintf(dst
, PAGE_SIZE
, "%s\n", src
);
311 mutex_unlock(&test_fw_mutex
);
316 static int test_dev_config_update_bool(const char *buf
, size_t size
,
321 mutex_lock(&test_fw_mutex
);
322 if (strtobool(buf
, cfg
) < 0)
326 mutex_unlock(&test_fw_mutex
);
331 static ssize_t
test_dev_config_show_bool(char *buf
, bool val
)
333 return snprintf(buf
, PAGE_SIZE
, "%d\n", val
);
336 static int test_dev_config_update_size_t(const char *buf
,
343 ret
= kstrtol(buf
, 10, &new);
347 mutex_lock(&test_fw_mutex
);
348 *(size_t *)cfg
= new;
349 mutex_unlock(&test_fw_mutex
);
351 /* Always return full write size even if we didn't consume all */
355 static ssize_t
test_dev_config_show_size_t(char *buf
, size_t val
)
357 return snprintf(buf
, PAGE_SIZE
, "%zu\n", val
);
360 static ssize_t
test_dev_config_show_int(char *buf
, int val
)
362 return snprintf(buf
, PAGE_SIZE
, "%d\n", val
);
365 static int test_dev_config_update_u8(const char *buf
, size_t size
, u8
*cfg
)
370 ret
= kstrtou8(buf
, 10, &val
);
374 mutex_lock(&test_fw_mutex
);
376 mutex_unlock(&test_fw_mutex
);
378 /* Always return full write size even if we didn't consume all */
382 static ssize_t
test_dev_config_show_u8(char *buf
, u8 val
)
384 return snprintf(buf
, PAGE_SIZE
, "%u\n", val
);
387 static ssize_t
config_name_show(struct device
*dev
,
388 struct device_attribute
*attr
,
391 return config_test_show_str(buf
, test_fw_config
->name
);
393 static DEVICE_ATTR_RW(config_name
);
395 static ssize_t
config_num_requests_store(struct device
*dev
,
396 struct device_attribute
*attr
,
397 const char *buf
, size_t count
)
401 mutex_lock(&test_fw_mutex
);
402 if (test_fw_config
->reqs
) {
403 pr_err("Must call release_all_firmware prior to changing config\n");
405 mutex_unlock(&test_fw_mutex
);
408 mutex_unlock(&test_fw_mutex
);
410 rc
= test_dev_config_update_u8(buf
, count
,
411 &test_fw_config
->num_requests
);
417 static ssize_t
config_num_requests_show(struct device
*dev
,
418 struct device_attribute
*attr
,
421 return test_dev_config_show_u8(buf
, test_fw_config
->num_requests
);
423 static DEVICE_ATTR_RW(config_num_requests
);
425 static ssize_t
config_into_buf_store(struct device
*dev
,
426 struct device_attribute
*attr
,
427 const char *buf
, size_t count
)
429 return test_dev_config_update_bool(buf
,
431 &test_fw_config
->into_buf
);
434 static ssize_t
config_into_buf_show(struct device
*dev
,
435 struct device_attribute
*attr
,
438 return test_dev_config_show_bool(buf
, test_fw_config
->into_buf
);
440 static DEVICE_ATTR_RW(config_into_buf
);
442 static ssize_t
config_buf_size_store(struct device
*dev
,
443 struct device_attribute
*attr
,
444 const char *buf
, size_t count
)
448 mutex_lock(&test_fw_mutex
);
449 if (test_fw_config
->reqs
) {
450 pr_err("Must call release_all_firmware prior to changing config\n");
452 mutex_unlock(&test_fw_mutex
);
455 mutex_unlock(&test_fw_mutex
);
457 rc
= test_dev_config_update_size_t(buf
, count
,
458 &test_fw_config
->buf_size
);
464 static ssize_t
config_buf_size_show(struct device
*dev
,
465 struct device_attribute
*attr
,
468 return test_dev_config_show_size_t(buf
, test_fw_config
->buf_size
);
470 static DEVICE_ATTR_RW(config_buf_size
);
472 static ssize_t
config_file_offset_store(struct device
*dev
,
473 struct device_attribute
*attr
,
474 const char *buf
, size_t count
)
478 mutex_lock(&test_fw_mutex
);
479 if (test_fw_config
->reqs
) {
480 pr_err("Must call release_all_firmware prior to changing config\n");
482 mutex_unlock(&test_fw_mutex
);
485 mutex_unlock(&test_fw_mutex
);
487 rc
= test_dev_config_update_size_t(buf
, count
,
488 &test_fw_config
->file_offset
);
494 static ssize_t
config_file_offset_show(struct device
*dev
,
495 struct device_attribute
*attr
,
498 return test_dev_config_show_size_t(buf
, test_fw_config
->file_offset
);
500 static DEVICE_ATTR_RW(config_file_offset
);
502 static ssize_t
config_partial_store(struct device
*dev
,
503 struct device_attribute
*attr
,
504 const char *buf
, size_t count
)
506 return test_dev_config_update_bool(buf
,
508 &test_fw_config
->partial
);
511 static ssize_t
config_partial_show(struct device
*dev
,
512 struct device_attribute
*attr
,
515 return test_dev_config_show_bool(buf
, test_fw_config
->partial
);
517 static DEVICE_ATTR_RW(config_partial
);
519 static ssize_t
config_sync_direct_store(struct device
*dev
,
520 struct device_attribute
*attr
,
521 const char *buf
, size_t count
)
523 int rc
= test_dev_config_update_bool(buf
, count
,
524 &test_fw_config
->sync_direct
);
527 test_fw_config
->req_firmware
= test_fw_config
->sync_direct
?
528 request_firmware_direct
:
533 static ssize_t
config_sync_direct_show(struct device
*dev
,
534 struct device_attribute
*attr
,
537 return test_dev_config_show_bool(buf
, test_fw_config
->sync_direct
);
539 static DEVICE_ATTR_RW(config_sync_direct
);
541 static ssize_t
config_send_uevent_store(struct device
*dev
,
542 struct device_attribute
*attr
,
543 const char *buf
, size_t count
)
545 return test_dev_config_update_bool(buf
, count
,
546 &test_fw_config
->send_uevent
);
549 static ssize_t
config_send_uevent_show(struct device
*dev
,
550 struct device_attribute
*attr
,
553 return test_dev_config_show_bool(buf
, test_fw_config
->send_uevent
);
555 static DEVICE_ATTR_RW(config_send_uevent
);
557 static ssize_t
config_read_fw_idx_store(struct device
*dev
,
558 struct device_attribute
*attr
,
559 const char *buf
, size_t count
)
561 return test_dev_config_update_u8(buf
, count
,
562 &test_fw_config
->read_fw_idx
);
565 static ssize_t
config_read_fw_idx_show(struct device
*dev
,
566 struct device_attribute
*attr
,
569 return test_dev_config_show_u8(buf
, test_fw_config
->read_fw_idx
);
571 static DEVICE_ATTR_RW(config_read_fw_idx
);
574 static ssize_t
trigger_request_store(struct device
*dev
,
575 struct device_attribute
*attr
,
576 const char *buf
, size_t count
)
581 name
= kstrndup(buf
, count
, GFP_KERNEL
);
585 pr_info("loading '%s'\n", name
);
587 mutex_lock(&test_fw_mutex
);
588 release_firmware(test_firmware
);
589 test_firmware
= NULL
;
590 rc
= request_firmware(&test_firmware
, name
, dev
);
592 pr_info("load of '%s' failed: %d\n", name
, rc
);
595 pr_info("loaded: %zu\n", test_firmware
->size
);
599 mutex_unlock(&test_fw_mutex
);
605 static DEVICE_ATTR_WO(trigger_request
);
607 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
608 extern struct list_head efi_embedded_fw_list
;
609 extern bool efi_embedded_fw_checked
;
611 static ssize_t
trigger_request_platform_store(struct device
*dev
,
612 struct device_attribute
*attr
,
613 const char *buf
, size_t count
)
615 static const u8 test_data
[] = {
616 0x55, 0xaa, 0x55, 0xaa, 0x01, 0x02, 0x03, 0x04,
617 0x55, 0xaa, 0x55, 0xaa, 0x05, 0x06, 0x07, 0x08,
618 0x55, 0xaa, 0x55, 0xaa, 0x10, 0x20, 0x30, 0x40,
619 0x55, 0xaa, 0x55, 0xaa, 0x50, 0x60, 0x70, 0x80
621 struct efi_embedded_fw efi_embedded_fw
;
622 const struct firmware
*firmware
= NULL
;
623 bool saved_efi_embedded_fw_checked
;
627 name
= kstrndup(buf
, count
, GFP_KERNEL
);
631 pr_info("inserting test platform fw '%s'\n", name
);
632 efi_embedded_fw
.name
= name
;
633 efi_embedded_fw
.data
= (void *)test_data
;
634 efi_embedded_fw
.length
= sizeof(test_data
);
635 list_add(&efi_embedded_fw
.list
, &efi_embedded_fw_list
);
636 saved_efi_embedded_fw_checked
= efi_embedded_fw_checked
;
637 efi_embedded_fw_checked
= true;
639 pr_info("loading '%s'\n", name
);
640 rc
= firmware_request_platform(&firmware
, name
, dev
);
642 pr_info("load of '%s' failed: %d\n", name
, rc
);
645 if (firmware
->size
!= sizeof(test_data
) ||
646 memcmp(firmware
->data
, test_data
, sizeof(test_data
)) != 0) {
647 pr_info("firmware contents mismatch for '%s'\n", name
);
651 pr_info("loaded: %zu\n", firmware
->size
);
655 efi_embedded_fw_checked
= saved_efi_embedded_fw_checked
;
656 release_firmware(firmware
);
657 list_del(&efi_embedded_fw
.list
);
662 static DEVICE_ATTR_WO(trigger_request_platform
);
665 static DECLARE_COMPLETION(async_fw_done
);
667 static void trigger_async_request_cb(const struct firmware
*fw
, void *context
)
670 complete(&async_fw_done
);
673 static ssize_t
trigger_async_request_store(struct device
*dev
,
674 struct device_attribute
*attr
,
675 const char *buf
, size_t count
)
680 name
= kstrndup(buf
, count
, GFP_KERNEL
);
684 pr_info("loading '%s'\n", name
);
686 mutex_lock(&test_fw_mutex
);
687 release_firmware(test_firmware
);
688 test_firmware
= NULL
;
689 rc
= request_firmware_nowait(THIS_MODULE
, 1, name
, dev
, GFP_KERNEL
,
690 NULL
, trigger_async_request_cb
);
692 pr_info("async load of '%s' failed: %d\n", name
, rc
);
696 /* Free 'name' ASAP, to test for race conditions */
699 wait_for_completion(&async_fw_done
);
702 pr_info("loaded: %zu\n", test_firmware
->size
);
705 pr_err("failed to async load firmware\n");
710 mutex_unlock(&test_fw_mutex
);
714 static DEVICE_ATTR_WO(trigger_async_request
);
716 static ssize_t
trigger_custom_fallback_store(struct device
*dev
,
717 struct device_attribute
*attr
,
718 const char *buf
, size_t count
)
723 name
= kstrndup(buf
, count
, GFP_KERNEL
);
727 pr_info("loading '%s' using custom fallback mechanism\n", name
);
729 mutex_lock(&test_fw_mutex
);
730 release_firmware(test_firmware
);
731 test_firmware
= NULL
;
732 rc
= request_firmware_nowait(THIS_MODULE
, FW_ACTION_NOHOTPLUG
, name
,
733 dev
, GFP_KERNEL
, NULL
,
734 trigger_async_request_cb
);
736 pr_info("async load of '%s' failed: %d\n", name
, rc
);
740 /* Free 'name' ASAP, to test for race conditions */
743 wait_for_completion(&async_fw_done
);
746 pr_info("loaded: %zu\n", test_firmware
->size
);
749 pr_err("failed to async load firmware\n");
754 mutex_unlock(&test_fw_mutex
);
758 static DEVICE_ATTR_WO(trigger_custom_fallback
);
760 static int test_fw_run_batch_request(void *data
)
762 struct test_batched_req
*req
= data
;
765 test_fw_config
->test_result
= -EINVAL
;
769 if (test_fw_config
->into_buf
) {
772 test_buf
= kzalloc(TEST_FIRMWARE_BUF_SIZE
, GFP_KERNEL
);
776 if (test_fw_config
->partial
)
777 req
->rc
= request_partial_firmware_into_buf
782 test_fw_config
->buf_size
,
783 test_fw_config
->file_offset
);
785 req
->rc
= request_firmware_into_buf
790 test_fw_config
->buf_size
);
794 req
->rc
= test_fw_config
->req_firmware(&req
->fw
,
800 pr_info("#%u: batched sync load failed: %d\n",
802 if (!test_fw_config
->test_result
)
803 test_fw_config
->test_result
= req
->rc
;
804 } else if (req
->fw
) {
806 pr_info("#%u: batched sync loaded %zu\n",
807 req
->idx
, req
->fw
->size
);
809 complete(&req
->completion
);
817 * We use a kthread as otherwise the kernel serializes all our sync requests
818 * and we would not be able to mimic batched requests on a sync call. Batched
819 * requests on a sync call can for instance happen on a device driver when
820 * multiple cards are used and firmware loading happens outside of probe.
822 static ssize_t
trigger_batched_requests_store(struct device
*dev
,
823 struct device_attribute
*attr
,
824 const char *buf
, size_t count
)
826 struct test_batched_req
*req
;
830 mutex_lock(&test_fw_mutex
);
832 test_fw_config
->reqs
=
833 vzalloc(array3_size(sizeof(struct test_batched_req
),
834 test_fw_config
->num_requests
, 2));
835 if (!test_fw_config
->reqs
) {
840 pr_info("batched sync firmware loading '%s' %u times\n",
841 test_fw_config
->name
, test_fw_config
->num_requests
);
843 for (i
= 0; i
< test_fw_config
->num_requests
; i
++) {
844 req
= &test_fw_config
->reqs
[i
];
847 req
->name
= test_fw_config
->name
;
849 init_completion(&req
->completion
);
850 req
->task
= kthread_run(test_fw_run_batch_request
, req
,
851 "%s-%u", KBUILD_MODNAME
, req
->idx
);
852 if (!req
->task
|| IS_ERR(req
->task
)) {
853 pr_err("Setting up thread %u failed\n", req
->idx
);
863 * We require an explicit release to enable more time and delay of
864 * calling release_firmware() to improve our chances of forcing a
865 * batched request. If we instead called release_firmware() right away
866 * then we might miss on an opportunity of having a successful firmware
867 * request pass on the opportunity to be come a batched request.
871 for (i
= 0; i
< test_fw_config
->num_requests
; i
++) {
872 req
= &test_fw_config
->reqs
[i
];
873 if (req
->task
|| req
->sent
)
874 wait_for_completion(&req
->completion
);
877 /* Override any worker error if we had a general setup error */
879 test_fw_config
->test_result
= rc
;
882 mutex_unlock(&test_fw_mutex
);
886 static DEVICE_ATTR_WO(trigger_batched_requests
);
889 * We wait for each callback to return with the lock held, no need to lock here
891 static void trigger_batched_cb(const struct firmware
*fw
, void *context
)
893 struct test_batched_req
*req
= context
;
896 test_fw_config
->test_result
= -EINVAL
;
900 /* forces *some* batched requests to queue up */
907 * Unfortunately the firmware API gives us nothing other than a null FW
908 * if the firmware was not found on async requests. Best we can do is
909 * just assume -ENOENT. A better API would pass the actual return
910 * value to the callback.
912 if (!fw
&& !test_fw_config
->test_result
)
913 test_fw_config
->test_result
= -ENOENT
;
915 complete(&req
->completion
);
919 ssize_t
trigger_batched_requests_async_store(struct device
*dev
,
920 struct device_attribute
*attr
,
921 const char *buf
, size_t count
)
923 struct test_batched_req
*req
;
928 mutex_lock(&test_fw_mutex
);
930 test_fw_config
->reqs
=
931 vzalloc(array3_size(sizeof(struct test_batched_req
),
932 test_fw_config
->num_requests
, 2));
933 if (!test_fw_config
->reqs
) {
938 pr_info("batched loading '%s' custom fallback mechanism %u times\n",
939 test_fw_config
->name
, test_fw_config
->num_requests
);
941 send_uevent
= test_fw_config
->send_uevent
? FW_ACTION_HOTPLUG
:
944 for (i
= 0; i
< test_fw_config
->num_requests
; i
++) {
945 req
= &test_fw_config
->reqs
[i
];
946 req
->name
= test_fw_config
->name
;
949 init_completion(&req
->completion
);
950 rc
= request_firmware_nowait(THIS_MODULE
, send_uevent
,
952 dev
, GFP_KERNEL
, req
,
955 pr_info("#%u: batched async load failed setup: %d\n",
968 * We require an explicit release to enable more time and delay of
969 * calling release_firmware() to improve our chances of forcing a
970 * batched request. If we instead called release_firmware() right away
971 * then we might miss on an opportunity of having a successful firmware
972 * request pass on the opportunity to be come a batched request.
975 for (i
= 0; i
< test_fw_config
->num_requests
; i
++) {
976 req
= &test_fw_config
->reqs
[i
];
978 wait_for_completion(&req
->completion
);
981 /* Override any worker error if we had a general setup error */
983 test_fw_config
->test_result
= rc
;
986 mutex_unlock(&test_fw_mutex
);
990 static DEVICE_ATTR_WO(trigger_batched_requests_async
);
992 static ssize_t
test_result_show(struct device
*dev
,
993 struct device_attribute
*attr
,
996 return test_dev_config_show_int(buf
, test_fw_config
->test_result
);
998 static DEVICE_ATTR_RO(test_result
);
1000 static ssize_t
release_all_firmware_store(struct device
*dev
,
1001 struct device_attribute
*attr
,
1002 const char *buf
, size_t count
)
1004 test_release_all_firmware();
1007 static DEVICE_ATTR_WO(release_all_firmware
);
1009 static ssize_t
read_firmware_show(struct device
*dev
,
1010 struct device_attribute
*attr
,
1013 struct test_batched_req
*req
;
1017 mutex_lock(&test_fw_mutex
);
1019 idx
= test_fw_config
->read_fw_idx
;
1020 if (idx
>= test_fw_config
->num_requests
) {
1025 if (!test_fw_config
->reqs
) {
1030 req
= &test_fw_config
->reqs
[idx
];
1032 pr_err("#%u: failed to async load firmware\n", idx
);
1037 pr_info("#%u: loaded %zu\n", idx
, req
->fw
->size
);
1039 if (req
->fw
->size
> PAGE_SIZE
) {
1040 pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
1044 memcpy(buf
, req
->fw
->data
, req
->fw
->size
);
1048 mutex_unlock(&test_fw_mutex
);
1052 static DEVICE_ATTR_RO(read_firmware
);
1054 #define TEST_FW_DEV_ATTR(name) &dev_attr_##name.attr
1056 static struct attribute
*test_dev_attrs
[] = {
1057 TEST_FW_DEV_ATTR(reset
),
1059 TEST_FW_DEV_ATTR(config
),
1060 TEST_FW_DEV_ATTR(config_name
),
1061 TEST_FW_DEV_ATTR(config_num_requests
),
1062 TEST_FW_DEV_ATTR(config_into_buf
),
1063 TEST_FW_DEV_ATTR(config_buf_size
),
1064 TEST_FW_DEV_ATTR(config_file_offset
),
1065 TEST_FW_DEV_ATTR(config_partial
),
1066 TEST_FW_DEV_ATTR(config_sync_direct
),
1067 TEST_FW_DEV_ATTR(config_send_uevent
),
1068 TEST_FW_DEV_ATTR(config_read_fw_idx
),
1070 /* These don't use the config at all - they could be ported! */
1071 TEST_FW_DEV_ATTR(trigger_request
),
1072 TEST_FW_DEV_ATTR(trigger_async_request
),
1073 TEST_FW_DEV_ATTR(trigger_custom_fallback
),
1074 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
1075 TEST_FW_DEV_ATTR(trigger_request_platform
),
1078 /* These use the config and can use the test_result */
1079 TEST_FW_DEV_ATTR(trigger_batched_requests
),
1080 TEST_FW_DEV_ATTR(trigger_batched_requests_async
),
1082 TEST_FW_DEV_ATTR(release_all_firmware
),
1083 TEST_FW_DEV_ATTR(test_result
),
1084 TEST_FW_DEV_ATTR(read_firmware
),
1088 ATTRIBUTE_GROUPS(test_dev
);
1090 static struct miscdevice test_fw_misc_device
= {
1091 .minor
= MISC_DYNAMIC_MINOR
,
1092 .name
= "test_firmware",
1093 .fops
= &test_fw_fops
,
1094 .groups
= test_dev_groups
,
1097 static int __init
test_firmware_init(void)
1101 test_fw_config
= kzalloc(sizeof(struct test_config
), GFP_KERNEL
);
1102 if (!test_fw_config
)
1105 rc
= __test_firmware_config_init();
1107 kfree(test_fw_config
);
1108 pr_err("could not init firmware test config: %d\n", rc
);
1112 rc
= misc_register(&test_fw_misc_device
);
1114 kfree(test_fw_config
);
1115 pr_err("could not register misc device: %d\n", rc
);
1119 pr_warn("interface ready\n");
1124 module_init(test_firmware_init
);
1126 static void __exit
test_firmware_exit(void)
1128 mutex_lock(&test_fw_mutex
);
1129 release_firmware(test_firmware
);
1130 misc_deregister(&test_fw_misc_device
);
1131 __test_firmware_config_free();
1132 kfree(test_fw_config
);
1133 mutex_unlock(&test_fw_mutex
);
1135 pr_warn("removed interface\n");
1138 module_exit(test_firmware_exit
);
1140 MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
1141 MODULE_LICENSE("GPL");