linux/drivers/acpi/apei/einj.c
<<
>>
Prefs
   1/*
   2 * APEI Error INJection support
   3 *
   4 * EINJ provides a hardware error injection mechanism, this is useful
   5 * for debugging and testing of other APEI and RAS features.
   6 *
   7 * For more information about EINJ, please refer to ACPI Specification
   8 * version 4.0, section 17.5.
   9 *
  10 * Copyright 2009-2010 Intel Corp.
  11 *   Author: Huang Ying <ying.huang@intel.com>
  12 *
  13 * This program is free software; you can redistribute it and/or
  14 * modify it under the terms of the GNU General Public License version
  15 * 2 as published by the Free Software Foundation.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 */
  22
  23#include <linux/kernel.h>
  24#include <linux/module.h>
  25#include <linux/init.h>
  26#include <linux/io.h>
  27#include <linux/debugfs.h>
  28#include <linux/seq_file.h>
  29#include <linux/nmi.h>
  30#include <linux/delay.h>
  31#include <linux/mm.h>
  32#include <asm/unaligned.h>
  33
  34#include "apei-internal.h"
  35
  36#undef pr_fmt
  37#define pr_fmt(fmt) "EINJ: " fmt
  38
  39#define SPIN_UNIT               100                     /* 100ns */
  40/* Firmware should respond within 1 milliseconds */
  41#define FIRMWARE_TIMEOUT        (1 * NSEC_PER_MSEC)
  42#define ACPI5_VENDOR_BIT        BIT(31)
  43#define MEM_ERROR_MASK          (ACPI_EINJ_MEMORY_CORRECTABLE | \
  44                                ACPI_EINJ_MEMORY_UNCORRECTABLE | \
  45                                ACPI_EINJ_MEMORY_FATAL)
  46
  47/*
  48 * ACPI version 5 provides a SET_ERROR_TYPE_WITH_ADDRESS action.
  49 */
  50static int acpi5;
  51
  52struct set_error_type_with_address {
  53        u32     type;
  54        u32     vendor_extension;
  55        u32     flags;
  56        u32     apicid;
  57        u64     memory_address;
  58        u64     memory_address_range;
  59        u32     pcie_sbdf;
  60};
  61enum {
  62        SETWA_FLAGS_APICID = 1,
  63        SETWA_FLAGS_MEM = 2,
  64        SETWA_FLAGS_PCIE_SBDF = 4,
  65};
  66
  67/*
  68 * Vendor extensions for platform specific operations
  69 */
  70struct vendor_error_type_extension {
  71        u32     length;
  72        u32     pcie_sbdf;
  73        u16     vendor_id;
  74        u16     device_id;
  75        u8      rev_id;
  76        u8      reserved[3];
  77};
  78
  79static u32 notrigger;
  80
  81static u32 vendor_flags;
  82static struct debugfs_blob_wrapper vendor_blob;
  83static char vendor_dev[64];
  84
  85/*
  86 * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the
  87 * EINJ table through an unpublished extension. Use with caution as
  88 * most will ignore the parameter and make their own choice of address
  89 * for error injection.  This extension is used only if
  90 * param_extension module parameter is specified.
  91 */
  92struct einj_parameter {
  93        u64 type;
  94        u64 reserved1;
  95        u64 reserved2;
  96        u64 param1;
  97        u64 param2;
  98};
  99
 100#define EINJ_OP_BUSY                    0x1
 101#define EINJ_STATUS_SUCCESS             0x0
 102#define EINJ_STATUS_FAIL                0x1
 103#define EINJ_STATUS_INVAL               0x2
 104
 105#define EINJ_TAB_ENTRY(tab)                                             \
 106        ((struct acpi_whea_header *)((char *)(tab) +                    \
 107                                    sizeof(struct acpi_table_einj)))
 108
 109static bool param_extension;
 110module_param(param_extension, bool, 0);
 111
 112static struct acpi_table_einj *einj_tab;
 113
 114static struct apei_resources einj_resources;
 115
 116static struct apei_exec_ins_type einj_ins_type[] = {
 117        [ACPI_EINJ_READ_REGISTER] = {
 118                .flags = APEI_EXEC_INS_ACCESS_REGISTER,
 119                .run   = apei_exec_read_register,
 120        },
 121        [ACPI_EINJ_READ_REGISTER_VALUE] = {
 122                .flags = APEI_EXEC_INS_ACCESS_REGISTER,
 123                .run   = apei_exec_read_register_value,
 124        },
 125        [ACPI_EINJ_WRITE_REGISTER] = {
 126                .flags = APEI_EXEC_INS_ACCESS_REGISTER,
 127                .run   = apei_exec_write_register,
 128        },
 129        [ACPI_EINJ_WRITE_REGISTER_VALUE] = {
 130                .flags = APEI_EXEC_INS_ACCESS_REGISTER,
 131                .run   = apei_exec_write_register_value,
 132        },
 133        [ACPI_EINJ_NOOP] = {
 134                .flags = 0,
 135                .run   = apei_exec_noop,
 136        },
 137};
 138
 139/*
 140 * Prevent EINJ interpreter to run simultaneously, because the
 141 * corresponding firmware implementation may not work properly when
 142 * invoked simultaneously.
 143 */
 144static DEFINE_MUTEX(einj_mutex);
 145
 146static void *einj_param;
 147
 148static void einj_exec_ctx_init(struct apei_exec_context *ctx)
 149{
 150        apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
 151                           EINJ_TAB_ENTRY(einj_tab), einj_tab->entries);
 152}
 153
 154static int __einj_get_available_error_type(u32 *type)
 155{
 156        struct apei_exec_context ctx;
 157        int rc;
 158
 159        einj_exec_ctx_init(&ctx);
 160        rc = apei_exec_run(&ctx, ACPI_EINJ_GET_ERROR_TYPE);
 161        if (rc)
 162                return rc;
 163        *type = apei_exec_ctx_get_output(&ctx);
 164
 165        return 0;
 166}
 167
 168/* Get error injection capabilities of the platform */
 169static int einj_get_available_error_type(u32 *type)
 170{
 171        int rc;
 172
 173        mutex_lock(&einj_mutex);
 174        rc = __einj_get_available_error_type(type);
 175        mutex_unlock(&einj_mutex);
 176
 177        return rc;
 178}
 179
 180static int einj_timedout(u64 *t)
 181{
 182        if ((s64)*t < SPIN_UNIT) {
 183                pr_warning(FW_WARN "Firmware does not respond in time\n");
 184                return 1;
 185        }
 186        *t -= SPIN_UNIT;
 187        ndelay(SPIN_UNIT);
 188        touch_nmi_watchdog();
 189        return 0;
 190}
 191
 192static void check_vendor_extension(u64 paddr,
 193                                   struct set_error_type_with_address *v5param)
 194{
 195        int     offset = v5param->vendor_extension;
 196        struct  vendor_error_type_extension *v;
 197        u32     sbdf;
 198
 199        if (!offset)
 200                return;
 201        v = acpi_os_map_iomem(paddr + offset, sizeof(*v));
 202        if (!v)
 203                return;
 204        sbdf = v->pcie_sbdf;
 205        sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n",
 206                sbdf >> 24, (sbdf >> 16) & 0xff,
 207                (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
 208                 v->vendor_id, v->device_id, v->rev_id);
 209        acpi_os_unmap_iomem(v, sizeof(*v));
 210}
 211
 212static void *einj_get_parameter_address(void)
 213{
 214        int i;
 215        u64 pa_v4 = 0, pa_v5 = 0;
 216        struct acpi_whea_header *entry;
 217
 218        entry = EINJ_TAB_ENTRY(einj_tab);
 219        for (i = 0; i < einj_tab->entries; i++) {
 220                if (entry->action == ACPI_EINJ_SET_ERROR_TYPE &&
 221                    entry->instruction == ACPI_EINJ_WRITE_REGISTER &&
 222                    entry->register_region.space_id ==
 223                    ACPI_ADR_SPACE_SYSTEM_MEMORY)
 224                        pa_v4 = get_unaligned(&entry->register_region.address);
 225                if (entry->action == ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS &&
 226                    entry->instruction == ACPI_EINJ_WRITE_REGISTER &&
 227                    entry->register_region.space_id ==
 228                    ACPI_ADR_SPACE_SYSTEM_MEMORY)
 229                        pa_v5 = get_unaligned(&entry->register_region.address);
 230                entry++;
 231        }
 232        if (pa_v5) {
 233                struct set_error_type_with_address *v5param;
 234
 235                v5param = acpi_os_map_iomem(pa_v5, sizeof(*v5param));
 236                if (v5param) {
 237                        acpi5 = 1;
 238                        check_vendor_extension(pa_v5, v5param);
 239                        return v5param;
 240                }
 241        }
 242        if (param_extension && pa_v4) {
 243                struct einj_parameter *v4param;
 244
 245                v4param = acpi_os_map_iomem(pa_v4, sizeof(*v4param));
 246                if (!v4param)
 247                        return NULL;
 248                if (v4param->reserved1 || v4param->reserved2) {
 249                        acpi_os_unmap_iomem(v4param, sizeof(*v4param));
 250                        return NULL;
 251                }
 252                return v4param;
 253        }
 254
 255        return NULL;
 256}
 257
 258/* do sanity check to trigger table */
 259static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab)
 260{
 261        if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger))
 262                return -EINVAL;
 263        if (trigger_tab->table_size > PAGE_SIZE ||
 264            trigger_tab->table_size < trigger_tab->header_size)
 265                return -EINVAL;
 266        if (trigger_tab->entry_count !=
 267            (trigger_tab->table_size - trigger_tab->header_size) /
 268            sizeof(struct acpi_einj_entry))
 269                return -EINVAL;
 270
 271        return 0;
 272}
 273
 274static struct acpi_generic_address *einj_get_trigger_parameter_region(
 275        struct acpi_einj_trigger *trigger_tab, u64 param1, u64 param2)
 276{
 277        int i;
 278        struct acpi_whea_header *entry;
 279
 280        entry = (struct acpi_whea_header *)
 281                ((char *)trigger_tab + sizeof(struct acpi_einj_trigger));
 282        for (i = 0; i < trigger_tab->entry_count; i++) {
 283                if (entry->action == ACPI_EINJ_TRIGGER_ERROR &&
 284                entry->instruction == ACPI_EINJ_WRITE_REGISTER_VALUE &&
 285                entry->register_region.space_id ==
 286                        ACPI_ADR_SPACE_SYSTEM_MEMORY &&
 287                (entry->register_region.address & param2) == (param1 & param2))
 288                        return &entry->register_region;
 289                entry++;
 290        }
 291
 292        return NULL;
 293}
 294/* Execute instructions in trigger error action table */
 295static int __einj_error_trigger(u64 trigger_paddr, u32 type,
 296                                u64 param1, u64 param2)
 297{
 298        struct acpi_einj_trigger *trigger_tab = NULL;
 299        struct apei_exec_context trigger_ctx;
 300        struct apei_resources trigger_resources;
 301        struct acpi_whea_header *trigger_entry;
 302        struct resource *r;
 303        u32 table_size;
 304        int rc = -EIO;
 305        struct acpi_generic_address *trigger_param_region = NULL;
 306
 307        r = request_mem_region(trigger_paddr, sizeof(*trigger_tab),
 308                               "APEI EINJ Trigger Table");
 309        if (!r) {
 310                pr_err("Can not request [mem %#010llx-%#010llx] for Trigger table\n",
 311                       (unsigned long long)trigger_paddr,
 312                       (unsigned long long)trigger_paddr +
 313                            sizeof(*trigger_tab) - 1);
 314                goto out;
 315        }
 316        trigger_tab = ioremap_cache(trigger_paddr, sizeof(*trigger_tab));
 317        if (!trigger_tab) {
 318                pr_err("Failed to map trigger table!\n");
 319                goto out_rel_header;
 320        }
 321        rc = einj_check_trigger_header(trigger_tab);
 322        if (rc) {
 323                pr_warning(FW_BUG "Invalid trigger error action table.\n");
 324                goto out_rel_header;
 325        }
 326
 327        /* No action structures in the TRIGGER_ERROR table, nothing to do */
 328        if (!trigger_tab->entry_count)
 329                goto out_rel_header;
 330
 331        rc = -EIO;
 332        table_size = trigger_tab->table_size;
 333        r = request_mem_region(trigger_paddr + sizeof(*trigger_tab),
 334                               table_size - sizeof(*trigger_tab),
 335                               "APEI EINJ Trigger Table");
 336        if (!r) {
 337                pr_err("Can not request [mem %#010llx-%#010llx] for Trigger Table Entry\n",
 338                       (unsigned long long)trigger_paddr + sizeof(*trigger_tab),
 339                       (unsigned long long)trigger_paddr + table_size - 1);
 340                goto out_rel_header;
 341        }
 342        iounmap(trigger_tab);
 343        trigger_tab = ioremap_cache(trigger_paddr, table_size);
 344        if (!trigger_tab) {
 345                pr_err("Failed to map trigger table!\n");
 346                goto out_rel_entry;
 347        }
 348        trigger_entry = (struct acpi_whea_header *)
 349                ((char *)trigger_tab + sizeof(struct acpi_einj_trigger));
 350        apei_resources_init(&trigger_resources);
 351        apei_exec_ctx_init(&trigger_ctx, einj_ins_type,
 352                           ARRAY_SIZE(einj_ins_type),
 353                           trigger_entry, trigger_tab->entry_count);
 354        rc = apei_exec_collect_resources(&trigger_ctx, &trigger_resources);
 355        if (rc)
 356                goto out_fini;
 357        rc = apei_resources_sub(&trigger_resources, &einj_resources);
 358        if (rc)
 359                goto out_fini;
 360        /*
 361         * Some firmware will access target address specified in
 362         * param1 to trigger the error when injecting memory error.
 363         * This will cause resource conflict with regular memory.  So
 364         * remove it from trigger table resources.
 365         */
 366        if ((param_extension || acpi5) && (type & MEM_ERROR_MASK) && param2) {
 367                struct apei_resources addr_resources;
 368                apei_resources_init(&addr_resources);
 369                trigger_param_region = einj_get_trigger_parameter_region(
 370                        trigger_tab, param1, param2);
 371                if (trigger_param_region) {
 372                        rc = apei_resources_add(&addr_resources,
 373                                trigger_param_region->address,
 374                                trigger_param_region->bit_width/8, true);
 375                        if (rc)
 376                                goto out_fini;
 377                        rc = apei_resources_sub(&trigger_resources,
 378                                        &addr_resources);
 379                }
 380                apei_resources_fini(&addr_resources);
 381                if (rc)
 382                        goto out_fini;
 383        }
 384        rc = apei_resources_request(&trigger_resources, "APEI EINJ Trigger");
 385        if (rc)
 386                goto out_fini;
 387        rc = apei_exec_pre_map_gars(&trigger_ctx);
 388        if (rc)
 389                goto out_release;
 390
 391        rc = apei_exec_run(&trigger_ctx, ACPI_EINJ_TRIGGER_ERROR);
 392
 393        apei_exec_post_unmap_gars(&trigger_ctx);
 394out_release:
 395        apei_resources_release(&trigger_resources);
 396out_fini:
 397        apei_resources_fini(&trigger_resources);
 398out_rel_entry:
 399        release_mem_region(trigger_paddr + sizeof(*trigger_tab),
 400                           table_size - sizeof(*trigger_tab));
 401out_rel_header:
 402        release_mem_region(trigger_paddr, sizeof(*trigger_tab));
 403out:
 404        if (trigger_tab)
 405                iounmap(trigger_tab);
 406
 407        return rc;
 408}
 409
 410static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
 411                               u64 param3, u64 param4)
 412{
 413        struct apei_exec_context ctx;
 414        u64 val, trigger_paddr, timeout = FIRMWARE_TIMEOUT;
 415        int rc;
 416
 417        einj_exec_ctx_init(&ctx);
 418
 419        rc = apei_exec_run_optional(&ctx, ACPI_EINJ_BEGIN_OPERATION);
 420        if (rc)
 421                return rc;
 422        apei_exec_ctx_set_input(&ctx, type);
 423        if (acpi5) {
 424                struct set_error_type_with_address *v5param = einj_param;
 425
 426                v5param->type = type;
 427                if (type & ACPI5_VENDOR_BIT) {
 428                        switch (vendor_flags) {
 429                        case SETWA_FLAGS_APICID:
 430                                v5param->apicid = param1;
 431                                break;
 432                        case SETWA_FLAGS_MEM:
 433                                v5param->memory_address = param1;
 434                                v5param->memory_address_range = param2;
 435                                break;
 436                        case SETWA_FLAGS_PCIE_SBDF:
 437                                v5param->pcie_sbdf = param1;
 438                                break;
 439                        }
 440                        v5param->flags = vendor_flags;
 441                } else if (flags) {
 442                                v5param->flags = flags;
 443                                v5param->memory_address = param1;
 444                                v5param->memory_address_range = param2;
 445                                v5param->apicid = param3;
 446                                v5param->pcie_sbdf = param4;
 447                } else {
 448                        switch (type) {
 449                        case ACPI_EINJ_PROCESSOR_CORRECTABLE:
 450                        case ACPI_EINJ_PROCESSOR_UNCORRECTABLE:
 451                        case ACPI_EINJ_PROCESSOR_FATAL:
 452                                v5param->apicid = param1;
 453                                v5param->flags = SETWA_FLAGS_APICID;
 454                                break;
 455                        case ACPI_EINJ_MEMORY_CORRECTABLE:
 456                        case ACPI_EINJ_MEMORY_UNCORRECTABLE:
 457                        case ACPI_EINJ_MEMORY_FATAL:
 458                                v5param->memory_address = param1;
 459                                v5param->memory_address_range = param2;
 460                                v5param->flags = SETWA_FLAGS_MEM;
 461                                break;
 462                        case ACPI_EINJ_PCIX_CORRECTABLE:
 463                        case ACPI_EINJ_PCIX_UNCORRECTABLE:
 464                        case ACPI_EINJ_PCIX_FATAL:
 465                                v5param->pcie_sbdf = param1;
 466                                v5param->flags = SETWA_FLAGS_PCIE_SBDF;
 467                                break;
 468                        }
 469                }
 470        } else {
 471                rc = apei_exec_run(&ctx, ACPI_EINJ_SET_ERROR_TYPE);
 472                if (rc)
 473                        return rc;
 474                if (einj_param) {
 475                        struct einj_parameter *v4param = einj_param;
 476                        v4param->param1 = param1;
 477                        v4param->param2 = param2;
 478                }
 479        }
 480        rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION);
 481        if (rc)
 482                return rc;
 483        for (;;) {
 484                rc = apei_exec_run(&ctx, ACPI_EINJ_CHECK_BUSY_STATUS);
 485                if (rc)
 486                        return rc;
 487                val = apei_exec_ctx_get_output(&ctx);
 488                if (!(val & EINJ_OP_BUSY))
 489                        break;
 490                if (einj_timedout(&timeout))
 491                        return -EIO;
 492        }
 493        rc = apei_exec_run(&ctx, ACPI_EINJ_GET_COMMAND_STATUS);
 494        if (rc)
 495                return rc;
 496        val = apei_exec_ctx_get_output(&ctx);
 497        if (val != EINJ_STATUS_SUCCESS)
 498                return -EBUSY;
 499
 500        rc = apei_exec_run(&ctx, ACPI_EINJ_GET_TRIGGER_TABLE);
 501        if (rc)
 502                return rc;
 503        trigger_paddr = apei_exec_ctx_get_output(&ctx);
 504        if (notrigger == 0) {
 505                rc = __einj_error_trigger(trigger_paddr, type, param1, param2);
 506                if (rc)
 507                        return rc;
 508        }
 509        rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION);
 510
 511        return rc;
 512}
 513
 514/* Inject the specified hardware error */
 515static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
 516                             u64 param3, u64 param4)
 517{
 518        int rc;
 519        u64 base_addr, size;
 520
 521        /* If user manually set "flags", make sure it is legal */
 522        if (flags && (flags &
 523                ~(SETWA_FLAGS_APICID|SETWA_FLAGS_MEM|SETWA_FLAGS_PCIE_SBDF)))
 524                return -EINVAL;
 525
 526        /*
 527         * We need extra sanity checks for memory errors.
 528         * Other types leap directly to injection.
 529         */
 530
 531        /* ensure param1/param2 existed */
 532        if (!(param_extension || acpi5))
 533                goto inject;
 534
 535        /* ensure injection is memory related */
 536        if (type & ACPI5_VENDOR_BIT) {
 537                if (vendor_flags != SETWA_FLAGS_MEM)
 538                        goto inject;
 539        } else if (!(type & MEM_ERROR_MASK) && !(flags & SETWA_FLAGS_MEM))
 540                goto inject;
 541
 542        /*
 543         * Disallow crazy address masks that give BIOS leeway to pick
 544         * injection address almost anywhere. Insist on page or
 545         * better granularity and that target address is normal RAM or
 546         * NVDIMM.
 547         */
 548        base_addr = param1 & param2;
 549        size = ~param2 + 1;
 550
 551        if (((param2 & PAGE_MASK) != PAGE_MASK) ||
 552            ((region_intersects(base_addr, size, IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)
 553                                != REGION_INTERSECTS) &&
 554             (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY)
 555                                != REGION_INTERSECTS)))
 556                return -EINVAL;
 557
 558inject:
 559        mutex_lock(&einj_mutex);
 560        rc = __einj_error_inject(type, flags, param1, param2, param3, param4);
 561        mutex_unlock(&einj_mutex);
 562
 563        return rc;
 564}
 565
 566static u32 error_type;
 567static u32 error_flags;
 568static u64 error_param1;
 569static u64 error_param2;
 570static u64 error_param3;
 571static u64 error_param4;
 572static struct dentry *einj_debug_dir;
 573
 574static int available_error_type_show(struct seq_file *m, void *v)
 575{
 576        int rc;
 577        u32 available_error_type = 0;
 578
 579        rc = einj_get_available_error_type(&available_error_type);
 580        if (rc)
 581                return rc;
 582        if (available_error_type & 0x0001)
 583                seq_printf(m, "0x00000001\tProcessor Correctable\n");
 584        if (available_error_type & 0x0002)
 585                seq_printf(m, "0x00000002\tProcessor Uncorrectable non-fatal\n");
 586        if (available_error_type & 0x0004)
 587                seq_printf(m, "0x00000004\tProcessor Uncorrectable fatal\n");
 588        if (available_error_type & 0x0008)
 589                seq_printf(m, "0x00000008\tMemory Correctable\n");
 590        if (available_error_type & 0x0010)
 591                seq_printf(m, "0x00000010\tMemory Uncorrectable non-fatal\n");
 592        if (available_error_type & 0x0020)
 593                seq_printf(m, "0x00000020\tMemory Uncorrectable fatal\n");
 594        if (available_error_type & 0x0040)
 595                seq_printf(m, "0x00000040\tPCI Express Correctable\n");
 596        if (available_error_type & 0x0080)
 597                seq_printf(m, "0x00000080\tPCI Express Uncorrectable non-fatal\n");
 598        if (available_error_type & 0x0100)
 599                seq_printf(m, "0x00000100\tPCI Express Uncorrectable fatal\n");
 600        if (available_error_type & 0x0200)
 601                seq_printf(m, "0x00000200\tPlatform Correctable\n");
 602        if (available_error_type & 0x0400)
 603                seq_printf(m, "0x00000400\tPlatform Uncorrectable non-fatal\n");
 604        if (available_error_type & 0x0800)
 605                seq_printf(m, "0x00000800\tPlatform Uncorrectable fatal\n");
 606
 607        return 0;
 608}
 609
 610static int available_error_type_open(struct inode *inode, struct file *file)
 611{
 612        return single_open(file, available_error_type_show, NULL);
 613}
 614
 615static const struct file_operations available_error_type_fops = {
 616        .open           = available_error_type_open,
 617        .read           = seq_read,
 618        .llseek         = seq_lseek,
 619        .release        = single_release,
 620};
 621
 622static int error_type_get(void *data, u64 *val)
 623{
 624        *val = error_type;
 625
 626        return 0;
 627}
 628
 629static int error_type_set(void *data, u64 val)
 630{
 631        int rc;
 632        u32 available_error_type = 0;
 633        u32 tval, vendor;
 634
 635        /*
 636         * Vendor defined types have 0x80000000 bit set, and
 637         * are not enumerated by ACPI_EINJ_GET_ERROR_TYPE
 638         */
 639        vendor = val & ACPI5_VENDOR_BIT;
 640        tval = val & 0x7fffffff;
 641
 642        /* Only one error type can be specified */
 643        if (tval & (tval - 1))
 644                return -EINVAL;
 645        if (!vendor) {
 646                rc = einj_get_available_error_type(&available_error_type);
 647                if (rc)
 648                        return rc;
 649                if (!(val & available_error_type))
 650                        return -EINVAL;
 651        }
 652        error_type = val;
 653
 654        return 0;
 655}
 656
 657DEFINE_SIMPLE_ATTRIBUTE(error_type_fops, error_type_get,
 658                        error_type_set, "0x%llx\n");
 659
 660static int error_inject_set(void *data, u64 val)
 661{
 662        if (!error_type)
 663                return -EINVAL;
 664
 665        return einj_error_inject(error_type, error_flags, error_param1, error_param2,
 666                error_param3, error_param4);
 667}
 668
 669DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL,
 670                        error_inject_set, "%llu\n");
 671
 672static int einj_check_table(struct acpi_table_einj *einj_tab)
 673{
 674        if ((einj_tab->header_length !=
 675             (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header)))
 676            && (einj_tab->header_length != sizeof(struct acpi_table_einj)))
 677                return -EINVAL;
 678        if (einj_tab->header.length < sizeof(struct acpi_table_einj))
 679                return -EINVAL;
 680        if (einj_tab->entries !=
 681            (einj_tab->header.length - sizeof(struct acpi_table_einj)) /
 682            sizeof(struct acpi_einj_entry))
 683                return -EINVAL;
 684
 685        return 0;
 686}
 687
 688static int __init einj_init(void)
 689{
 690        int rc;
 691        acpi_status status;
 692        struct dentry *fentry;
 693        struct apei_exec_context ctx;
 694
 695        if (acpi_disabled) {
 696                pr_warn("ACPI disabled.\n");
 697                return -ENODEV;
 698        }
 699
 700        status = acpi_get_table(ACPI_SIG_EINJ, 0,
 701                                (struct acpi_table_header **)&einj_tab);
 702        if (status == AE_NOT_FOUND) {
 703                pr_warn("EINJ table not found.\n");
 704                return -ENODEV;
 705        }
 706        else if (ACPI_FAILURE(status)) {
 707                pr_err("Failed to get EINJ table: %s\n",
 708                                acpi_format_exception(status));
 709                return -EINVAL;
 710        }
 711
 712        rc = einj_check_table(einj_tab);
 713        if (rc) {
 714                pr_warn(FW_BUG "Invalid EINJ table.n");
 715                return -EINVAL;
 716        }
 717
 718        rc = -ENOMEM;
 719        einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir());
 720        if (!einj_debug_dir) {
 721                pr_err("Error creating debugfs node.\n");
 722                goto err_cleanup;
 723        }
 724
 725        fentry = debugfs_create_file("available_error_type", S_IRUSR,
 726                                     einj_debug_dir, NULL,
 727                                     &available_error_type_fops);
 728        if (!fentry)
 729                goto err_cleanup;
 730
 731        fentry = debugfs_create_file("error_type", S_IRUSR | S_IWUSR,
 732                                     einj_debug_dir, NULL, &error_type_fops);
 733        if (!fentry)
 734                goto err_cleanup;
 735        fentry = debugfs_create_file("error_inject", S_IWUSR,
 736                                     einj_debug_dir, NULL, &error_inject_fops);
 737        if (!fentry)
 738                goto err_cleanup;
 739
 740        apei_resources_init(&einj_resources);
 741        einj_exec_ctx_init(&ctx);
 742        rc = apei_exec_collect_resources(&ctx, &einj_resources);
 743        if (rc) {
 744                pr_err("Error collecting EINJ resources.\n");
 745                goto err_fini;
 746        }
 747
 748        rc = apei_resources_request(&einj_resources, "APEI EINJ");
 749        if (rc) {
 750                pr_err("Error requesting memory/port resources.\n");
 751                goto err_fini;
 752        }
 753
 754        rc = apei_exec_pre_map_gars(&ctx);
 755        if (rc) {
 756                pr_err("Error pre-mapping GARs.\n");
 757                goto err_release;
 758        }
 759
 760        rc = -ENOMEM;
 761        einj_param = einj_get_parameter_address();
 762        if ((param_extension || acpi5) && einj_param) {
 763                fentry = debugfs_create_x32("flags", S_IRUSR | S_IWUSR,
 764                                            einj_debug_dir, &error_flags);
 765                if (!fentry)
 766                        goto err_unmap;
 767                fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR,
 768                                            einj_debug_dir, &error_param1);
 769                if (!fentry)
 770                        goto err_unmap;
 771                fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR,
 772                                            einj_debug_dir, &error_param2);
 773                if (!fentry)
 774                        goto err_unmap;
 775                fentry = debugfs_create_x64("param3", S_IRUSR | S_IWUSR,
 776                                            einj_debug_dir, &error_param3);
 777                if (!fentry)
 778                        goto err_unmap;
 779                fentry = debugfs_create_x64("param4", S_IRUSR | S_IWUSR,
 780                                            einj_debug_dir, &error_param4);
 781                if (!fentry)
 782                        goto err_unmap;
 783
 784                fentry = debugfs_create_x32("notrigger", S_IRUSR | S_IWUSR,
 785                                            einj_debug_dir, &notrigger);
 786                if (!fentry)
 787                        goto err_unmap;
 788        }
 789
 790        if (vendor_dev[0]) {
 791                vendor_blob.data = vendor_dev;
 792                vendor_blob.size = strlen(vendor_dev);
 793                fentry = debugfs_create_blob("vendor", S_IRUSR,
 794                                             einj_debug_dir, &vendor_blob);
 795                if (!fentry)
 796                        goto err_unmap;
 797                fentry = debugfs_create_x32("vendor_flags", S_IRUSR | S_IWUSR,
 798                                            einj_debug_dir, &vendor_flags);
 799                if (!fentry)
 800                        goto err_unmap;
 801        }
 802
 803        pr_info("Error INJection is initialized.\n");
 804
 805        return 0;
 806
 807err_unmap:
 808        if (einj_param) {
 809                acpi_size size = (acpi5) ?
 810                        sizeof(struct set_error_type_with_address) :
 811                        sizeof(struct einj_parameter);
 812
 813                acpi_os_unmap_iomem(einj_param, size);
 814                pr_err("Error creating param extension debugfs nodes.\n");
 815        }
 816        apei_exec_post_unmap_gars(&ctx);
 817err_release:
 818        apei_resources_release(&einj_resources);
 819err_fini:
 820        apei_resources_fini(&einj_resources);
 821err_cleanup:
 822        pr_err("Error creating primary debugfs nodes.\n");
 823        debugfs_remove_recursive(einj_debug_dir);
 824
 825        return rc;
 826}
 827
 828static void __exit einj_exit(void)
 829{
 830        struct apei_exec_context ctx;
 831
 832        if (einj_param) {
 833                acpi_size size = (acpi5) ?
 834                        sizeof(struct set_error_type_with_address) :
 835                        sizeof(struct einj_parameter);
 836
 837                acpi_os_unmap_iomem(einj_param, size);
 838        }
 839        einj_exec_ctx_init(&ctx);
 840        apei_exec_post_unmap_gars(&ctx);
 841        apei_resources_release(&einj_resources);
 842        apei_resources_fini(&einj_resources);
 843        debugfs_remove_recursive(einj_debug_dir);
 844}
 845
 846module_init(einj_init);
 847module_exit(einj_exit);
 848
 849MODULE_AUTHOR("Huang Ying");
 850MODULE_DESCRIPTION("APEI Error INJection support");
 851MODULE_LICENSE("GPL");
 852