int hmp_pcie_aer_inject_error(Monitor *mon,

                             const QDict *qdict, QObject **ret_data)

{

    const char *id = qdict_get_str(qdict, "id");

    const char *error_name;

    uint32_t error_status;

    bool correctable;

    PCIDevice *dev;

    PCIEAERErr err;

    int ret;



    ret = pci_qdev_find_device(id, &dev);

    if (ret < 0) {

        monitor_printf(mon,

                       "id or pci device path is invalid or device not "

                       "found. %s\n", id);

        return ret;

    }

    if (!pci_is_express(dev)) {

        monitor_printf(mon, "the device doesn't support pci express. %s\n",

                       id);

        return -ENOSYS;

    }



    error_name = qdict_get_str(qdict, "error_status");

    if (pcie_aer_parse_error_string(error_name, &error_status, &correctable)) {

        char *e = NULL;

        error_status = strtoul(error_name, &e, 0);

        correctable = qdict_get_try_bool(qdict, "correctable", 0);

        if (!e || *e != '\0') {

            monitor_printf(mon, "invalid error status value. \"%s\"",

                           error_name);

            return -EINVAL;

        }

    }

    err.status = error_status;

    err.source_id = (pci_bus_num(dev->bus) << 8) | dev->devfn;



    err.flags = 0;

    if (correctable) {

        err.flags |= PCIE_AER_ERR_IS_CORRECTABLE;

    }

    if (qdict_get_try_bool(qdict, "advisory_non_fatal", 0)) {

        err.flags |= PCIE_AER_ERR_MAYBE_ADVISORY;

    }

    if (qdict_haskey(qdict, "header0")) {

        err.flags |= PCIE_AER_ERR_HEADER_VALID;

    }

    if (qdict_haskey(qdict, "prefix0")) {

        err.flags |= PCIE_AER_ERR_TLP_PREFIX_PRESENT;

    }



    err.header[0] = qdict_get_try_int(qdict, "header0", 0);

    err.header[1] = qdict_get_try_int(qdict, "header1", 0);

    err.header[2] = qdict_get_try_int(qdict, "header2", 0);

    err.header[3] = qdict_get_try_int(qdict, "header3", 0);



    err.prefix[0] = qdict_get_try_int(qdict, "prefix0", 0);

    err.prefix[1] = qdict_get_try_int(qdict, "prefix1", 0);

    err.prefix[2] = qdict_get_try_int(qdict, "prefix2", 0);

    err.prefix[3] = qdict_get_try_int(qdict, "prefix3", 0);



    ret = pcie_aer_inject_error(dev, &err);

    *ret_data = qobject_from_jsonf("{'id': %s, "

                                   "'root_bus': %s, 'bus': %d, 'devfn': %d, "

                                   "'ret': %d}",

                                   id, pci_root_bus_path(dev),

                                   pci_bus_num(dev->bus), dev->devfn,

                                   ret);

    assert(*ret_data);



    return 0;

}
