hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/lib/test_firmware.c
....@@ -22,6 +22,7 @@
2222 #include <linux/slab.h>
2323 #include <linux/uaccess.h>
2424 #include <linux/delay.h>
25
+#include <linux/kstrtox.h>
2526 #include <linux/kthread.h>
2627 #include <linux/vmalloc.h>
2728 #include <linux/efi_embedded_fw.h>
....@@ -41,6 +42,7 @@
4142 bool sent;
4243 const struct firmware *fw;
4344 const char *name;
45
+ const char *fw_buf;
4446 struct completion completion;
4547 struct task_struct *task;
4648 struct device *dev;
....@@ -143,8 +145,14 @@
143145
144146 for (i = 0; i < test_fw_config->num_requests; i++) {
145147 req = &test_fw_config->reqs[i];
146
- if (req->fw)
148
+ if (req->fw) {
149
+ if (req->fw_buf) {
150
+ kfree_const(req->fw_buf);
151
+ req->fw_buf = NULL;
152
+ }
147153 release_firmware(req->fw);
154
+ req->fw = NULL;
155
+ }
148156 }
149157
150158 vfree(test_fw_config->reqs);
....@@ -175,7 +183,7 @@
175183 {
176184 *dst = kstrndup(name, count, gfp);
177185 if (!*dst)
178
- return -ENOSPC;
186
+ return -ENOMEM;
179187 return count;
180188 }
181189
....@@ -313,16 +321,26 @@
313321 return len;
314322 }
315323
324
+static inline int __test_dev_config_update_bool(const char *buf, size_t size,
325
+ bool *cfg)
326
+{
327
+ int ret;
328
+
329
+ if (kstrtobool(buf, cfg) < 0)
330
+ ret = -EINVAL;
331
+ else
332
+ ret = size;
333
+
334
+ return ret;
335
+}
336
+
316337 static int test_dev_config_update_bool(const char *buf, size_t size,
317338 bool *cfg)
318339 {
319340 int ret;
320341
321342 mutex_lock(&test_fw_mutex);
322
- if (strtobool(buf, cfg) < 0)
323
- ret = -EINVAL;
324
- else
325
- ret = size;
343
+ ret = __test_dev_config_update_bool(buf, size, cfg);
326344 mutex_unlock(&test_fw_mutex);
327345
328346 return ret;
....@@ -333,7 +351,8 @@
333351 return snprintf(buf, PAGE_SIZE, "%d\n", val);
334352 }
335353
336
-static int test_dev_config_update_size_t(const char *buf,
354
+static int __test_dev_config_update_size_t(
355
+ const char *buf,
337356 size_t size,
338357 size_t *cfg)
339358 {
....@@ -344,9 +363,7 @@
344363 if (ret)
345364 return ret;
346365
347
- mutex_lock(&test_fw_mutex);
348366 *(size_t *)cfg = new;
349
- mutex_unlock(&test_fw_mutex);
350367
351368 /* Always return full write size even if we didn't consume all */
352369 return size;
....@@ -362,24 +379,30 @@
362379 return snprintf(buf, PAGE_SIZE, "%d\n", val);
363380 }
364381
365
-static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
382
+static int __test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
366383 {
384
+ u8 val;
367385 int ret;
368
- long new;
369386
370
- ret = kstrtol(buf, 10, &new);
387
+ ret = kstrtou8(buf, 10, &val);
371388 if (ret)
372389 return ret;
373390
374
- if (new > U8_MAX)
375
- return -EINVAL;
376
-
377
- mutex_lock(&test_fw_mutex);
378
- *(u8 *)cfg = new;
379
- mutex_unlock(&test_fw_mutex);
391
+ *(u8 *)cfg = val;
380392
381393 /* Always return full write size even if we didn't consume all */
382394 return size;
395
+}
396
+
397
+static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
398
+{
399
+ int ret;
400
+
401
+ mutex_lock(&test_fw_mutex);
402
+ ret = __test_dev_config_update_u8(buf, size, cfg);
403
+ mutex_unlock(&test_fw_mutex);
404
+
405
+ return ret;
383406 }
384407
385408 static ssize_t test_dev_config_show_u8(char *buf, u8 val)
....@@ -408,10 +431,10 @@
408431 mutex_unlock(&test_fw_mutex);
409432 goto out;
410433 }
411
- mutex_unlock(&test_fw_mutex);
412434
413
- rc = test_dev_config_update_u8(buf, count,
414
- &test_fw_config->num_requests);
435
+ rc = __test_dev_config_update_u8(buf, count,
436
+ &test_fw_config->num_requests);
437
+ mutex_unlock(&test_fw_mutex);
415438
416439 out:
417440 return rc;
....@@ -455,10 +478,10 @@
455478 mutex_unlock(&test_fw_mutex);
456479 goto out;
457480 }
458
- mutex_unlock(&test_fw_mutex);
459481
460
- rc = test_dev_config_update_size_t(buf, count,
461
- &test_fw_config->buf_size);
482
+ rc = __test_dev_config_update_size_t(buf, count,
483
+ &test_fw_config->buf_size);
484
+ mutex_unlock(&test_fw_mutex);
462485
463486 out:
464487 return rc;
....@@ -485,10 +508,10 @@
485508 mutex_unlock(&test_fw_mutex);
486509 goto out;
487510 }
488
- mutex_unlock(&test_fw_mutex);
489511
490
- rc = test_dev_config_update_size_t(buf, count,
491
- &test_fw_config->file_offset);
512
+ rc = __test_dev_config_update_size_t(buf, count,
513
+ &test_fw_config->file_offset);
514
+ mutex_unlock(&test_fw_mutex);
492515
493516 out:
494517 return rc;
....@@ -583,12 +606,14 @@
583606
584607 name = kstrndup(buf, count, GFP_KERNEL);
585608 if (!name)
586
- return -ENOSPC;
609
+ return -ENOMEM;
587610
588611 pr_info("loading '%s'\n", name);
589612
590613 mutex_lock(&test_fw_mutex);
591614 release_firmware(test_firmware);
615
+ if (test_fw_config->reqs)
616
+ __test_release_all_firmware();
592617 test_firmware = NULL;
593618 rc = request_firmware(&test_firmware, name, dev);
594619 if (rc) {
....@@ -629,7 +654,7 @@
629654
630655 name = kstrndup(buf, count, GFP_KERNEL);
631656 if (!name)
632
- return -ENOSPC;
657
+ return -ENOMEM;
633658
634659 pr_info("inserting test platform fw '%s'\n", name);
635660 efi_embedded_fw.name = name;
....@@ -682,13 +707,15 @@
682707
683708 name = kstrndup(buf, count, GFP_KERNEL);
684709 if (!name)
685
- return -ENOSPC;
710
+ return -ENOMEM;
686711
687712 pr_info("loading '%s'\n", name);
688713
689714 mutex_lock(&test_fw_mutex);
690715 release_firmware(test_firmware);
691716 test_firmware = NULL;
717
+ if (test_fw_config->reqs)
718
+ __test_release_all_firmware();
692719 rc = request_firmware_nowait(THIS_MODULE, 1, name, dev, GFP_KERNEL,
693720 NULL, trigger_async_request_cb);
694721 if (rc) {
....@@ -725,12 +752,14 @@
725752
726753 name = kstrndup(buf, count, GFP_KERNEL);
727754 if (!name)
728
- return -ENOSPC;
755
+ return -ENOMEM;
729756
730757 pr_info("loading '%s' using custom fallback mechanism\n", name);
731758
732759 mutex_lock(&test_fw_mutex);
733760 release_firmware(test_firmware);
761
+ if (test_fw_config->reqs)
762
+ __test_release_all_firmware();
734763 test_firmware = NULL;
735764 rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, name,
736765 dev, GFP_KERNEL, NULL,
....@@ -774,7 +803,7 @@
774803
775804 test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL);
776805 if (!test_buf)
777
- return -ENOSPC;
806
+ return -ENOMEM;
778807
779808 if (test_fw_config->partial)
780809 req->rc = request_partial_firmware_into_buf
....@@ -793,6 +822,8 @@
793822 test_fw_config->buf_size);
794823 if (!req->fw)
795824 kfree(test_buf);
825
+ else
826
+ req->fw_buf = test_buf;
796827 } else {
797828 req->rc = test_fw_config->req_firmware(&req->fw,
798829 req->name,
....@@ -832,6 +863,11 @@
832863
833864 mutex_lock(&test_fw_mutex);
834865
866
+ if (test_fw_config->reqs) {
867
+ rc = -EBUSY;
868
+ goto out_bail;
869
+ }
870
+
835871 test_fw_config->reqs =
836872 vzalloc(array3_size(sizeof(struct test_batched_req),
837873 test_fw_config->num_requests, 2));
....@@ -848,6 +884,7 @@
848884 req->fw = NULL;
849885 req->idx = i;
850886 req->name = test_fw_config->name;
887
+ req->fw_buf = NULL;
851888 req->dev = dev;
852889 init_completion(&req->completion);
853890 req->task = kthread_run(test_fw_run_batch_request, req,
....@@ -930,6 +967,11 @@
930967
931968 mutex_lock(&test_fw_mutex);
932969
970
+ if (test_fw_config->reqs) {
971
+ rc = -EBUSY;
972
+ goto out_bail;
973
+ }
974
+
933975 test_fw_config->reqs =
934976 vzalloc(array3_size(sizeof(struct test_batched_req),
935977 test_fw_config->num_requests, 2));
....@@ -947,6 +989,7 @@
947989 for (i = 0; i < test_fw_config->num_requests; i++) {
948990 req = &test_fw_config->reqs[i];
949991 req->name = test_fw_config->name;
992
+ req->fw_buf = NULL;
950993 req->fw = NULL;
951994 req->idx = i;
952995 init_completion(&req->completion);
....@@ -1114,6 +1157,7 @@
11141157
11151158 rc = misc_register(&test_fw_misc_device);
11161159 if (rc) {
1160
+ __test_firmware_config_free();
11171161 kfree(test_fw_config);
11181162 pr_err("could not register misc device: %d\n", rc);
11191163 return rc;