~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/lib/test_firmware.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php