]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - lib/test_firmware.c
Merge branch 'next' into for-linus
[mirror_ubuntu-jammy-kernel.git] / lib / test_firmware.c
1 // SPDX-License-Identifier: GPL-2.0-only
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>
16 #include <linux/completion.h>
17 #include <linux/firmware.h>
18 #include <linux/device.h>
19 #include <linux/fs.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>
28
29 MODULE_IMPORT_NS(TEST_FIRMWARE);
30
31 #define TEST_FIRMWARE_NAME "test-firmware.bin"
32 #define TEST_FIRMWARE_NUM_REQS 4
33 #define TEST_FIRMWARE_BUF_SIZE SZ_1K
34
35 static DEFINE_MUTEX(test_fw_mutex);
36 static const struct firmware *test_firmware;
37
38 struct test_batched_req {
39 u8 idx;
40 int rc;
41 bool sent;
42 const struct firmware *fw;
43 const char *name;
44 struct completion completion;
45 struct task_struct *task;
46 struct device *dev;
47 };
48
49 /**
50 * test_config - represents configuration for the test for different triggers
51 *
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 * @sync_direct: when the sync trigger is used if this is true
56 * request_firmware_direct() will be used instead.
57 * @send_uevent: whether or not to send a uevent for async requests
58 * @num_requests: number of requests to try per test case. This is trigger
59 * specific.
60 * @reqs: stores all requests information
61 * @read_fw_idx: index of thread from which we want to read firmware results
62 * from through the read_fw trigger.
63 * @test_result: a test may use this to collect the result from the call
64 * of the request_firmware*() calls used in their tests. In order of
65 * priority we always keep first any setup error. If no setup errors were
66 * found then we move on to the first error encountered while running the
67 * API. Note that for async calls this typically will be a successful
68 * result (0) unless of course you've used bogus parameters, or the system
69 * is out of memory. In the async case the callback is expected to do a
70 * bit more homework to figure out what happened, unfortunately the only
71 * information passed today on error is the fact that no firmware was
72 * found so we can only assume -ENOENT on async calls if the firmware is
73 * NULL.
74 *
75 * Errors you can expect:
76 *
77 * API specific:
78 *
79 * 0: success for sync, for async it means request was sent
80 * -EINVAL: invalid parameters or request
81 * -ENOENT: files not found
82 *
83 * System environment:
84 *
85 * -ENOMEM: memory pressure on system
86 * -ENODEV: out of number of devices to test
87 * -EINVAL: an unexpected error has occurred
88 * @req_firmware: if @sync_direct is true this is set to
89 * request_firmware_direct(), otherwise request_firmware()
90 */
91 struct test_config {
92 char *name;
93 bool into_buf;
94 bool sync_direct;
95 bool send_uevent;
96 u8 num_requests;
97 u8 read_fw_idx;
98
99 /*
100 * These below don't belong her but we'll move them once we create
101 * a struct fw_test_device and stuff the misc_dev under there later.
102 */
103 struct test_batched_req *reqs;
104 int test_result;
105 int (*req_firmware)(const struct firmware **fw, const char *name,
106 struct device *device);
107 };
108
109 static struct test_config *test_fw_config;
110
111 static ssize_t test_fw_misc_read(struct file *f, char __user *buf,
112 size_t size, loff_t *offset)
113 {
114 ssize_t rc = 0;
115
116 mutex_lock(&test_fw_mutex);
117 if (test_firmware)
118 rc = simple_read_from_buffer(buf, size, offset,
119 test_firmware->data,
120 test_firmware->size);
121 mutex_unlock(&test_fw_mutex);
122 return rc;
123 }
124
125 static const struct file_operations test_fw_fops = {
126 .owner = THIS_MODULE,
127 .read = test_fw_misc_read,
128 };
129
130 static void __test_release_all_firmware(void)
131 {
132 struct test_batched_req *req;
133 u8 i;
134
135 if (!test_fw_config->reqs)
136 return;
137
138 for (i = 0; i < test_fw_config->num_requests; i++) {
139 req = &test_fw_config->reqs[i];
140 if (req->fw)
141 release_firmware(req->fw);
142 }
143
144 vfree(test_fw_config->reqs);
145 test_fw_config->reqs = NULL;
146 }
147
148 static void test_release_all_firmware(void)
149 {
150 mutex_lock(&test_fw_mutex);
151 __test_release_all_firmware();
152 mutex_unlock(&test_fw_mutex);
153 }
154
155
156 static void __test_firmware_config_free(void)
157 {
158 __test_release_all_firmware();
159 kfree_const(test_fw_config->name);
160 test_fw_config->name = NULL;
161 }
162
163 /*
164 * XXX: move to kstrncpy() once merged.
165 *
166 * Users should use kfree_const() when freeing these.
167 */
168 static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp)
169 {
170 *dst = kstrndup(name, count, gfp);
171 if (!*dst)
172 return -ENOSPC;
173 return count;
174 }
175
176 static int __test_firmware_config_init(void)
177 {
178 int ret;
179
180 ret = __kstrncpy(&test_fw_config->name, TEST_FIRMWARE_NAME,
181 strlen(TEST_FIRMWARE_NAME), GFP_KERNEL);
182 if (ret < 0)
183 goto out;
184
185 test_fw_config->num_requests = TEST_FIRMWARE_NUM_REQS;
186 test_fw_config->send_uevent = true;
187 test_fw_config->into_buf = false;
188 test_fw_config->sync_direct = false;
189 test_fw_config->req_firmware = request_firmware;
190 test_fw_config->test_result = 0;
191 test_fw_config->reqs = NULL;
192
193 return 0;
194
195 out:
196 __test_firmware_config_free();
197 return ret;
198 }
199
200 static ssize_t reset_store(struct device *dev,
201 struct device_attribute *attr,
202 const char *buf, size_t count)
203 {
204 int ret;
205
206 mutex_lock(&test_fw_mutex);
207
208 __test_firmware_config_free();
209
210 ret = __test_firmware_config_init();
211 if (ret < 0) {
212 ret = -ENOMEM;
213 pr_err("could not alloc settings for config trigger: %d\n",
214 ret);
215 goto out;
216 }
217
218 pr_info("reset\n");
219 ret = count;
220
221 out:
222 mutex_unlock(&test_fw_mutex);
223
224 return ret;
225 }
226 static DEVICE_ATTR_WO(reset);
227
228 static ssize_t config_show(struct device *dev,
229 struct device_attribute *attr,
230 char *buf)
231 {
232 int len = 0;
233
234 mutex_lock(&test_fw_mutex);
235
236 len += scnprintf(buf, PAGE_SIZE - len,
237 "Custom trigger configuration for: %s\n",
238 dev_name(dev));
239
240 if (test_fw_config->name)
241 len += scnprintf(buf+len, PAGE_SIZE - len,
242 "name:\t%s\n",
243 test_fw_config->name);
244 else
245 len += scnprintf(buf+len, PAGE_SIZE - len,
246 "name:\tEMTPY\n");
247
248 len += scnprintf(buf+len, PAGE_SIZE - len,
249 "num_requests:\t%u\n", test_fw_config->num_requests);
250
251 len += scnprintf(buf+len, PAGE_SIZE - len,
252 "send_uevent:\t\t%s\n",
253 test_fw_config->send_uevent ?
254 "FW_ACTION_HOTPLUG" :
255 "FW_ACTION_NOHOTPLUG");
256 len += scnprintf(buf+len, PAGE_SIZE - len,
257 "into_buf:\t\t%s\n",
258 test_fw_config->into_buf ? "true" : "false");
259 len += scnprintf(buf+len, PAGE_SIZE - len,
260 "sync_direct:\t\t%s\n",
261 test_fw_config->sync_direct ? "true" : "false");
262 len += scnprintf(buf+len, PAGE_SIZE - len,
263 "read_fw_idx:\t%u\n", test_fw_config->read_fw_idx);
264
265 mutex_unlock(&test_fw_mutex);
266
267 return len;
268 }
269 static DEVICE_ATTR_RO(config);
270
271 static ssize_t config_name_store(struct device *dev,
272 struct device_attribute *attr,
273 const char *buf, size_t count)
274 {
275 int ret;
276
277 mutex_lock(&test_fw_mutex);
278 kfree_const(test_fw_config->name);
279 ret = __kstrncpy(&test_fw_config->name, buf, count, GFP_KERNEL);
280 mutex_unlock(&test_fw_mutex);
281
282 return ret;
283 }
284
285 /*
286 * As per sysfs_kf_seq_show() the buf is max PAGE_SIZE.
287 */
288 static ssize_t config_test_show_str(char *dst,
289 char *src)
290 {
291 int len;
292
293 mutex_lock(&test_fw_mutex);
294 len = snprintf(dst, PAGE_SIZE, "%s\n", src);
295 mutex_unlock(&test_fw_mutex);
296
297 return len;
298 }
299
300 static int test_dev_config_update_bool(const char *buf, size_t size,
301 bool *cfg)
302 {
303 int ret;
304
305 mutex_lock(&test_fw_mutex);
306 if (strtobool(buf, cfg) < 0)
307 ret = -EINVAL;
308 else
309 ret = size;
310 mutex_unlock(&test_fw_mutex);
311
312 return ret;
313 }
314
315 static ssize_t test_dev_config_show_bool(char *buf, bool val)
316 {
317 return snprintf(buf, PAGE_SIZE, "%d\n", val);
318 }
319
320 static ssize_t test_dev_config_show_int(char *buf, int val)
321 {
322 return snprintf(buf, PAGE_SIZE, "%d\n", val);
323 }
324
325 static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
326 {
327 int ret;
328 long new;
329
330 ret = kstrtol(buf, 10, &new);
331 if (ret)
332 return ret;
333
334 if (new > U8_MAX)
335 return -EINVAL;
336
337 mutex_lock(&test_fw_mutex);
338 *(u8 *)cfg = new;
339 mutex_unlock(&test_fw_mutex);
340
341 /* Always return full write size even if we didn't consume all */
342 return size;
343 }
344
345 static ssize_t test_dev_config_show_u8(char *buf, u8 val)
346 {
347 return snprintf(buf, PAGE_SIZE, "%u\n", val);
348 }
349
350 static ssize_t config_name_show(struct device *dev,
351 struct device_attribute *attr,
352 char *buf)
353 {
354 return config_test_show_str(buf, test_fw_config->name);
355 }
356 static DEVICE_ATTR_RW(config_name);
357
358 static ssize_t config_num_requests_store(struct device *dev,
359 struct device_attribute *attr,
360 const char *buf, size_t count)
361 {
362 int rc;
363
364 mutex_lock(&test_fw_mutex);
365 if (test_fw_config->reqs) {
366 pr_err("Must call release_all_firmware prior to changing config\n");
367 rc = -EINVAL;
368 mutex_unlock(&test_fw_mutex);
369 goto out;
370 }
371 mutex_unlock(&test_fw_mutex);
372
373 rc = test_dev_config_update_u8(buf, count,
374 &test_fw_config->num_requests);
375
376 out:
377 return rc;
378 }
379
380 static ssize_t config_num_requests_show(struct device *dev,
381 struct device_attribute *attr,
382 char *buf)
383 {
384 return test_dev_config_show_u8(buf, test_fw_config->num_requests);
385 }
386 static DEVICE_ATTR_RW(config_num_requests);
387
388 static ssize_t config_into_buf_store(struct device *dev,
389 struct device_attribute *attr,
390 const char *buf, size_t count)
391 {
392 return test_dev_config_update_bool(buf,
393 count,
394 &test_fw_config->into_buf);
395 }
396
397 static ssize_t config_into_buf_show(struct device *dev,
398 struct device_attribute *attr,
399 char *buf)
400 {
401 return test_dev_config_show_bool(buf, test_fw_config->into_buf);
402 }
403 static DEVICE_ATTR_RW(config_into_buf);
404
405 static ssize_t config_sync_direct_store(struct device *dev,
406 struct device_attribute *attr,
407 const char *buf, size_t count)
408 {
409 int rc = test_dev_config_update_bool(buf, count,
410 &test_fw_config->sync_direct);
411
412 if (rc == count)
413 test_fw_config->req_firmware = test_fw_config->sync_direct ?
414 request_firmware_direct :
415 request_firmware;
416 return rc;
417 }
418
419 static ssize_t config_sync_direct_show(struct device *dev,
420 struct device_attribute *attr,
421 char *buf)
422 {
423 return test_dev_config_show_bool(buf, test_fw_config->sync_direct);
424 }
425 static DEVICE_ATTR_RW(config_sync_direct);
426
427 static ssize_t config_send_uevent_store(struct device *dev,
428 struct device_attribute *attr,
429 const char *buf, size_t count)
430 {
431 return test_dev_config_update_bool(buf, count,
432 &test_fw_config->send_uevent);
433 }
434
435 static ssize_t config_send_uevent_show(struct device *dev,
436 struct device_attribute *attr,
437 char *buf)
438 {
439 return test_dev_config_show_bool(buf, test_fw_config->send_uevent);
440 }
441 static DEVICE_ATTR_RW(config_send_uevent);
442
443 static ssize_t config_read_fw_idx_store(struct device *dev,
444 struct device_attribute *attr,
445 const char *buf, size_t count)
446 {
447 return test_dev_config_update_u8(buf, count,
448 &test_fw_config->read_fw_idx);
449 }
450
451 static ssize_t config_read_fw_idx_show(struct device *dev,
452 struct device_attribute *attr,
453 char *buf)
454 {
455 return test_dev_config_show_u8(buf, test_fw_config->read_fw_idx);
456 }
457 static DEVICE_ATTR_RW(config_read_fw_idx);
458
459
460 static ssize_t trigger_request_store(struct device *dev,
461 struct device_attribute *attr,
462 const char *buf, size_t count)
463 {
464 int rc;
465 char *name;
466
467 name = kstrndup(buf, count, GFP_KERNEL);
468 if (!name)
469 return -ENOSPC;
470
471 pr_info("loading '%s'\n", name);
472
473 mutex_lock(&test_fw_mutex);
474 release_firmware(test_firmware);
475 test_firmware = NULL;
476 rc = request_firmware(&test_firmware, name, dev);
477 if (rc) {
478 pr_info("load of '%s' failed: %d\n", name, rc);
479 goto out;
480 }
481 pr_info("loaded: %zu\n", test_firmware->size);
482 rc = count;
483
484 out:
485 mutex_unlock(&test_fw_mutex);
486
487 kfree(name);
488
489 return rc;
490 }
491 static DEVICE_ATTR_WO(trigger_request);
492
493 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
494 extern struct list_head efi_embedded_fw_list;
495 extern bool efi_embedded_fw_checked;
496
497 static ssize_t trigger_request_platform_store(struct device *dev,
498 struct device_attribute *attr,
499 const char *buf, size_t count)
500 {
501 static const u8 test_data[] = {
502 0x55, 0xaa, 0x55, 0xaa, 0x01, 0x02, 0x03, 0x04,
503 0x55, 0xaa, 0x55, 0xaa, 0x05, 0x06, 0x07, 0x08,
504 0x55, 0xaa, 0x55, 0xaa, 0x10, 0x20, 0x30, 0x40,
505 0x55, 0xaa, 0x55, 0xaa, 0x50, 0x60, 0x70, 0x80
506 };
507 struct efi_embedded_fw efi_embedded_fw;
508 const struct firmware *firmware = NULL;
509 bool saved_efi_embedded_fw_checked;
510 char *name;
511 int rc;
512
513 name = kstrndup(buf, count, GFP_KERNEL);
514 if (!name)
515 return -ENOSPC;
516
517 pr_info("inserting test platform fw '%s'\n", name);
518 efi_embedded_fw.name = name;
519 efi_embedded_fw.data = (void *)test_data;
520 efi_embedded_fw.length = sizeof(test_data);
521 list_add(&efi_embedded_fw.list, &efi_embedded_fw_list);
522 saved_efi_embedded_fw_checked = efi_embedded_fw_checked;
523 efi_embedded_fw_checked = true;
524
525 pr_info("loading '%s'\n", name);
526 rc = firmware_request_platform(&firmware, name, dev);
527 if (rc) {
528 pr_info("load of '%s' failed: %d\n", name, rc);
529 goto out;
530 }
531 if (firmware->size != sizeof(test_data) ||
532 memcmp(firmware->data, test_data, sizeof(test_data)) != 0) {
533 pr_info("firmware contents mismatch for '%s'\n", name);
534 rc = -EINVAL;
535 goto out;
536 }
537 pr_info("loaded: %zu\n", firmware->size);
538 rc = count;
539
540 out:
541 efi_embedded_fw_checked = saved_efi_embedded_fw_checked;
542 release_firmware(firmware);
543 list_del(&efi_embedded_fw.list);
544 kfree(name);
545
546 return rc;
547 }
548 static DEVICE_ATTR_WO(trigger_request_platform);
549 #endif
550
551 static DECLARE_COMPLETION(async_fw_done);
552
553 static void trigger_async_request_cb(const struct firmware *fw, void *context)
554 {
555 test_firmware = fw;
556 complete(&async_fw_done);
557 }
558
559 static ssize_t trigger_async_request_store(struct device *dev,
560 struct device_attribute *attr,
561 const char *buf, size_t count)
562 {
563 int rc;
564 char *name;
565
566 name = kstrndup(buf, count, GFP_KERNEL);
567 if (!name)
568 return -ENOSPC;
569
570 pr_info("loading '%s'\n", name);
571
572 mutex_lock(&test_fw_mutex);
573 release_firmware(test_firmware);
574 test_firmware = NULL;
575 rc = request_firmware_nowait(THIS_MODULE, 1, name, dev, GFP_KERNEL,
576 NULL, trigger_async_request_cb);
577 if (rc) {
578 pr_info("async load of '%s' failed: %d\n", name, rc);
579 kfree(name);
580 goto out;
581 }
582 /* Free 'name' ASAP, to test for race conditions */
583 kfree(name);
584
585 wait_for_completion(&async_fw_done);
586
587 if (test_firmware) {
588 pr_info("loaded: %zu\n", test_firmware->size);
589 rc = count;
590 } else {
591 pr_err("failed to async load firmware\n");
592 rc = -ENOMEM;
593 }
594
595 out:
596 mutex_unlock(&test_fw_mutex);
597
598 return rc;
599 }
600 static DEVICE_ATTR_WO(trigger_async_request);
601
602 static ssize_t trigger_custom_fallback_store(struct device *dev,
603 struct device_attribute *attr,
604 const char *buf, size_t count)
605 {
606 int rc;
607 char *name;
608
609 name = kstrndup(buf, count, GFP_KERNEL);
610 if (!name)
611 return -ENOSPC;
612
613 pr_info("loading '%s' using custom fallback mechanism\n", name);
614
615 mutex_lock(&test_fw_mutex);
616 release_firmware(test_firmware);
617 test_firmware = NULL;
618 rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, name,
619 dev, GFP_KERNEL, NULL,
620 trigger_async_request_cb);
621 if (rc) {
622 pr_info("async load of '%s' failed: %d\n", name, rc);
623 kfree(name);
624 goto out;
625 }
626 /* Free 'name' ASAP, to test for race conditions */
627 kfree(name);
628
629 wait_for_completion(&async_fw_done);
630
631 if (test_firmware) {
632 pr_info("loaded: %zu\n", test_firmware->size);
633 rc = count;
634 } else {
635 pr_err("failed to async load firmware\n");
636 rc = -ENODEV;
637 }
638
639 out:
640 mutex_unlock(&test_fw_mutex);
641
642 return rc;
643 }
644 static DEVICE_ATTR_WO(trigger_custom_fallback);
645
646 static int test_fw_run_batch_request(void *data)
647 {
648 struct test_batched_req *req = data;
649
650 if (!req) {
651 test_fw_config->test_result = -EINVAL;
652 return -EINVAL;
653 }
654
655 if (test_fw_config->into_buf) {
656 void *test_buf;
657
658 test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL);
659 if (!test_buf)
660 return -ENOSPC;
661
662 req->rc = request_firmware_into_buf(&req->fw,
663 req->name,
664 req->dev,
665 test_buf,
666 TEST_FIRMWARE_BUF_SIZE);
667 if (!req->fw)
668 kfree(test_buf);
669 } else {
670 req->rc = test_fw_config->req_firmware(&req->fw,
671 req->name,
672 req->dev);
673 }
674
675 if (req->rc) {
676 pr_info("#%u: batched sync load failed: %d\n",
677 req->idx, req->rc);
678 if (!test_fw_config->test_result)
679 test_fw_config->test_result = req->rc;
680 } else if (req->fw) {
681 req->sent = true;
682 pr_info("#%u: batched sync loaded %zu\n",
683 req->idx, req->fw->size);
684 }
685 complete(&req->completion);
686
687 req->task = NULL;
688
689 return 0;
690 }
691
692 /*
693 * We use a kthread as otherwise the kernel serializes all our sync requests
694 * and we would not be able to mimic batched requests on a sync call. Batched
695 * requests on a sync call can for instance happen on a device driver when
696 * multiple cards are used and firmware loading happens outside of probe.
697 */
698 static ssize_t trigger_batched_requests_store(struct device *dev,
699 struct device_attribute *attr,
700 const char *buf, size_t count)
701 {
702 struct test_batched_req *req;
703 int rc;
704 u8 i;
705
706 mutex_lock(&test_fw_mutex);
707
708 test_fw_config->reqs =
709 vzalloc(array3_size(sizeof(struct test_batched_req),
710 test_fw_config->num_requests, 2));
711 if (!test_fw_config->reqs) {
712 rc = -ENOMEM;
713 goto out_unlock;
714 }
715
716 pr_info("batched sync firmware loading '%s' %u times\n",
717 test_fw_config->name, test_fw_config->num_requests);
718
719 for (i = 0; i < test_fw_config->num_requests; i++) {
720 req = &test_fw_config->reqs[i];
721 req->fw = NULL;
722 req->idx = i;
723 req->name = test_fw_config->name;
724 req->dev = dev;
725 init_completion(&req->completion);
726 req->task = kthread_run(test_fw_run_batch_request, req,
727 "%s-%u", KBUILD_MODNAME, req->idx);
728 if (!req->task || IS_ERR(req->task)) {
729 pr_err("Setting up thread %u failed\n", req->idx);
730 req->task = NULL;
731 rc = -ENOMEM;
732 goto out_bail;
733 }
734 }
735
736 rc = count;
737
738 /*
739 * We require an explicit release to enable more time and delay of
740 * calling release_firmware() to improve our chances of forcing a
741 * batched request. If we instead called release_firmware() right away
742 * then we might miss on an opportunity of having a successful firmware
743 * request pass on the opportunity to be come a batched request.
744 */
745
746 out_bail:
747 for (i = 0; i < test_fw_config->num_requests; i++) {
748 req = &test_fw_config->reqs[i];
749 if (req->task || req->sent)
750 wait_for_completion(&req->completion);
751 }
752
753 /* Override any worker error if we had a general setup error */
754 if (rc < 0)
755 test_fw_config->test_result = rc;
756
757 out_unlock:
758 mutex_unlock(&test_fw_mutex);
759
760 return rc;
761 }
762 static DEVICE_ATTR_WO(trigger_batched_requests);
763
764 /*
765 * We wait for each callback to return with the lock held, no need to lock here
766 */
767 static void trigger_batched_cb(const struct firmware *fw, void *context)
768 {
769 struct test_batched_req *req = context;
770
771 if (!req) {
772 test_fw_config->test_result = -EINVAL;
773 return;
774 }
775
776 /* forces *some* batched requests to queue up */
777 if (!req->idx)
778 ssleep(2);
779
780 req->fw = fw;
781
782 /*
783 * Unfortunately the firmware API gives us nothing other than a null FW
784 * if the firmware was not found on async requests. Best we can do is
785 * just assume -ENOENT. A better API would pass the actual return
786 * value to the callback.
787 */
788 if (!fw && !test_fw_config->test_result)
789 test_fw_config->test_result = -ENOENT;
790
791 complete(&req->completion);
792 }
793
794 static
795 ssize_t trigger_batched_requests_async_store(struct device *dev,
796 struct device_attribute *attr,
797 const char *buf, size_t count)
798 {
799 struct test_batched_req *req;
800 bool send_uevent;
801 int rc;
802 u8 i;
803
804 mutex_lock(&test_fw_mutex);
805
806 test_fw_config->reqs =
807 vzalloc(array3_size(sizeof(struct test_batched_req),
808 test_fw_config->num_requests, 2));
809 if (!test_fw_config->reqs) {
810 rc = -ENOMEM;
811 goto out;
812 }
813
814 pr_info("batched loading '%s' custom fallback mechanism %u times\n",
815 test_fw_config->name, test_fw_config->num_requests);
816
817 send_uevent = test_fw_config->send_uevent ? FW_ACTION_HOTPLUG :
818 FW_ACTION_NOHOTPLUG;
819
820 for (i = 0; i < test_fw_config->num_requests; i++) {
821 req = &test_fw_config->reqs[i];
822 req->name = test_fw_config->name;
823 req->fw = NULL;
824 req->idx = i;
825 init_completion(&req->completion);
826 rc = request_firmware_nowait(THIS_MODULE, send_uevent,
827 req->name,
828 dev, GFP_KERNEL, req,
829 trigger_batched_cb);
830 if (rc) {
831 pr_info("#%u: batched async load failed setup: %d\n",
832 i, rc);
833 req->rc = rc;
834 goto out_bail;
835 } else
836 req->sent = true;
837 }
838
839 rc = count;
840
841 out_bail:
842
843 /*
844 * We require an explicit release to enable more time and delay of
845 * calling release_firmware() to improve our chances of forcing a
846 * batched request. If we instead called release_firmware() right away
847 * then we might miss on an opportunity of having a successful firmware
848 * request pass on the opportunity to be come a batched request.
849 */
850
851 for (i = 0; i < test_fw_config->num_requests; i++) {
852 req = &test_fw_config->reqs[i];
853 if (req->sent)
854 wait_for_completion(&req->completion);
855 }
856
857 /* Override any worker error if we had a general setup error */
858 if (rc < 0)
859 test_fw_config->test_result = rc;
860
861 out:
862 mutex_unlock(&test_fw_mutex);
863
864 return rc;
865 }
866 static DEVICE_ATTR_WO(trigger_batched_requests_async);
867
868 static ssize_t test_result_show(struct device *dev,
869 struct device_attribute *attr,
870 char *buf)
871 {
872 return test_dev_config_show_int(buf, test_fw_config->test_result);
873 }
874 static DEVICE_ATTR_RO(test_result);
875
876 static ssize_t release_all_firmware_store(struct device *dev,
877 struct device_attribute *attr,
878 const char *buf, size_t count)
879 {
880 test_release_all_firmware();
881 return count;
882 }
883 static DEVICE_ATTR_WO(release_all_firmware);
884
885 static ssize_t read_firmware_show(struct device *dev,
886 struct device_attribute *attr,
887 char *buf)
888 {
889 struct test_batched_req *req;
890 u8 idx;
891 ssize_t rc = 0;
892
893 mutex_lock(&test_fw_mutex);
894
895 idx = test_fw_config->read_fw_idx;
896 if (idx >= test_fw_config->num_requests) {
897 rc = -ERANGE;
898 goto out;
899 }
900
901 if (!test_fw_config->reqs) {
902 rc = -EINVAL;
903 goto out;
904 }
905
906 req = &test_fw_config->reqs[idx];
907 if (!req->fw) {
908 pr_err("#%u: failed to async load firmware\n", idx);
909 rc = -ENOENT;
910 goto out;
911 }
912
913 pr_info("#%u: loaded %zu\n", idx, req->fw->size);
914
915 if (req->fw->size > PAGE_SIZE) {
916 pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
917 rc = -EINVAL;
918 goto out;
919 }
920 memcpy(buf, req->fw->data, req->fw->size);
921
922 rc = req->fw->size;
923 out:
924 mutex_unlock(&test_fw_mutex);
925
926 return rc;
927 }
928 static DEVICE_ATTR_RO(read_firmware);
929
930 #define TEST_FW_DEV_ATTR(name) &dev_attr_##name.attr
931
932 static struct attribute *test_dev_attrs[] = {
933 TEST_FW_DEV_ATTR(reset),
934
935 TEST_FW_DEV_ATTR(config),
936 TEST_FW_DEV_ATTR(config_name),
937 TEST_FW_DEV_ATTR(config_num_requests),
938 TEST_FW_DEV_ATTR(config_into_buf),
939 TEST_FW_DEV_ATTR(config_sync_direct),
940 TEST_FW_DEV_ATTR(config_send_uevent),
941 TEST_FW_DEV_ATTR(config_read_fw_idx),
942
943 /* These don't use the config at all - they could be ported! */
944 TEST_FW_DEV_ATTR(trigger_request),
945 TEST_FW_DEV_ATTR(trigger_async_request),
946 TEST_FW_DEV_ATTR(trigger_custom_fallback),
947 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
948 TEST_FW_DEV_ATTR(trigger_request_platform),
949 #endif
950
951 /* These use the config and can use the test_result */
952 TEST_FW_DEV_ATTR(trigger_batched_requests),
953 TEST_FW_DEV_ATTR(trigger_batched_requests_async),
954
955 TEST_FW_DEV_ATTR(release_all_firmware),
956 TEST_FW_DEV_ATTR(test_result),
957 TEST_FW_DEV_ATTR(read_firmware),
958 NULL,
959 };
960
961 ATTRIBUTE_GROUPS(test_dev);
962
963 static struct miscdevice test_fw_misc_device = {
964 .minor = MISC_DYNAMIC_MINOR,
965 .name = "test_firmware",
966 .fops = &test_fw_fops,
967 .groups = test_dev_groups,
968 };
969
970 static int __init test_firmware_init(void)
971 {
972 int rc;
973
974 test_fw_config = kzalloc(sizeof(struct test_config), GFP_KERNEL);
975 if (!test_fw_config)
976 return -ENOMEM;
977
978 rc = __test_firmware_config_init();
979 if (rc) {
980 kfree(test_fw_config);
981 pr_err("could not init firmware test config: %d\n", rc);
982 return rc;
983 }
984
985 rc = misc_register(&test_fw_misc_device);
986 if (rc) {
987 kfree(test_fw_config);
988 pr_err("could not register misc device: %d\n", rc);
989 return rc;
990 }
991
992 pr_warn("interface ready\n");
993
994 return 0;
995 }
996
997 module_init(test_firmware_init);
998
999 static void __exit test_firmware_exit(void)
1000 {
1001 mutex_lock(&test_fw_mutex);
1002 release_firmware(test_firmware);
1003 misc_deregister(&test_fw_misc_device);
1004 __test_firmware_config_free();
1005 kfree(test_fw_config);
1006 mutex_unlock(&test_fw_mutex);
1007
1008 pr_warn("removed interface\n");
1009 }
1010
1011 module_exit(test_firmware_exit);
1012
1013 MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
1014 MODULE_LICENSE("GPL");