0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0012
0013 #include <linux/init.h>
0014 #include <linux/module.h>
0015 #include <linux/printk.h>
0016 #include <linux/completion.h>
0017 #include <linux/firmware.h>
0018 #include <linux/device.h>
0019 #include <linux/fs.h>
0020 #include <linux/miscdevice.h>
0021 #include <linux/sizes.h>
0022 #include <linux/slab.h>
0023 #include <linux/uaccess.h>
0024 #include <linux/delay.h>
0025 #include <linux/kthread.h>
0026 #include <linux/vmalloc.h>
0027 #include <linux/efi_embedded_fw.h>
0028
0029 MODULE_IMPORT_NS(TEST_FIRMWARE);
0030
0031 #define TEST_FIRMWARE_NAME "test-firmware.bin"
0032 #define TEST_FIRMWARE_NUM_REQS 4
0033 #define TEST_FIRMWARE_BUF_SIZE SZ_1K
0034 #define TEST_UPLOAD_MAX_SIZE SZ_2K
0035 #define TEST_UPLOAD_BLK_SIZE 37
0036
0037 static DEFINE_MUTEX(test_fw_mutex);
0038 static const struct firmware *test_firmware;
0039 static LIST_HEAD(test_upload_list);
0040
0041 struct test_batched_req {
0042 u8 idx;
0043 int rc;
0044 bool sent;
0045 const struct firmware *fw;
0046 const char *name;
0047 struct completion completion;
0048 struct task_struct *task;
0049 struct device *dev;
0050 };
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 struct test_config {
0099 char *name;
0100 bool into_buf;
0101 size_t buf_size;
0102 size_t file_offset;
0103 bool partial;
0104 bool sync_direct;
0105 bool send_uevent;
0106 u8 num_requests;
0107 u8 read_fw_idx;
0108 char *upload_name;
0109
0110
0111
0112
0113
0114 struct test_batched_req *reqs;
0115 int test_result;
0116 int (*req_firmware)(const struct firmware **fw, const char *name,
0117 struct device *device);
0118 };
0119
0120 struct upload_inject_err {
0121 const char *prog;
0122 enum fw_upload_err err_code;
0123 };
0124
0125 struct test_firmware_upload {
0126 char *name;
0127 struct list_head node;
0128 char *buf;
0129 size_t size;
0130 bool cancel_request;
0131 struct upload_inject_err inject;
0132 struct fw_upload *fwl;
0133 };
0134
0135 static struct test_config *test_fw_config;
0136
0137 static struct test_firmware_upload *upload_lookup_name(const char *name)
0138 {
0139 struct test_firmware_upload *tst;
0140
0141 list_for_each_entry(tst, &test_upload_list, node)
0142 if (strncmp(name, tst->name, strlen(tst->name)) == 0)
0143 return tst;
0144
0145 return NULL;
0146 }
0147
0148 static ssize_t test_fw_misc_read(struct file *f, char __user *buf,
0149 size_t size, loff_t *offset)
0150 {
0151 ssize_t rc = 0;
0152
0153 mutex_lock(&test_fw_mutex);
0154 if (test_firmware)
0155 rc = simple_read_from_buffer(buf, size, offset,
0156 test_firmware->data,
0157 test_firmware->size);
0158 mutex_unlock(&test_fw_mutex);
0159 return rc;
0160 }
0161
0162 static const struct file_operations test_fw_fops = {
0163 .owner = THIS_MODULE,
0164 .read = test_fw_misc_read,
0165 };
0166
0167 static void __test_release_all_firmware(void)
0168 {
0169 struct test_batched_req *req;
0170 u8 i;
0171
0172 if (!test_fw_config->reqs)
0173 return;
0174
0175 for (i = 0; i < test_fw_config->num_requests; i++) {
0176 req = &test_fw_config->reqs[i];
0177 if (req->fw)
0178 release_firmware(req->fw);
0179 }
0180
0181 vfree(test_fw_config->reqs);
0182 test_fw_config->reqs = NULL;
0183 }
0184
0185 static void test_release_all_firmware(void)
0186 {
0187 mutex_lock(&test_fw_mutex);
0188 __test_release_all_firmware();
0189 mutex_unlock(&test_fw_mutex);
0190 }
0191
0192
0193 static void __test_firmware_config_free(void)
0194 {
0195 __test_release_all_firmware();
0196 kfree_const(test_fw_config->name);
0197 test_fw_config->name = NULL;
0198 }
0199
0200
0201
0202
0203
0204
0205 static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp)
0206 {
0207 *dst = kstrndup(name, count, gfp);
0208 if (!*dst)
0209 return -ENOSPC;
0210 return count;
0211 }
0212
0213 static int __test_firmware_config_init(void)
0214 {
0215 int ret;
0216
0217 ret = __kstrncpy(&test_fw_config->name, TEST_FIRMWARE_NAME,
0218 strlen(TEST_FIRMWARE_NAME), GFP_KERNEL);
0219 if (ret < 0)
0220 goto out;
0221
0222 test_fw_config->num_requests = TEST_FIRMWARE_NUM_REQS;
0223 test_fw_config->send_uevent = true;
0224 test_fw_config->into_buf = false;
0225 test_fw_config->buf_size = TEST_FIRMWARE_BUF_SIZE;
0226 test_fw_config->file_offset = 0;
0227 test_fw_config->partial = false;
0228 test_fw_config->sync_direct = false;
0229 test_fw_config->req_firmware = request_firmware;
0230 test_fw_config->test_result = 0;
0231 test_fw_config->reqs = NULL;
0232 test_fw_config->upload_name = NULL;
0233
0234 return 0;
0235
0236 out:
0237 __test_firmware_config_free();
0238 return ret;
0239 }
0240
0241 static ssize_t reset_store(struct device *dev,
0242 struct device_attribute *attr,
0243 const char *buf, size_t count)
0244 {
0245 int ret;
0246
0247 mutex_lock(&test_fw_mutex);
0248
0249 __test_firmware_config_free();
0250
0251 ret = __test_firmware_config_init();
0252 if (ret < 0) {
0253 ret = -ENOMEM;
0254 pr_err("could not alloc settings for config trigger: %d\n",
0255 ret);
0256 goto out;
0257 }
0258
0259 pr_info("reset\n");
0260 ret = count;
0261
0262 out:
0263 mutex_unlock(&test_fw_mutex);
0264
0265 return ret;
0266 }
0267 static DEVICE_ATTR_WO(reset);
0268
0269 static ssize_t config_show(struct device *dev,
0270 struct device_attribute *attr,
0271 char *buf)
0272 {
0273 int len = 0;
0274
0275 mutex_lock(&test_fw_mutex);
0276
0277 len += scnprintf(buf, PAGE_SIZE - len,
0278 "Custom trigger configuration for: %s\n",
0279 dev_name(dev));
0280
0281 if (test_fw_config->name)
0282 len += scnprintf(buf + len, PAGE_SIZE - len,
0283 "name:\t%s\n",
0284 test_fw_config->name);
0285 else
0286 len += scnprintf(buf + len, PAGE_SIZE - len,
0287 "name:\tEMTPY\n");
0288
0289 len += scnprintf(buf + len, PAGE_SIZE - len,
0290 "num_requests:\t%u\n", test_fw_config->num_requests);
0291
0292 len += scnprintf(buf + len, PAGE_SIZE - len,
0293 "send_uevent:\t\t%s\n",
0294 test_fw_config->send_uevent ?
0295 "FW_ACTION_UEVENT" :
0296 "FW_ACTION_NOUEVENT");
0297 len += scnprintf(buf + len, PAGE_SIZE - len,
0298 "into_buf:\t\t%s\n",
0299 test_fw_config->into_buf ? "true" : "false");
0300 len += scnprintf(buf + len, PAGE_SIZE - len,
0301 "buf_size:\t%zu\n", test_fw_config->buf_size);
0302 len += scnprintf(buf + len, PAGE_SIZE - len,
0303 "file_offset:\t%zu\n", test_fw_config->file_offset);
0304 len += scnprintf(buf + len, PAGE_SIZE - len,
0305 "partial:\t\t%s\n",
0306 test_fw_config->partial ? "true" : "false");
0307 len += scnprintf(buf + len, PAGE_SIZE - len,
0308 "sync_direct:\t\t%s\n",
0309 test_fw_config->sync_direct ? "true" : "false");
0310 len += scnprintf(buf + len, PAGE_SIZE - len,
0311 "read_fw_idx:\t%u\n", test_fw_config->read_fw_idx);
0312 if (test_fw_config->upload_name)
0313 len += scnprintf(buf + len, PAGE_SIZE - len,
0314 "upload_name:\t%s\n",
0315 test_fw_config->upload_name);
0316 else
0317 len += scnprintf(buf + len, PAGE_SIZE - len,
0318 "upload_name:\tEMTPY\n");
0319
0320 mutex_unlock(&test_fw_mutex);
0321
0322 return len;
0323 }
0324 static DEVICE_ATTR_RO(config);
0325
0326 static ssize_t config_name_store(struct device *dev,
0327 struct device_attribute *attr,
0328 const char *buf, size_t count)
0329 {
0330 int ret;
0331
0332 mutex_lock(&test_fw_mutex);
0333 kfree_const(test_fw_config->name);
0334 ret = __kstrncpy(&test_fw_config->name, buf, count, GFP_KERNEL);
0335 mutex_unlock(&test_fw_mutex);
0336
0337 return ret;
0338 }
0339
0340
0341
0342
0343 static ssize_t config_test_show_str(char *dst,
0344 char *src)
0345 {
0346 int len;
0347
0348 mutex_lock(&test_fw_mutex);
0349 len = snprintf(dst, PAGE_SIZE, "%s\n", src);
0350 mutex_unlock(&test_fw_mutex);
0351
0352 return len;
0353 }
0354
0355 static int test_dev_config_update_bool(const char *buf, size_t size,
0356 bool *cfg)
0357 {
0358 int ret;
0359
0360 mutex_lock(&test_fw_mutex);
0361 if (strtobool(buf, cfg) < 0)
0362 ret = -EINVAL;
0363 else
0364 ret = size;
0365 mutex_unlock(&test_fw_mutex);
0366
0367 return ret;
0368 }
0369
0370 static ssize_t test_dev_config_show_bool(char *buf, bool val)
0371 {
0372 return snprintf(buf, PAGE_SIZE, "%d\n", val);
0373 }
0374
0375 static int test_dev_config_update_size_t(const char *buf,
0376 size_t size,
0377 size_t *cfg)
0378 {
0379 int ret;
0380 long new;
0381
0382 ret = kstrtol(buf, 10, &new);
0383 if (ret)
0384 return ret;
0385
0386 mutex_lock(&test_fw_mutex);
0387 *(size_t *)cfg = new;
0388 mutex_unlock(&test_fw_mutex);
0389
0390
0391 return size;
0392 }
0393
0394 static ssize_t test_dev_config_show_size_t(char *buf, size_t val)
0395 {
0396 return snprintf(buf, PAGE_SIZE, "%zu\n", val);
0397 }
0398
0399 static ssize_t test_dev_config_show_int(char *buf, int val)
0400 {
0401 return snprintf(buf, PAGE_SIZE, "%d\n", val);
0402 }
0403
0404 static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
0405 {
0406 u8 val;
0407 int ret;
0408
0409 ret = kstrtou8(buf, 10, &val);
0410 if (ret)
0411 return ret;
0412
0413 mutex_lock(&test_fw_mutex);
0414 *(u8 *)cfg = val;
0415 mutex_unlock(&test_fw_mutex);
0416
0417
0418 return size;
0419 }
0420
0421 static ssize_t test_dev_config_show_u8(char *buf, u8 val)
0422 {
0423 return snprintf(buf, PAGE_SIZE, "%u\n", val);
0424 }
0425
0426 static ssize_t config_name_show(struct device *dev,
0427 struct device_attribute *attr,
0428 char *buf)
0429 {
0430 return config_test_show_str(buf, test_fw_config->name);
0431 }
0432 static DEVICE_ATTR_RW(config_name);
0433
0434 static ssize_t config_upload_name_store(struct device *dev,
0435 struct device_attribute *attr,
0436 const char *buf, size_t count)
0437 {
0438 struct test_firmware_upload *tst;
0439 int ret = count;
0440
0441 mutex_lock(&test_fw_mutex);
0442 tst = upload_lookup_name(buf);
0443 if (tst)
0444 test_fw_config->upload_name = tst->name;
0445 else
0446 ret = -EINVAL;
0447 mutex_unlock(&test_fw_mutex);
0448
0449 return ret;
0450 }
0451
0452 static ssize_t config_upload_name_show(struct device *dev,
0453 struct device_attribute *attr,
0454 char *buf)
0455 {
0456 return config_test_show_str(buf, test_fw_config->upload_name);
0457 }
0458 static DEVICE_ATTR_RW(config_upload_name);
0459
0460 static ssize_t config_num_requests_store(struct device *dev,
0461 struct device_attribute *attr,
0462 const char *buf, size_t count)
0463 {
0464 int rc;
0465
0466 mutex_lock(&test_fw_mutex);
0467 if (test_fw_config->reqs) {
0468 pr_err("Must call release_all_firmware prior to changing config\n");
0469 rc = -EINVAL;
0470 mutex_unlock(&test_fw_mutex);
0471 goto out;
0472 }
0473 mutex_unlock(&test_fw_mutex);
0474
0475 rc = test_dev_config_update_u8(buf, count,
0476 &test_fw_config->num_requests);
0477
0478 out:
0479 return rc;
0480 }
0481
0482 static ssize_t config_num_requests_show(struct device *dev,
0483 struct device_attribute *attr,
0484 char *buf)
0485 {
0486 return test_dev_config_show_u8(buf, test_fw_config->num_requests);
0487 }
0488 static DEVICE_ATTR_RW(config_num_requests);
0489
0490 static ssize_t config_into_buf_store(struct device *dev,
0491 struct device_attribute *attr,
0492 const char *buf, size_t count)
0493 {
0494 return test_dev_config_update_bool(buf,
0495 count,
0496 &test_fw_config->into_buf);
0497 }
0498
0499 static ssize_t config_into_buf_show(struct device *dev,
0500 struct device_attribute *attr,
0501 char *buf)
0502 {
0503 return test_dev_config_show_bool(buf, test_fw_config->into_buf);
0504 }
0505 static DEVICE_ATTR_RW(config_into_buf);
0506
0507 static ssize_t config_buf_size_store(struct device *dev,
0508 struct device_attribute *attr,
0509 const char *buf, size_t count)
0510 {
0511 int rc;
0512
0513 mutex_lock(&test_fw_mutex);
0514 if (test_fw_config->reqs) {
0515 pr_err("Must call release_all_firmware prior to changing config\n");
0516 rc = -EINVAL;
0517 mutex_unlock(&test_fw_mutex);
0518 goto out;
0519 }
0520 mutex_unlock(&test_fw_mutex);
0521
0522 rc = test_dev_config_update_size_t(buf, count,
0523 &test_fw_config->buf_size);
0524
0525 out:
0526 return rc;
0527 }
0528
0529 static ssize_t config_buf_size_show(struct device *dev,
0530 struct device_attribute *attr,
0531 char *buf)
0532 {
0533 return test_dev_config_show_size_t(buf, test_fw_config->buf_size);
0534 }
0535 static DEVICE_ATTR_RW(config_buf_size);
0536
0537 static ssize_t config_file_offset_store(struct device *dev,
0538 struct device_attribute *attr,
0539 const char *buf, size_t count)
0540 {
0541 int rc;
0542
0543 mutex_lock(&test_fw_mutex);
0544 if (test_fw_config->reqs) {
0545 pr_err("Must call release_all_firmware prior to changing config\n");
0546 rc = -EINVAL;
0547 mutex_unlock(&test_fw_mutex);
0548 goto out;
0549 }
0550 mutex_unlock(&test_fw_mutex);
0551
0552 rc = test_dev_config_update_size_t(buf, count,
0553 &test_fw_config->file_offset);
0554
0555 out:
0556 return rc;
0557 }
0558
0559 static ssize_t config_file_offset_show(struct device *dev,
0560 struct device_attribute *attr,
0561 char *buf)
0562 {
0563 return test_dev_config_show_size_t(buf, test_fw_config->file_offset);
0564 }
0565 static DEVICE_ATTR_RW(config_file_offset);
0566
0567 static ssize_t config_partial_store(struct device *dev,
0568 struct device_attribute *attr,
0569 const char *buf, size_t count)
0570 {
0571 return test_dev_config_update_bool(buf,
0572 count,
0573 &test_fw_config->partial);
0574 }
0575
0576 static ssize_t config_partial_show(struct device *dev,
0577 struct device_attribute *attr,
0578 char *buf)
0579 {
0580 return test_dev_config_show_bool(buf, test_fw_config->partial);
0581 }
0582 static DEVICE_ATTR_RW(config_partial);
0583
0584 static ssize_t config_sync_direct_store(struct device *dev,
0585 struct device_attribute *attr,
0586 const char *buf, size_t count)
0587 {
0588 int rc = test_dev_config_update_bool(buf, count,
0589 &test_fw_config->sync_direct);
0590
0591 if (rc == count)
0592 test_fw_config->req_firmware = test_fw_config->sync_direct ?
0593 request_firmware_direct :
0594 request_firmware;
0595 return rc;
0596 }
0597
0598 static ssize_t config_sync_direct_show(struct device *dev,
0599 struct device_attribute *attr,
0600 char *buf)
0601 {
0602 return test_dev_config_show_bool(buf, test_fw_config->sync_direct);
0603 }
0604 static DEVICE_ATTR_RW(config_sync_direct);
0605
0606 static ssize_t config_send_uevent_store(struct device *dev,
0607 struct device_attribute *attr,
0608 const char *buf, size_t count)
0609 {
0610 return test_dev_config_update_bool(buf, count,
0611 &test_fw_config->send_uevent);
0612 }
0613
0614 static ssize_t config_send_uevent_show(struct device *dev,
0615 struct device_attribute *attr,
0616 char *buf)
0617 {
0618 return test_dev_config_show_bool(buf, test_fw_config->send_uevent);
0619 }
0620 static DEVICE_ATTR_RW(config_send_uevent);
0621
0622 static ssize_t config_read_fw_idx_store(struct device *dev,
0623 struct device_attribute *attr,
0624 const char *buf, size_t count)
0625 {
0626 return test_dev_config_update_u8(buf, count,
0627 &test_fw_config->read_fw_idx);
0628 }
0629
0630 static ssize_t config_read_fw_idx_show(struct device *dev,
0631 struct device_attribute *attr,
0632 char *buf)
0633 {
0634 return test_dev_config_show_u8(buf, test_fw_config->read_fw_idx);
0635 }
0636 static DEVICE_ATTR_RW(config_read_fw_idx);
0637
0638
0639 static ssize_t trigger_request_store(struct device *dev,
0640 struct device_attribute *attr,
0641 const char *buf, size_t count)
0642 {
0643 int rc;
0644 char *name;
0645
0646 name = kstrndup(buf, count, GFP_KERNEL);
0647 if (!name)
0648 return -ENOSPC;
0649
0650 pr_info("loading '%s'\n", name);
0651
0652 mutex_lock(&test_fw_mutex);
0653 release_firmware(test_firmware);
0654 test_firmware = NULL;
0655 rc = request_firmware(&test_firmware, name, dev);
0656 if (rc) {
0657 pr_info("load of '%s' failed: %d\n", name, rc);
0658 goto out;
0659 }
0660 pr_info("loaded: %zu\n", test_firmware->size);
0661 rc = count;
0662
0663 out:
0664 mutex_unlock(&test_fw_mutex);
0665
0666 kfree(name);
0667
0668 return rc;
0669 }
0670 static DEVICE_ATTR_WO(trigger_request);
0671
0672 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
0673 extern struct list_head efi_embedded_fw_list;
0674 extern bool efi_embedded_fw_checked;
0675
0676 static ssize_t trigger_request_platform_store(struct device *dev,
0677 struct device_attribute *attr,
0678 const char *buf, size_t count)
0679 {
0680 static const u8 test_data[] = {
0681 0x55, 0xaa, 0x55, 0xaa, 0x01, 0x02, 0x03, 0x04,
0682 0x55, 0xaa, 0x55, 0xaa, 0x05, 0x06, 0x07, 0x08,
0683 0x55, 0xaa, 0x55, 0xaa, 0x10, 0x20, 0x30, 0x40,
0684 0x55, 0xaa, 0x55, 0xaa, 0x50, 0x60, 0x70, 0x80
0685 };
0686 struct efi_embedded_fw efi_embedded_fw;
0687 const struct firmware *firmware = NULL;
0688 bool saved_efi_embedded_fw_checked;
0689 char *name;
0690 int rc;
0691
0692 name = kstrndup(buf, count, GFP_KERNEL);
0693 if (!name)
0694 return -ENOSPC;
0695
0696 pr_info("inserting test platform fw '%s'\n", name);
0697 efi_embedded_fw.name = name;
0698 efi_embedded_fw.data = (void *)test_data;
0699 efi_embedded_fw.length = sizeof(test_data);
0700 list_add(&efi_embedded_fw.list, &efi_embedded_fw_list);
0701 saved_efi_embedded_fw_checked = efi_embedded_fw_checked;
0702 efi_embedded_fw_checked = true;
0703
0704 pr_info("loading '%s'\n", name);
0705 rc = firmware_request_platform(&firmware, name, dev);
0706 if (rc) {
0707 pr_info("load of '%s' failed: %d\n", name, rc);
0708 goto out;
0709 }
0710 if (firmware->size != sizeof(test_data) ||
0711 memcmp(firmware->data, test_data, sizeof(test_data)) != 0) {
0712 pr_info("firmware contents mismatch for '%s'\n", name);
0713 rc = -EINVAL;
0714 goto out;
0715 }
0716 pr_info("loaded: %zu\n", firmware->size);
0717 rc = count;
0718
0719 out:
0720 efi_embedded_fw_checked = saved_efi_embedded_fw_checked;
0721 release_firmware(firmware);
0722 list_del(&efi_embedded_fw.list);
0723 kfree(name);
0724
0725 return rc;
0726 }
0727 static DEVICE_ATTR_WO(trigger_request_platform);
0728 #endif
0729
0730 static DECLARE_COMPLETION(async_fw_done);
0731
0732 static void trigger_async_request_cb(const struct firmware *fw, void *context)
0733 {
0734 test_firmware = fw;
0735 complete(&async_fw_done);
0736 }
0737
0738 static ssize_t trigger_async_request_store(struct device *dev,
0739 struct device_attribute *attr,
0740 const char *buf, size_t count)
0741 {
0742 int rc;
0743 char *name;
0744
0745 name = kstrndup(buf, count, GFP_KERNEL);
0746 if (!name)
0747 return -ENOSPC;
0748
0749 pr_info("loading '%s'\n", name);
0750
0751 mutex_lock(&test_fw_mutex);
0752 release_firmware(test_firmware);
0753 test_firmware = NULL;
0754 rc = request_firmware_nowait(THIS_MODULE, 1, name, dev, GFP_KERNEL,
0755 NULL, trigger_async_request_cb);
0756 if (rc) {
0757 pr_info("async load of '%s' failed: %d\n", name, rc);
0758 kfree(name);
0759 goto out;
0760 }
0761
0762 kfree(name);
0763
0764 wait_for_completion(&async_fw_done);
0765
0766 if (test_firmware) {
0767 pr_info("loaded: %zu\n", test_firmware->size);
0768 rc = count;
0769 } else {
0770 pr_err("failed to async load firmware\n");
0771 rc = -ENOMEM;
0772 }
0773
0774 out:
0775 mutex_unlock(&test_fw_mutex);
0776
0777 return rc;
0778 }
0779 static DEVICE_ATTR_WO(trigger_async_request);
0780
0781 static ssize_t trigger_custom_fallback_store(struct device *dev,
0782 struct device_attribute *attr,
0783 const char *buf, size_t count)
0784 {
0785 int rc;
0786 char *name;
0787
0788 name = kstrndup(buf, count, GFP_KERNEL);
0789 if (!name)
0790 return -ENOSPC;
0791
0792 pr_info("loading '%s' using custom fallback mechanism\n", name);
0793
0794 mutex_lock(&test_fw_mutex);
0795 release_firmware(test_firmware);
0796 test_firmware = NULL;
0797 rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOUEVENT, name,
0798 dev, GFP_KERNEL, NULL,
0799 trigger_async_request_cb);
0800 if (rc) {
0801 pr_info("async load of '%s' failed: %d\n", name, rc);
0802 kfree(name);
0803 goto out;
0804 }
0805
0806 kfree(name);
0807
0808 wait_for_completion(&async_fw_done);
0809
0810 if (test_firmware) {
0811 pr_info("loaded: %zu\n", test_firmware->size);
0812 rc = count;
0813 } else {
0814 pr_err("failed to async load firmware\n");
0815 rc = -ENODEV;
0816 }
0817
0818 out:
0819 mutex_unlock(&test_fw_mutex);
0820
0821 return rc;
0822 }
0823 static DEVICE_ATTR_WO(trigger_custom_fallback);
0824
0825 static int test_fw_run_batch_request(void *data)
0826 {
0827 struct test_batched_req *req = data;
0828
0829 if (!req) {
0830 test_fw_config->test_result = -EINVAL;
0831 return -EINVAL;
0832 }
0833
0834 if (test_fw_config->into_buf) {
0835 void *test_buf;
0836
0837 test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL);
0838 if (!test_buf)
0839 return -ENOSPC;
0840
0841 if (test_fw_config->partial)
0842 req->rc = request_partial_firmware_into_buf
0843 (&req->fw,
0844 req->name,
0845 req->dev,
0846 test_buf,
0847 test_fw_config->buf_size,
0848 test_fw_config->file_offset);
0849 else
0850 req->rc = request_firmware_into_buf
0851 (&req->fw,
0852 req->name,
0853 req->dev,
0854 test_buf,
0855 test_fw_config->buf_size);
0856 if (!req->fw)
0857 kfree(test_buf);
0858 } else {
0859 req->rc = test_fw_config->req_firmware(&req->fw,
0860 req->name,
0861 req->dev);
0862 }
0863
0864 if (req->rc) {
0865 pr_info("#%u: batched sync load failed: %d\n",
0866 req->idx, req->rc);
0867 if (!test_fw_config->test_result)
0868 test_fw_config->test_result = req->rc;
0869 } else if (req->fw) {
0870 req->sent = true;
0871 pr_info("#%u: batched sync loaded %zu\n",
0872 req->idx, req->fw->size);
0873 }
0874 complete(&req->completion);
0875
0876 req->task = NULL;
0877
0878 return 0;
0879 }
0880
0881
0882
0883
0884
0885
0886
0887 static ssize_t trigger_batched_requests_store(struct device *dev,
0888 struct device_attribute *attr,
0889 const char *buf, size_t count)
0890 {
0891 struct test_batched_req *req;
0892 int rc;
0893 u8 i;
0894
0895 mutex_lock(&test_fw_mutex);
0896
0897 test_fw_config->reqs =
0898 vzalloc(array3_size(sizeof(struct test_batched_req),
0899 test_fw_config->num_requests, 2));
0900 if (!test_fw_config->reqs) {
0901 rc = -ENOMEM;
0902 goto out_unlock;
0903 }
0904
0905 pr_info("batched sync firmware loading '%s' %u times\n",
0906 test_fw_config->name, test_fw_config->num_requests);
0907
0908 for (i = 0; i < test_fw_config->num_requests; i++) {
0909 req = &test_fw_config->reqs[i];
0910 req->fw = NULL;
0911 req->idx = i;
0912 req->name = test_fw_config->name;
0913 req->dev = dev;
0914 init_completion(&req->completion);
0915 req->task = kthread_run(test_fw_run_batch_request, req,
0916 "%s-%u", KBUILD_MODNAME, req->idx);
0917 if (!req->task || IS_ERR(req->task)) {
0918 pr_err("Setting up thread %u failed\n", req->idx);
0919 req->task = NULL;
0920 rc = -ENOMEM;
0921 goto out_bail;
0922 }
0923 }
0924
0925 rc = count;
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935 out_bail:
0936 for (i = 0; i < test_fw_config->num_requests; i++) {
0937 req = &test_fw_config->reqs[i];
0938 if (req->task || req->sent)
0939 wait_for_completion(&req->completion);
0940 }
0941
0942
0943 if (rc < 0)
0944 test_fw_config->test_result = rc;
0945
0946 out_unlock:
0947 mutex_unlock(&test_fw_mutex);
0948
0949 return rc;
0950 }
0951 static DEVICE_ATTR_WO(trigger_batched_requests);
0952
0953
0954
0955
0956 static void trigger_batched_cb(const struct firmware *fw, void *context)
0957 {
0958 struct test_batched_req *req = context;
0959
0960 if (!req) {
0961 test_fw_config->test_result = -EINVAL;
0962 return;
0963 }
0964
0965
0966 if (!req->idx)
0967 ssleep(2);
0968
0969 req->fw = fw;
0970
0971
0972
0973
0974
0975
0976
0977 if (!fw && !test_fw_config->test_result)
0978 test_fw_config->test_result = -ENOENT;
0979
0980 complete(&req->completion);
0981 }
0982
0983 static
0984 ssize_t trigger_batched_requests_async_store(struct device *dev,
0985 struct device_attribute *attr,
0986 const char *buf, size_t count)
0987 {
0988 struct test_batched_req *req;
0989 bool send_uevent;
0990 int rc;
0991 u8 i;
0992
0993 mutex_lock(&test_fw_mutex);
0994
0995 test_fw_config->reqs =
0996 vzalloc(array3_size(sizeof(struct test_batched_req),
0997 test_fw_config->num_requests, 2));
0998 if (!test_fw_config->reqs) {
0999 rc = -ENOMEM;
1000 goto out;
1001 }
1002
1003 pr_info("batched loading '%s' custom fallback mechanism %u times\n",
1004 test_fw_config->name, test_fw_config->num_requests);
1005
1006 send_uevent = test_fw_config->send_uevent ? FW_ACTION_UEVENT :
1007 FW_ACTION_NOUEVENT;
1008
1009 for (i = 0; i < test_fw_config->num_requests; i++) {
1010 req = &test_fw_config->reqs[i];
1011 req->name = test_fw_config->name;
1012 req->fw = NULL;
1013 req->idx = i;
1014 init_completion(&req->completion);
1015 rc = request_firmware_nowait(THIS_MODULE, send_uevent,
1016 req->name,
1017 dev, GFP_KERNEL, req,
1018 trigger_batched_cb);
1019 if (rc) {
1020 pr_info("#%u: batched async load failed setup: %d\n",
1021 i, rc);
1022 req->rc = rc;
1023 goto out_bail;
1024 } else
1025 req->sent = true;
1026 }
1027
1028 rc = count;
1029
1030 out_bail:
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040 for (i = 0; i < test_fw_config->num_requests; i++) {
1041 req = &test_fw_config->reqs[i];
1042 if (req->sent)
1043 wait_for_completion(&req->completion);
1044 }
1045
1046
1047 if (rc < 0)
1048 test_fw_config->test_result = rc;
1049
1050 out:
1051 mutex_unlock(&test_fw_mutex);
1052
1053 return rc;
1054 }
1055 static DEVICE_ATTR_WO(trigger_batched_requests_async);
1056
1057 static void upload_release(struct test_firmware_upload *tst)
1058 {
1059 firmware_upload_unregister(tst->fwl);
1060 kfree(tst->buf);
1061 kfree(tst->name);
1062 kfree(tst);
1063 }
1064
1065 static void upload_release_all(void)
1066 {
1067 struct test_firmware_upload *tst, *tmp;
1068
1069 list_for_each_entry_safe(tst, tmp, &test_upload_list, node) {
1070 list_del(&tst->node);
1071 upload_release(tst);
1072 }
1073 test_fw_config->upload_name = NULL;
1074 }
1075
1076
1077
1078
1079
1080 static const char * const fw_upload_err_str[] = {
1081 [FW_UPLOAD_ERR_NONE] = "none",
1082 [FW_UPLOAD_ERR_HW_ERROR] = "hw-error",
1083 [FW_UPLOAD_ERR_TIMEOUT] = "timeout",
1084 [FW_UPLOAD_ERR_CANCELED] = "user-abort",
1085 [FW_UPLOAD_ERR_BUSY] = "device-busy",
1086 [FW_UPLOAD_ERR_INVALID_SIZE] = "invalid-file-size",
1087 [FW_UPLOAD_ERR_RW_ERROR] = "read-write-error",
1088 [FW_UPLOAD_ERR_WEAROUT] = "flash-wearout",
1089 };
1090
1091 static void upload_err_inject_error(struct test_firmware_upload *tst,
1092 const u8 *p, const char *prog)
1093 {
1094 enum fw_upload_err err;
1095
1096 for (err = FW_UPLOAD_ERR_NONE + 1; err < FW_UPLOAD_ERR_MAX; err++) {
1097 if (strncmp(p, fw_upload_err_str[err],
1098 strlen(fw_upload_err_str[err])) == 0) {
1099 tst->inject.prog = prog;
1100 tst->inject.err_code = err;
1101 return;
1102 }
1103 }
1104 }
1105
1106 static void upload_err_inject_prog(struct test_firmware_upload *tst,
1107 const u8 *p)
1108 {
1109 static const char * const progs[] = {
1110 "preparing:", "transferring:", "programming:"
1111 };
1112 int i;
1113
1114 for (i = 0; i < ARRAY_SIZE(progs); i++) {
1115 if (strncmp(p, progs[i], strlen(progs[i])) == 0) {
1116 upload_err_inject_error(tst, p + strlen(progs[i]),
1117 progs[i]);
1118 return;
1119 }
1120 }
1121 }
1122
1123 #define FIVE_MINUTES_MS (5 * 60 * 1000)
1124 static enum fw_upload_err
1125 fw_upload_wait_on_cancel(struct test_firmware_upload *tst)
1126 {
1127 int ms_delay;
1128
1129 for (ms_delay = 0; ms_delay < FIVE_MINUTES_MS; ms_delay += 100) {
1130 msleep(100);
1131 if (tst->cancel_request)
1132 return FW_UPLOAD_ERR_CANCELED;
1133 }
1134 return FW_UPLOAD_ERR_NONE;
1135 }
1136
1137 static enum fw_upload_err test_fw_upload_prepare(struct fw_upload *fwl,
1138 const u8 *data, u32 size)
1139 {
1140 struct test_firmware_upload *tst = fwl->dd_handle;
1141 enum fw_upload_err ret = FW_UPLOAD_ERR_NONE;
1142 const char *progress = "preparing:";
1143
1144 tst->cancel_request = false;
1145
1146 if (!size || size > TEST_UPLOAD_MAX_SIZE) {
1147 ret = FW_UPLOAD_ERR_INVALID_SIZE;
1148 goto err_out;
1149 }
1150
1151 if (strncmp(data, "inject:", strlen("inject:")) == 0)
1152 upload_err_inject_prog(tst, data + strlen("inject:"));
1153
1154 memset(tst->buf, 0, TEST_UPLOAD_MAX_SIZE);
1155 tst->size = size;
1156
1157 if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
1158 strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
1159 return FW_UPLOAD_ERR_NONE;
1160
1161 if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
1162 ret = fw_upload_wait_on_cancel(tst);
1163 else
1164 ret = tst->inject.err_code;
1165
1166 err_out:
1167
1168
1169
1170
1171 tst->inject.err_code = FW_UPLOAD_ERR_NONE;
1172 tst->inject.prog = NULL;
1173
1174 return ret;
1175 }
1176
1177 static enum fw_upload_err test_fw_upload_write(struct fw_upload *fwl,
1178 const u8 *data, u32 offset,
1179 u32 size, u32 *written)
1180 {
1181 struct test_firmware_upload *tst = fwl->dd_handle;
1182 const char *progress = "transferring:";
1183 u32 blk_size;
1184
1185 if (tst->cancel_request)
1186 return FW_UPLOAD_ERR_CANCELED;
1187
1188 blk_size = min_t(u32, TEST_UPLOAD_BLK_SIZE, size);
1189 memcpy(tst->buf + offset, data + offset, blk_size);
1190
1191 *written = blk_size;
1192
1193 if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
1194 strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
1195 return FW_UPLOAD_ERR_NONE;
1196
1197 if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
1198 return fw_upload_wait_on_cancel(tst);
1199
1200 return tst->inject.err_code;
1201 }
1202
1203 static enum fw_upload_err test_fw_upload_complete(struct fw_upload *fwl)
1204 {
1205 struct test_firmware_upload *tst = fwl->dd_handle;
1206 const char *progress = "programming:";
1207
1208 if (tst->cancel_request)
1209 return FW_UPLOAD_ERR_CANCELED;
1210
1211 if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
1212 strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
1213 return FW_UPLOAD_ERR_NONE;
1214
1215 if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
1216 return fw_upload_wait_on_cancel(tst);
1217
1218 return tst->inject.err_code;
1219 }
1220
1221 static void test_fw_upload_cancel(struct fw_upload *fwl)
1222 {
1223 struct test_firmware_upload *tst = fwl->dd_handle;
1224
1225 tst->cancel_request = true;
1226 }
1227
1228 static void test_fw_cleanup(struct fw_upload *fwl)
1229 {
1230 struct test_firmware_upload *tst = fwl->dd_handle;
1231
1232 tst->inject.err_code = FW_UPLOAD_ERR_NONE;
1233 tst->inject.prog = NULL;
1234 }
1235
1236 static const struct fw_upload_ops upload_test_ops = {
1237 .prepare = test_fw_upload_prepare,
1238 .write = test_fw_upload_write,
1239 .poll_complete = test_fw_upload_complete,
1240 .cancel = test_fw_upload_cancel,
1241 .cleanup = test_fw_cleanup
1242 };
1243
1244 static ssize_t upload_register_store(struct device *dev,
1245 struct device_attribute *attr,
1246 const char *buf, size_t count)
1247 {
1248 struct test_firmware_upload *tst;
1249 struct fw_upload *fwl;
1250 char *name;
1251 int ret;
1252
1253 name = kstrndup(buf, count, GFP_KERNEL);
1254 if (!name)
1255 return -ENOMEM;
1256
1257 mutex_lock(&test_fw_mutex);
1258 tst = upload_lookup_name(name);
1259 if (tst) {
1260 ret = -EEXIST;
1261 goto free_name;
1262 }
1263
1264 tst = kzalloc(sizeof(*tst), GFP_KERNEL);
1265 if (!tst) {
1266 ret = -ENOMEM;
1267 goto free_name;
1268 }
1269
1270 tst->name = name;
1271 tst->buf = kzalloc(TEST_UPLOAD_MAX_SIZE, GFP_KERNEL);
1272 if (!tst->buf) {
1273 ret = -ENOMEM;
1274 goto free_tst;
1275 }
1276
1277 fwl = firmware_upload_register(THIS_MODULE, dev, tst->name,
1278 &upload_test_ops, tst);
1279 if (IS_ERR(fwl)) {
1280 ret = PTR_ERR(fwl);
1281 goto free_buf;
1282 }
1283
1284 tst->fwl = fwl;
1285 list_add_tail(&tst->node, &test_upload_list);
1286 mutex_unlock(&test_fw_mutex);
1287 return count;
1288
1289 free_buf:
1290 kfree(tst->buf);
1291
1292 free_tst:
1293 kfree(tst);
1294
1295 free_name:
1296 mutex_unlock(&test_fw_mutex);
1297 kfree(name);
1298
1299 return ret;
1300 }
1301 static DEVICE_ATTR_WO(upload_register);
1302
1303 static ssize_t upload_unregister_store(struct device *dev,
1304 struct device_attribute *attr,
1305 const char *buf, size_t count)
1306 {
1307 struct test_firmware_upload *tst;
1308 int ret = count;
1309
1310 mutex_lock(&test_fw_mutex);
1311 tst = upload_lookup_name(buf);
1312 if (!tst) {
1313 ret = -EINVAL;
1314 goto out;
1315 }
1316
1317 if (test_fw_config->upload_name == tst->name)
1318 test_fw_config->upload_name = NULL;
1319
1320 list_del(&tst->node);
1321 upload_release(tst);
1322
1323 out:
1324 mutex_unlock(&test_fw_mutex);
1325 return ret;
1326 }
1327 static DEVICE_ATTR_WO(upload_unregister);
1328
1329 static ssize_t test_result_show(struct device *dev,
1330 struct device_attribute *attr,
1331 char *buf)
1332 {
1333 return test_dev_config_show_int(buf, test_fw_config->test_result);
1334 }
1335 static DEVICE_ATTR_RO(test_result);
1336
1337 static ssize_t release_all_firmware_store(struct device *dev,
1338 struct device_attribute *attr,
1339 const char *buf, size_t count)
1340 {
1341 test_release_all_firmware();
1342 return count;
1343 }
1344 static DEVICE_ATTR_WO(release_all_firmware);
1345
1346 static ssize_t read_firmware_show(struct device *dev,
1347 struct device_attribute *attr,
1348 char *buf)
1349 {
1350 struct test_batched_req *req;
1351 u8 idx;
1352 ssize_t rc = 0;
1353
1354 mutex_lock(&test_fw_mutex);
1355
1356 idx = test_fw_config->read_fw_idx;
1357 if (idx >= test_fw_config->num_requests) {
1358 rc = -ERANGE;
1359 goto out;
1360 }
1361
1362 if (!test_fw_config->reqs) {
1363 rc = -EINVAL;
1364 goto out;
1365 }
1366
1367 req = &test_fw_config->reqs[idx];
1368 if (!req->fw) {
1369 pr_err("#%u: failed to async load firmware\n", idx);
1370 rc = -ENOENT;
1371 goto out;
1372 }
1373
1374 pr_info("#%u: loaded %zu\n", idx, req->fw->size);
1375
1376 if (req->fw->size > PAGE_SIZE) {
1377 pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
1378 rc = -EINVAL;
1379 goto out;
1380 }
1381 memcpy(buf, req->fw->data, req->fw->size);
1382
1383 rc = req->fw->size;
1384 out:
1385 mutex_unlock(&test_fw_mutex);
1386
1387 return rc;
1388 }
1389 static DEVICE_ATTR_RO(read_firmware);
1390
1391 static ssize_t upload_read_show(struct device *dev,
1392 struct device_attribute *attr,
1393 char *buf)
1394 {
1395 struct test_firmware_upload *tst = NULL;
1396 struct test_firmware_upload *tst_iter;
1397 int ret = -EINVAL;
1398
1399 if (!test_fw_config->upload_name) {
1400 pr_err("Set config_upload_name before using upload_read\n");
1401 return -EINVAL;
1402 }
1403
1404 mutex_lock(&test_fw_mutex);
1405 list_for_each_entry(tst_iter, &test_upload_list, node)
1406 if (tst_iter->name == test_fw_config->upload_name) {
1407 tst = tst_iter;
1408 break;
1409 }
1410
1411 if (!tst) {
1412 pr_err("Firmware name not found: %s\n",
1413 test_fw_config->upload_name);
1414 goto out;
1415 }
1416
1417 if (tst->size > PAGE_SIZE) {
1418 pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
1419 goto out;
1420 }
1421
1422 memcpy(buf, tst->buf, tst->size);
1423 ret = tst->size;
1424 out:
1425 mutex_unlock(&test_fw_mutex);
1426 return ret;
1427 }
1428 static DEVICE_ATTR_RO(upload_read);
1429
1430 #define TEST_FW_DEV_ATTR(name) &dev_attr_##name.attr
1431
1432 static struct attribute *test_dev_attrs[] = {
1433 TEST_FW_DEV_ATTR(reset),
1434
1435 TEST_FW_DEV_ATTR(config),
1436 TEST_FW_DEV_ATTR(config_name),
1437 TEST_FW_DEV_ATTR(config_num_requests),
1438 TEST_FW_DEV_ATTR(config_into_buf),
1439 TEST_FW_DEV_ATTR(config_buf_size),
1440 TEST_FW_DEV_ATTR(config_file_offset),
1441 TEST_FW_DEV_ATTR(config_partial),
1442 TEST_FW_DEV_ATTR(config_sync_direct),
1443 TEST_FW_DEV_ATTR(config_send_uevent),
1444 TEST_FW_DEV_ATTR(config_read_fw_idx),
1445 TEST_FW_DEV_ATTR(config_upload_name),
1446
1447
1448 TEST_FW_DEV_ATTR(trigger_request),
1449 TEST_FW_DEV_ATTR(trigger_async_request),
1450 TEST_FW_DEV_ATTR(trigger_custom_fallback),
1451 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
1452 TEST_FW_DEV_ATTR(trigger_request_platform),
1453 #endif
1454
1455
1456 TEST_FW_DEV_ATTR(trigger_batched_requests),
1457 TEST_FW_DEV_ATTR(trigger_batched_requests_async),
1458
1459 TEST_FW_DEV_ATTR(release_all_firmware),
1460 TEST_FW_DEV_ATTR(test_result),
1461 TEST_FW_DEV_ATTR(read_firmware),
1462 TEST_FW_DEV_ATTR(upload_read),
1463 TEST_FW_DEV_ATTR(upload_register),
1464 TEST_FW_DEV_ATTR(upload_unregister),
1465 NULL,
1466 };
1467
1468 ATTRIBUTE_GROUPS(test_dev);
1469
1470 static struct miscdevice test_fw_misc_device = {
1471 .minor = MISC_DYNAMIC_MINOR,
1472 .name = "test_firmware",
1473 .fops = &test_fw_fops,
1474 .groups = test_dev_groups,
1475 };
1476
1477 static int __init test_firmware_init(void)
1478 {
1479 int rc;
1480
1481 test_fw_config = kzalloc(sizeof(struct test_config), GFP_KERNEL);
1482 if (!test_fw_config)
1483 return -ENOMEM;
1484
1485 rc = __test_firmware_config_init();
1486 if (rc) {
1487 kfree(test_fw_config);
1488 pr_err("could not init firmware test config: %d\n", rc);
1489 return rc;
1490 }
1491
1492 rc = misc_register(&test_fw_misc_device);
1493 if (rc) {
1494 kfree(test_fw_config);
1495 pr_err("could not register misc device: %d\n", rc);
1496 return rc;
1497 }
1498
1499 pr_warn("interface ready\n");
1500
1501 return 0;
1502 }
1503
1504 module_init(test_firmware_init);
1505
1506 static void __exit test_firmware_exit(void)
1507 {
1508 mutex_lock(&test_fw_mutex);
1509 release_firmware(test_firmware);
1510 misc_deregister(&test_fw_misc_device);
1511 upload_release_all();
1512 __test_firmware_config_free();
1513 kfree(test_fw_config);
1514 mutex_unlock(&test_fw_mutex);
1515
1516 pr_warn("removed interface\n");
1517 }
1518
1519 module_exit(test_firmware_exit);
1520
1521 MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
1522 MODULE_LICENSE("GPL");