test_firmware.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933
  1. /*
  2. * This module provides an interface to trigger and test firmware loading.
  3. *
  4. * It is designed to be used for basic evaluation of the firmware loading
  5. * subsystem (for example when validating firmware verification). It lacks
  6. * any extra dependencies, and will not normally be loaded by the system
  7. * unless explicitly requested by name.
  8. */
  9. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  10. #include <linux/init.h>
  11. #include <linux/module.h>
  12. #include <linux/printk.h>
  13. #include <linux/completion.h>
  14. #include <linux/firmware.h>
  15. #include <linux/device.h>
  16. #include <linux/fs.h>
  17. #include <linux/miscdevice.h>
  18. #include <linux/slab.h>
  19. #include <linux/uaccess.h>
  20. #include <linux/delay.h>
  21. #include <linux/kthread.h>
  22. #include <linux/vmalloc.h>
  23. #define TEST_FIRMWARE_NAME "test-firmware.bin"
  24. #define TEST_FIRMWARE_NUM_REQS 4
  25. static DEFINE_MUTEX(test_fw_mutex);
  26. static const struct firmware *test_firmware;
  27. struct test_batched_req {
  28. u8 idx;
  29. int rc;
  30. bool sent;
  31. const struct firmware *fw;
  32. const char *name;
  33. struct completion completion;
  34. struct task_struct *task;
  35. struct device *dev;
  36. };
  37. /**
  38. * test_config - represents configuration for the test for different triggers
  39. *
  40. * @name: the name of the firmware file to look for
  41. * @sync_direct: when the sync trigger is used if this is true
  42. * request_firmware_direct() will be used instead.
  43. * @send_uevent: whether or not to send a uevent for async requests
  44. * @num_requests: number of requests to try per test case. This is trigger
  45. * specific.
  46. * @reqs: stores all requests information
  47. * @read_fw_idx: index of thread from which we want to read firmware results
  48. * from through the read_fw trigger.
  49. * @test_result: a test may use this to collect the result from the call
  50. * of the request_firmware*() calls used in their tests. In order of
  51. * priority we always keep first any setup error. If no setup errors were
  52. * found then we move on to the first error encountered while running the
  53. * API. Note that for async calls this typically will be a successful
  54. * result (0) unless of course you've used bogus parameters, or the system
  55. * is out of memory. In the async case the callback is expected to do a
  56. * bit more homework to figure out what happened, unfortunately the only
  57. * information passed today on error is the fact that no firmware was
  58. * found so we can only assume -ENOENT on async calls if the firmware is
  59. * NULL.
  60. *
  61. * Errors you can expect:
  62. *
  63. * API specific:
  64. *
  65. * 0: success for sync, for async it means request was sent
  66. * -EINVAL: invalid parameters or request
  67. * -ENOENT: files not found
  68. *
  69. * System environment:
  70. *
  71. * -ENOMEM: memory pressure on system
  72. * -ENODEV: out of number of devices to test
  73. * -EINVAL: an unexpected error has occurred
  74. * @req_firmware: if @sync_direct is true this is set to
  75. * request_firmware_direct(), otherwise request_firmware()
  76. */
  77. struct test_config {
  78. char *name;
  79. bool sync_direct;
  80. bool send_uevent;
  81. u8 num_requests;
  82. u8 read_fw_idx;
  83. /*
  84. * These below don't belong her but we'll move them once we create
  85. * a struct fw_test_device and stuff the misc_dev under there later.
  86. */
  87. struct test_batched_req *reqs;
  88. int test_result;
  89. int (*req_firmware)(const struct firmware **fw, const char *name,
  90. struct device *device);
  91. };
  92. static struct test_config *test_fw_config;
  93. static ssize_t test_fw_misc_read(struct file *f, char __user *buf,
  94. size_t size, loff_t *offset)
  95. {
  96. ssize_t rc = 0;
  97. mutex_lock(&test_fw_mutex);
  98. if (test_firmware)
  99. rc = simple_read_from_buffer(buf, size, offset,
  100. test_firmware->data,
  101. test_firmware->size);
  102. mutex_unlock(&test_fw_mutex);
  103. return rc;
  104. }
  105. static const struct file_operations test_fw_fops = {
  106. .owner = THIS_MODULE,
  107. .read = test_fw_misc_read,
  108. };
  109. static void __test_release_all_firmware(void)
  110. {
  111. struct test_batched_req *req;
  112. u8 i;
  113. if (!test_fw_config->reqs)
  114. return;
  115. for (i = 0; i < test_fw_config->num_requests; i++) {
  116. req = &test_fw_config->reqs[i];
  117. if (req->fw)
  118. release_firmware(req->fw);
  119. }
  120. vfree(test_fw_config->reqs);
  121. test_fw_config->reqs = NULL;
  122. }
  123. static void test_release_all_firmware(void)
  124. {
  125. mutex_lock(&test_fw_mutex);
  126. __test_release_all_firmware();
  127. mutex_unlock(&test_fw_mutex);
  128. }
  129. static void __test_firmware_config_free(void)
  130. {
  131. __test_release_all_firmware();
  132. kfree_const(test_fw_config->name);
  133. test_fw_config->name = NULL;
  134. }
  135. /*
  136. * XXX: move to kstrncpy() once merged.
  137. *
  138. * Users should use kfree_const() when freeing these.
  139. */
  140. static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp)
  141. {
  142. *dst = kstrndup(name, count, gfp);
  143. if (!*dst)
  144. return -ENOSPC;
  145. return count;
  146. }
  147. static int __test_firmware_config_init(void)
  148. {
  149. int ret;
  150. ret = __kstrncpy(&test_fw_config->name, TEST_FIRMWARE_NAME,
  151. strlen(TEST_FIRMWARE_NAME), GFP_KERNEL);
  152. if (ret < 0)
  153. goto out;
  154. test_fw_config->num_requests = TEST_FIRMWARE_NUM_REQS;
  155. test_fw_config->send_uevent = true;
  156. test_fw_config->sync_direct = false;
  157. test_fw_config->req_firmware = request_firmware;
  158. test_fw_config->test_result = 0;
  159. test_fw_config->reqs = NULL;
  160. return 0;
  161. out:
  162. __test_firmware_config_free();
  163. return ret;
  164. }
  165. static ssize_t reset_store(struct device *dev,
  166. struct device_attribute *attr,
  167. const char *buf, size_t count)
  168. {
  169. int ret;
  170. mutex_lock(&test_fw_mutex);
  171. __test_firmware_config_free();
  172. ret = __test_firmware_config_init();
  173. if (ret < 0) {
  174. ret = -ENOMEM;
  175. pr_err("could not alloc settings for config trigger: %d\n",
  176. ret);
  177. goto out;
  178. }
  179. pr_info("reset\n");
  180. ret = count;
  181. out:
  182. mutex_unlock(&test_fw_mutex);
  183. return ret;
  184. }
  185. static DEVICE_ATTR_WO(reset);
  186. static ssize_t config_show(struct device *dev,
  187. struct device_attribute *attr,
  188. char *buf)
  189. {
  190. int len = 0;
  191. mutex_lock(&test_fw_mutex);
  192. len += scnprintf(buf, PAGE_SIZE - len,
  193. "Custom trigger configuration for: %s\n",
  194. dev_name(dev));
  195. if (test_fw_config->name)
  196. len += scnprintf(buf+len, PAGE_SIZE - len,
  197. "name:\t%s\n",
  198. test_fw_config->name);
  199. else
  200. len += scnprintf(buf+len, PAGE_SIZE - len,
  201. "name:\tEMTPY\n");
  202. len += scnprintf(buf+len, PAGE_SIZE - len,
  203. "num_requests:\t%u\n", test_fw_config->num_requests);
  204. len += scnprintf(buf+len, PAGE_SIZE - len,
  205. "send_uevent:\t\t%s\n",
  206. test_fw_config->send_uevent ?
  207. "FW_ACTION_HOTPLUG" :
  208. "FW_ACTION_NOHOTPLUG");
  209. len += scnprintf(buf+len, PAGE_SIZE - len,
  210. "sync_direct:\t\t%s\n",
  211. test_fw_config->sync_direct ? "true" : "false");
  212. len += scnprintf(buf+len, PAGE_SIZE - len,
  213. "read_fw_idx:\t%u\n", test_fw_config->read_fw_idx);
  214. mutex_unlock(&test_fw_mutex);
  215. return len;
  216. }
  217. static DEVICE_ATTR_RO(config);
  218. static ssize_t config_name_store(struct device *dev,
  219. struct device_attribute *attr,
  220. const char *buf, size_t count)
  221. {
  222. int ret;
  223. mutex_lock(&test_fw_mutex);
  224. kfree_const(test_fw_config->name);
  225. ret = __kstrncpy(&test_fw_config->name, buf, count, GFP_KERNEL);
  226. mutex_unlock(&test_fw_mutex);
  227. return ret;
  228. }
  229. /*
  230. * As per sysfs_kf_seq_show() the buf is max PAGE_SIZE.
  231. */
  232. static ssize_t config_test_show_str(char *dst,
  233. char *src)
  234. {
  235. int len;
  236. mutex_lock(&test_fw_mutex);
  237. len = snprintf(dst, PAGE_SIZE, "%s\n", src);
  238. mutex_unlock(&test_fw_mutex);
  239. return len;
  240. }
  241. static int test_dev_config_update_bool(const char *buf, size_t size,
  242. bool *cfg)
  243. {
  244. int ret;
  245. mutex_lock(&test_fw_mutex);
  246. if (strtobool(buf, cfg) < 0)
  247. ret = -EINVAL;
  248. else
  249. ret = size;
  250. mutex_unlock(&test_fw_mutex);
  251. return ret;
  252. }
  253. static ssize_t
  254. test_dev_config_show_bool(char *buf,
  255. bool config)
  256. {
  257. bool val;
  258. mutex_lock(&test_fw_mutex);
  259. val = config;
  260. mutex_unlock(&test_fw_mutex);
  261. return snprintf(buf, PAGE_SIZE, "%d\n", val);
  262. }
  263. static ssize_t test_dev_config_show_int(char *buf, int cfg)
  264. {
  265. int val;
  266. mutex_lock(&test_fw_mutex);
  267. val = cfg;
  268. mutex_unlock(&test_fw_mutex);
  269. return snprintf(buf, PAGE_SIZE, "%d\n", val);
  270. }
  271. static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
  272. {
  273. int ret;
  274. long new;
  275. ret = kstrtol(buf, 10, &new);
  276. if (ret)
  277. return ret;
  278. if (new > U8_MAX)
  279. return -EINVAL;
  280. mutex_lock(&test_fw_mutex);
  281. *(u8 *)cfg = new;
  282. mutex_unlock(&test_fw_mutex);
  283. /* Always return full write size even if we didn't consume all */
  284. return size;
  285. }
  286. static ssize_t test_dev_config_show_u8(char *buf, u8 cfg)
  287. {
  288. u8 val;
  289. mutex_lock(&test_fw_mutex);
  290. val = cfg;
  291. mutex_unlock(&test_fw_mutex);
  292. return snprintf(buf, PAGE_SIZE, "%u\n", val);
  293. }
  294. static ssize_t config_name_show(struct device *dev,
  295. struct device_attribute *attr,
  296. char *buf)
  297. {
  298. return config_test_show_str(buf, test_fw_config->name);
  299. }
  300. static DEVICE_ATTR_RW(config_name);
  301. static ssize_t config_num_requests_store(struct device *dev,
  302. struct device_attribute *attr,
  303. const char *buf, size_t count)
  304. {
  305. int rc;
  306. mutex_lock(&test_fw_mutex);
  307. if (test_fw_config->reqs) {
  308. pr_err("Must call release_all_firmware prior to changing config\n");
  309. rc = -EINVAL;
  310. mutex_unlock(&test_fw_mutex);
  311. goto out;
  312. }
  313. mutex_unlock(&test_fw_mutex);
  314. rc = test_dev_config_update_u8(buf, count,
  315. &test_fw_config->num_requests);
  316. out:
  317. return rc;
  318. }
  319. static ssize_t config_num_requests_show(struct device *dev,
  320. struct device_attribute *attr,
  321. char *buf)
  322. {
  323. return test_dev_config_show_u8(buf, test_fw_config->num_requests);
  324. }
  325. static DEVICE_ATTR_RW(config_num_requests);
  326. static ssize_t config_sync_direct_store(struct device *dev,
  327. struct device_attribute *attr,
  328. const char *buf, size_t count)
  329. {
  330. int rc = test_dev_config_update_bool(buf, count,
  331. &test_fw_config->sync_direct);
  332. if (rc == count)
  333. test_fw_config->req_firmware = test_fw_config->sync_direct ?
  334. request_firmware_direct :
  335. request_firmware;
  336. return rc;
  337. }
  338. static ssize_t config_sync_direct_show(struct device *dev,
  339. struct device_attribute *attr,
  340. char *buf)
  341. {
  342. return test_dev_config_show_bool(buf, test_fw_config->sync_direct);
  343. }
  344. static DEVICE_ATTR_RW(config_sync_direct);
  345. static ssize_t config_send_uevent_store(struct device *dev,
  346. struct device_attribute *attr,
  347. const char *buf, size_t count)
  348. {
  349. return test_dev_config_update_bool(buf, count,
  350. &test_fw_config->send_uevent);
  351. }
  352. static ssize_t config_send_uevent_show(struct device *dev,
  353. struct device_attribute *attr,
  354. char *buf)
  355. {
  356. return test_dev_config_show_bool(buf, test_fw_config->send_uevent);
  357. }
  358. static DEVICE_ATTR_RW(config_send_uevent);
  359. static ssize_t config_read_fw_idx_store(struct device *dev,
  360. struct device_attribute *attr,
  361. const char *buf, size_t count)
  362. {
  363. return test_dev_config_update_u8(buf, count,
  364. &test_fw_config->read_fw_idx);
  365. }
  366. static ssize_t config_read_fw_idx_show(struct device *dev,
  367. struct device_attribute *attr,
  368. char *buf)
  369. {
  370. return test_dev_config_show_u8(buf, test_fw_config->read_fw_idx);
  371. }
  372. static DEVICE_ATTR_RW(config_read_fw_idx);
  373. static ssize_t trigger_request_store(struct device *dev,
  374. struct device_attribute *attr,
  375. const char *buf, size_t count)
  376. {
  377. int rc;
  378. char *name;
  379. name = kstrndup(buf, count, GFP_KERNEL);
  380. if (!name)
  381. return -ENOSPC;
  382. pr_info("loading '%s'\n", name);
  383. mutex_lock(&test_fw_mutex);
  384. release_firmware(test_firmware);
  385. test_firmware = NULL;
  386. rc = request_firmware(&test_firmware, name, dev);
  387. if (rc) {
  388. pr_info("load of '%s' failed: %d\n", name, rc);
  389. goto out;
  390. }
  391. pr_info("loaded: %zu\n", test_firmware->size);
  392. rc = count;
  393. out:
  394. mutex_unlock(&test_fw_mutex);
  395. kfree(name);
  396. return rc;
  397. }
  398. static DEVICE_ATTR_WO(trigger_request);
  399. static DECLARE_COMPLETION(async_fw_done);
  400. static void trigger_async_request_cb(const struct firmware *fw, void *context)
  401. {
  402. test_firmware = fw;
  403. complete(&async_fw_done);
  404. }
  405. static ssize_t trigger_async_request_store(struct device *dev,
  406. struct device_attribute *attr,
  407. const char *buf, size_t count)
  408. {
  409. int rc;
  410. char *name;
  411. name = kstrndup(buf, count, GFP_KERNEL);
  412. if (!name)
  413. return -ENOSPC;
  414. pr_info("loading '%s'\n", name);
  415. mutex_lock(&test_fw_mutex);
  416. release_firmware(test_firmware);
  417. test_firmware = NULL;
  418. rc = request_firmware_nowait(THIS_MODULE, 1, name, dev, GFP_KERNEL,
  419. NULL, trigger_async_request_cb);
  420. if (rc) {
  421. pr_info("async load of '%s' failed: %d\n", name, rc);
  422. kfree(name);
  423. goto out;
  424. }
  425. /* Free 'name' ASAP, to test for race conditions */
  426. kfree(name);
  427. wait_for_completion(&async_fw_done);
  428. if (test_firmware) {
  429. pr_info("loaded: %zu\n", test_firmware->size);
  430. rc = count;
  431. } else {
  432. pr_err("failed to async load firmware\n");
  433. rc = -ENODEV;
  434. }
  435. out:
  436. mutex_unlock(&test_fw_mutex);
  437. return rc;
  438. }
  439. static DEVICE_ATTR_WO(trigger_async_request);
  440. static ssize_t trigger_custom_fallback_store(struct device *dev,
  441. struct device_attribute *attr,
  442. const char *buf, size_t count)
  443. {
  444. int rc;
  445. char *name;
  446. name = kstrndup(buf, count, GFP_KERNEL);
  447. if (!name)
  448. return -ENOSPC;
  449. pr_info("loading '%s' using custom fallback mechanism\n", name);
  450. mutex_lock(&test_fw_mutex);
  451. release_firmware(test_firmware);
  452. test_firmware = NULL;
  453. rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, name,
  454. dev, GFP_KERNEL, NULL,
  455. trigger_async_request_cb);
  456. if (rc) {
  457. pr_info("async load of '%s' failed: %d\n", name, rc);
  458. kfree(name);
  459. goto out;
  460. }
  461. /* Free 'name' ASAP, to test for race conditions */
  462. kfree(name);
  463. wait_for_completion(&async_fw_done);
  464. if (test_firmware) {
  465. pr_info("loaded: %zu\n", test_firmware->size);
  466. rc = count;
  467. } else {
  468. pr_err("failed to async load firmware\n");
  469. rc = -ENODEV;
  470. }
  471. out:
  472. mutex_unlock(&test_fw_mutex);
  473. return rc;
  474. }
  475. static DEVICE_ATTR_WO(trigger_custom_fallback);
  476. static int test_fw_run_batch_request(void *data)
  477. {
  478. struct test_batched_req *req = data;
  479. if (!req) {
  480. test_fw_config->test_result = -EINVAL;
  481. return -EINVAL;
  482. }
  483. req->rc = test_fw_config->req_firmware(&req->fw, req->name, req->dev);
  484. if (req->rc) {
  485. pr_info("#%u: batched sync load failed: %d\n",
  486. req->idx, req->rc);
  487. if (!test_fw_config->test_result)
  488. test_fw_config->test_result = req->rc;
  489. } else if (req->fw) {
  490. req->sent = true;
  491. pr_info("#%u: batched sync loaded %zu\n",
  492. req->idx, req->fw->size);
  493. }
  494. complete(&req->completion);
  495. req->task = NULL;
  496. return 0;
  497. }
  498. /*
  499. * We use a kthread as otherwise the kernel serializes all our sync requests
  500. * and we would not be able to mimic batched requests on a sync call. Batched
  501. * requests on a sync call can for instance happen on a device driver when
  502. * multiple cards are used and firmware loading happens outside of probe.
  503. */
  504. static ssize_t trigger_batched_requests_store(struct device *dev,
  505. struct device_attribute *attr,
  506. const char *buf, size_t count)
  507. {
  508. struct test_batched_req *req;
  509. int rc;
  510. u8 i;
  511. mutex_lock(&test_fw_mutex);
  512. test_fw_config->reqs =
  513. vzalloc(array3_size(sizeof(struct test_batched_req),
  514. test_fw_config->num_requests, 2));
  515. if (!test_fw_config->reqs) {
  516. rc = -ENOMEM;
  517. goto out_unlock;
  518. }
  519. pr_info("batched sync firmware loading '%s' %u times\n",
  520. test_fw_config->name, test_fw_config->num_requests);
  521. for (i = 0; i < test_fw_config->num_requests; i++) {
  522. req = &test_fw_config->reqs[i];
  523. if (!req) {
  524. WARN_ON(1);
  525. rc = -ENOMEM;
  526. goto out_bail;
  527. }
  528. req->fw = NULL;
  529. req->idx = i;
  530. req->name = test_fw_config->name;
  531. req->dev = dev;
  532. init_completion(&req->completion);
  533. req->task = kthread_run(test_fw_run_batch_request, req,
  534. "%s-%u", KBUILD_MODNAME, req->idx);
  535. if (!req->task || IS_ERR(req->task)) {
  536. pr_err("Setting up thread %u failed\n", req->idx);
  537. req->task = NULL;
  538. rc = -ENOMEM;
  539. goto out_bail;
  540. }
  541. }
  542. rc = count;
  543. /*
  544. * We require an explicit release to enable more time and delay of
  545. * calling release_firmware() to improve our chances of forcing a
  546. * batched request. If we instead called release_firmware() right away
  547. * then we might miss on an opportunity of having a successful firmware
  548. * request pass on the opportunity to be come a batched request.
  549. */
  550. out_bail:
  551. for (i = 0; i < test_fw_config->num_requests; i++) {
  552. req = &test_fw_config->reqs[i];
  553. if (req->task || req->sent)
  554. wait_for_completion(&req->completion);
  555. }
  556. /* Override any worker error if we had a general setup error */
  557. if (rc < 0)
  558. test_fw_config->test_result = rc;
  559. out_unlock:
  560. mutex_unlock(&test_fw_mutex);
  561. return rc;
  562. }
  563. static DEVICE_ATTR_WO(trigger_batched_requests);
  564. /*
  565. * We wait for each callback to return with the lock held, no need to lock here
  566. */
  567. static void trigger_batched_cb(const struct firmware *fw, void *context)
  568. {
  569. struct test_batched_req *req = context;
  570. if (!req) {
  571. test_fw_config->test_result = -EINVAL;
  572. return;
  573. }
  574. /* forces *some* batched requests to queue up */
  575. if (!req->idx)
  576. ssleep(2);
  577. req->fw = fw;
  578. /*
  579. * Unfortunately the firmware API gives us nothing other than a null FW
  580. * if the firmware was not found on async requests. Best we can do is
  581. * just assume -ENOENT. A better API would pass the actual return
  582. * value to the callback.
  583. */
  584. if (!fw && !test_fw_config->test_result)
  585. test_fw_config->test_result = -ENOENT;
  586. complete(&req->completion);
  587. }
  588. static
  589. ssize_t trigger_batched_requests_async_store(struct device *dev,
  590. struct device_attribute *attr,
  591. const char *buf, size_t count)
  592. {
  593. struct test_batched_req *req;
  594. bool send_uevent;
  595. int rc;
  596. u8 i;
  597. mutex_lock(&test_fw_mutex);
  598. test_fw_config->reqs =
  599. vzalloc(array3_size(sizeof(struct test_batched_req),
  600. test_fw_config->num_requests, 2));
  601. if (!test_fw_config->reqs) {
  602. rc = -ENOMEM;
  603. goto out;
  604. }
  605. pr_info("batched loading '%s' custom fallback mechanism %u times\n",
  606. test_fw_config->name, test_fw_config->num_requests);
  607. send_uevent = test_fw_config->send_uevent ? FW_ACTION_HOTPLUG :
  608. FW_ACTION_NOHOTPLUG;
  609. for (i = 0; i < test_fw_config->num_requests; i++) {
  610. req = &test_fw_config->reqs[i];
  611. if (!req) {
  612. WARN_ON(1);
  613. goto out_bail;
  614. }
  615. req->name = test_fw_config->name;
  616. req->fw = NULL;
  617. req->idx = i;
  618. init_completion(&req->completion);
  619. rc = request_firmware_nowait(THIS_MODULE, send_uevent,
  620. req->name,
  621. dev, GFP_KERNEL, req,
  622. trigger_batched_cb);
  623. if (rc) {
  624. pr_info("#%u: batched async load failed setup: %d\n",
  625. i, rc);
  626. req->rc = rc;
  627. goto out_bail;
  628. } else
  629. req->sent = true;
  630. }
  631. rc = count;
  632. out_bail:
  633. /*
  634. * We require an explicit release to enable more time and delay of
  635. * calling release_firmware() to improve our chances of forcing a
  636. * batched request. If we instead called release_firmware() right away
  637. * then we might miss on an opportunity of having a successful firmware
  638. * request pass on the opportunity to be come a batched request.
  639. */
  640. for (i = 0; i < test_fw_config->num_requests; i++) {
  641. req = &test_fw_config->reqs[i];
  642. if (req->sent)
  643. wait_for_completion(&req->completion);
  644. }
  645. /* Override any worker error if we had a general setup error */
  646. if (rc < 0)
  647. test_fw_config->test_result = rc;
  648. out:
  649. mutex_unlock(&test_fw_mutex);
  650. return rc;
  651. }
  652. static DEVICE_ATTR_WO(trigger_batched_requests_async);
  653. static ssize_t test_result_show(struct device *dev,
  654. struct device_attribute *attr,
  655. char *buf)
  656. {
  657. return test_dev_config_show_int(buf, test_fw_config->test_result);
  658. }
  659. static DEVICE_ATTR_RO(test_result);
  660. static ssize_t release_all_firmware_store(struct device *dev,
  661. struct device_attribute *attr,
  662. const char *buf, size_t count)
  663. {
  664. test_release_all_firmware();
  665. return count;
  666. }
  667. static DEVICE_ATTR_WO(release_all_firmware);
  668. static ssize_t read_firmware_show(struct device *dev,
  669. struct device_attribute *attr,
  670. char *buf)
  671. {
  672. struct test_batched_req *req;
  673. u8 idx;
  674. ssize_t rc = 0;
  675. mutex_lock(&test_fw_mutex);
  676. idx = test_fw_config->read_fw_idx;
  677. if (idx >= test_fw_config->num_requests) {
  678. rc = -ERANGE;
  679. goto out;
  680. }
  681. if (!test_fw_config->reqs) {
  682. rc = -EINVAL;
  683. goto out;
  684. }
  685. req = &test_fw_config->reqs[idx];
  686. if (!req->fw) {
  687. pr_err("#%u: failed to async load firmware\n", idx);
  688. rc = -ENOENT;
  689. goto out;
  690. }
  691. pr_info("#%u: loaded %zu\n", idx, req->fw->size);
  692. if (req->fw->size > PAGE_SIZE) {
  693. pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
  694. rc = -EINVAL;
  695. goto out;
  696. }
  697. memcpy(buf, req->fw->data, req->fw->size);
  698. rc = req->fw->size;
  699. out:
  700. mutex_unlock(&test_fw_mutex);
  701. return rc;
  702. }
  703. static DEVICE_ATTR_RO(read_firmware);
  704. #define TEST_FW_DEV_ATTR(name) &dev_attr_##name.attr
  705. static struct attribute *test_dev_attrs[] = {
  706. TEST_FW_DEV_ATTR(reset),
  707. TEST_FW_DEV_ATTR(config),
  708. TEST_FW_DEV_ATTR(config_name),
  709. TEST_FW_DEV_ATTR(config_num_requests),
  710. TEST_FW_DEV_ATTR(config_sync_direct),
  711. TEST_FW_DEV_ATTR(config_send_uevent),
  712. TEST_FW_DEV_ATTR(config_read_fw_idx),
  713. /* These don't use the config at all - they could be ported! */
  714. TEST_FW_DEV_ATTR(trigger_request),
  715. TEST_FW_DEV_ATTR(trigger_async_request),
  716. TEST_FW_DEV_ATTR(trigger_custom_fallback),
  717. /* These use the config and can use the test_result */
  718. TEST_FW_DEV_ATTR(trigger_batched_requests),
  719. TEST_FW_DEV_ATTR(trigger_batched_requests_async),
  720. TEST_FW_DEV_ATTR(release_all_firmware),
  721. TEST_FW_DEV_ATTR(test_result),
  722. TEST_FW_DEV_ATTR(read_firmware),
  723. NULL,
  724. };
  725. ATTRIBUTE_GROUPS(test_dev);
  726. static struct miscdevice test_fw_misc_device = {
  727. .minor = MISC_DYNAMIC_MINOR,
  728. .name = "test_firmware",
  729. .fops = &test_fw_fops,
  730. .groups = test_dev_groups,
  731. };
  732. static int __init test_firmware_init(void)
  733. {
  734. int rc;
  735. test_fw_config = kzalloc(sizeof(struct test_config), GFP_KERNEL);
  736. if (!test_fw_config)
  737. return -ENOMEM;
  738. rc = __test_firmware_config_init();
  739. if (rc) {
  740. kfree(test_fw_config);
  741. pr_err("could not init firmware test config: %d\n", rc);
  742. return rc;
  743. }
  744. rc = misc_register(&test_fw_misc_device);
  745. if (rc) {
  746. kfree(test_fw_config);
  747. pr_err("could not register misc device: %d\n", rc);
  748. return rc;
  749. }
  750. pr_warn("interface ready\n");
  751. return 0;
  752. }
  753. module_init(test_firmware_init);
  754. static void __exit test_firmware_exit(void)
  755. {
  756. mutex_lock(&test_fw_mutex);
  757. release_firmware(test_firmware);
  758. misc_deregister(&test_fw_misc_device);
  759. __test_firmware_config_free();
  760. kfree(test_fw_config);
  761. mutex_unlock(&test_fw_mutex);
  762. pr_warn("removed interface\n");
  763. }
  764. module_exit(test_firmware_exit);
  765. MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
  766. MODULE_LICENSE("GPL");