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