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