Commit 15763776 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging



pci, pc, virtio: fixes, features

VTD fixes
IR and split irqchip are now the default for Q35
ACPI refactoring
hotplug refactoring
new names for virtio devices
multiple pcie link width/speeds
PCI fixes

Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Thu 20 Dec 2018 18:26:03 GMT
# gpg:                using RSA key 281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream: (44 commits)
  x86-iommu: turn on IR by default if proper
  x86-iommu: switch intr_supported to OnOffAuto type
  q35: set split kernel irqchip as default
  pci: Adjust PCI config limit based on bus topology
  spapr_pci: perform unplug via the hotplug handler
  pci/shpc: perform unplug via the hotplug handler
  pci: Reuse pci-bridge hotplug handler handlers for pcie-pci-bridge
  pci/pcie: perform unplug via the hotplug handler
  pci/pcihp: perform unplug via the hotplug handler
  pci/pcihp: overwrite hotplug handler recursively from the start
  pci/pcihp: perform check for bus capability in pre_plug handler
  s390x/pci: rename hotplug handler callbacks
  pci/shpc: rename hotplug handler callbacks
  pci/pcie: rename hotplug handler callbacks
  hw/i386: Remove deprecated machines pc-0.10 and pc-0.11
  hw: acpi: Remove AcpiRsdpDescriptor and fix tests
  hw: acpi: Export and share the ARM RSDP build
  hw: arm: Support both legacy and current RSDP build
  hw: arm: Convert the RSDP build to the buid_append_foo() API
  hw: arm: Carry RSDP specific data through AcpiRsdpData
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 41e2c56e 47748bbb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1262,7 +1262,7 @@ M: Michael S. Tsirkin <mst@redhat.com>
M: Igor Mammedov <imammedo@redhat.com>
S: Supported
F: include/hw/acpi/*
F: include/hw/smbios/*
F: include/hw/firmware/smbios.h
F: hw/mem/*
F: hw/acpi/*
F: hw/smbios/*
+68 −0
Original line number Diff line number Diff line
@@ -1589,6 +1589,74 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
    g_array_free(tables->vmgenid, mfre);
}

/*
 * ACPI spec 5.2.5.3 Root System Description Pointer (RSDP).
 * (Revision 1.0 or later)
 */
void
build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data)
{
    int tbl_off = tbl->len; /* Table offset in the RSDP file */

    switch (rsdp_data->revision) {
    case 0:
        /* With ACPI 1.0, we must have an RSDT pointer */
        g_assert(rsdp_data->rsdt_tbl_offset);
        break;
    case 2:
        /* With ACPI 2.0+, we must have an XSDT pointer */
        g_assert(rsdp_data->xsdt_tbl_offset);
        break;
    default:
        /* Only revisions 0 (ACPI 1.0) and 2 (ACPI 2.0+) are valid for RSDP */
        g_assert_not_reached();
    }

    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, tbl, 16,
                             true /* fseg memory */);

    g_array_append_vals(tbl, "RSD PTR ", 8); /* Signature */
    build_append_int_noprefix(tbl, 0, 1); /* Checksum */
    g_array_append_vals(tbl, rsdp_data->oem_id, 6); /* OEMID */
    build_append_int_noprefix(tbl, rsdp_data->revision, 1); /* Revision */
    build_append_int_noprefix(tbl, 0, 4); /* RsdtAddress */
    if (rsdp_data->rsdt_tbl_offset) {
        /* RSDT address to be filled by guest linker */
        bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
                                       tbl_off + 16, 4,
                                       ACPI_BUILD_TABLE_FILE,
                                       *rsdp_data->rsdt_tbl_offset);
    }

    /* Checksum to be filled by guest linker */
    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
                                    tbl_off, 20, /* ACPI rev 1.0 RSDP size */
                                    8);

    if (rsdp_data->revision == 0) {
        /* ACPI 1.0 RSDP, we're done */
        return;
    }

    build_append_int_noprefix(tbl, 36, 4); /* Length */

    /* XSDT address to be filled by guest linker */
    build_append_int_noprefix(tbl, 0, 8); /* XsdtAddress */
    /* We already validated our xsdt pointer */
    bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
                                   tbl_off + 24, 8,
                                   ACPI_BUILD_TABLE_FILE,
                                   *rsdp_data->xsdt_tbl_offset);

    build_append_int_noprefix(tbl, 0, 1); /* Extended Checksum */
    build_append_int_noprefix(tbl, 0, 3); /* Reserved */

    /* Extended checksum to be filled by Guest linker */
    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
                                    tbl_off, 36, /* ACPI rev 2.0 RSDP size */
                                    32);
}

/* Build rsdt table */
void
build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
+40 −7
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_bridge.h"
#include "hw/acpi/acpi.h"
#include "sysemu/sysemu.h"
#include "exec/address-spaces.h"
@@ -153,6 +154,7 @@ static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev)

static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots)
{
    HotplugHandler *hotplug_ctrl;
    BusChild *kid, *next;
    int slot = ctz32(slots);
    PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
@@ -170,7 +172,8 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo
        PCIDevice *dev = PCI_DEVICE(qdev);
        if (PCI_SLOT(dev->devfn) == slot) {
            if (!acpi_pcihp_pc_no_hotplug(s, dev)) {
                object_unparent(OBJECT(qdev));
                hotplug_ctrl = qdev_get_hotplug_handler(qdev);
                hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort);
            }
        }
    }
@@ -217,31 +220,61 @@ void acpi_pcihp_reset(AcpiPciHpState *s)
    acpi_pcihp_update(s);
}

void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
                                   DeviceState *dev, Error **errp)
{
    PCIDevice *pdev = PCI_DEVICE(dev);
    int slot = PCI_SLOT(pdev->devfn);
    int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
    if (bsel < 0) {
    /* Only hotplugged devices need the hotplug capability. */
    if (dev->hotplugged &&
        acpi_pcihp_get_bsel(pci_get_bus(PCI_DEVICE(dev))) < 0) {
        error_setg(errp, "Unsupported bus. Bus doesn't have property '"
                   ACPI_PCIHP_PROP_BSEL "' set");
        return;
    }
}

void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
                               DeviceState *dev, Error **errp)
{
    PCIDevice *pdev = PCI_DEVICE(dev);
    int slot = PCI_SLOT(pdev->devfn);
    int bsel;

    /* Don't send event when device is enabled during qemu machine creation:
     * it is present on boot, no hotplug event is necessary. We do send an
     * event when the device is disabled later. */
    if (!dev->hotplugged) {
        /*
         * Overwrite the default hotplug handler with the ACPI PCI one
         * for cold plugged bridges only.
         */
        if (!s->legacy_piix &&
            object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
            PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));

            qbus_set_hotplug_handler(BUS(sec), DEVICE(hotplug_dev),
                                     &error_abort);
            /* We don't have to overwrite any other hotplug handler yet */
            assert(QLIST_EMPTY(&sec->child));
        }

        return;
    }

    bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
    g_assert(bsel >= 0);
    s->acpi_pcihp_pci_status[bsel].up |= (1U << slot);
    acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
}

void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
                                 DeviceState *dev, Error **errp)
{
    object_unparent(OBJECT(dev));
}

void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
                                         AcpiPciHpState *s, DeviceState *dev,
                                         Error **errp)
{
    PCIDevice *pdev = PCI_DEVICE(dev);
    int slot = PCI_SLOT(pdev->devfn);
+21 −19
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ static int vmstate_acpi_post_load(void *opaque, int version_id)
    PIIX4PMState *s = opaque;

    pm_io_space_update(s);
    smbus_io_space_update(s);
    return 0;
}

@@ -370,6 +371,18 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque)
    acpi_pm1_evt_power_down(&s->ar);
}

static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev,
                                    DeviceState *dev, Error **errp)
{
    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
        acpi_pcihp_device_pre_plug_cb(hotplug_dev, dev, errp);
    } else if (!object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
               !object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
        error_setg(errp, "acpi: device pre plug request for not supported"
                   " device type: %s", object_get_typename(OBJECT(dev)));
    }
}

static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
                                 DeviceState *dev, Error **errp)
{
@@ -392,8 +405,7 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
            acpi_cpu_plug_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
        }
    } else {
        error_setg(errp, "acpi: device plug request for not supported device"
                   " type: %s", object_get_typename(OBJECT(dev)));
        g_assert_not_reached();
    }
}

@@ -407,8 +419,8 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
        acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug,
                                      dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
        acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
                                    errp);
        acpi_pcihp_device_unplug_request_cb(hotplug_dev, &s->acpi_pci_hotplug,
                                            dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
               !s->cpu_hotplug_legacy) {
        acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
@@ -426,6 +438,9 @@ static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev,
    if (s->acpi_memory_hotplug.is_enabled &&
        object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
        acpi_memory_unplug_cb(&s->acpi_memory_hotplug, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
        acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
                                    errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
               !s->cpu_hotplug_legacy) {
        acpi_cpu_unplug_cb(&s->cpuhp_state, dev, errp);
@@ -435,15 +450,6 @@ static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev,
    }
}

static void piix4_update_bus_hotplug(PCIBus *pci_bus, void *opaque)
{
    PIIX4PMState *s = opaque;

    /* pci_bus cannot outlive PIIX4PMState, because /machine keeps it alive
     * and it's not hot-unpluggable */
    qbus_set_hotplug_handler(BUS(pci_bus), DEVICE(s), &error_abort);
}

static void piix4_pm_machine_ready(Notifier *n, void *opaque)
{
    PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready);
@@ -457,12 +463,6 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque)
    pci_conf[0x63] = 0x60;
    pci_conf[0x67] = (memory_region_present(io_as, 0x3f8) ? 0x08 : 0) |
        (memory_region_present(io_as, 0x2f8) ? 0x90 : 0);

    if (s->use_acpi_pci_hotplug) {
        pci_for_each_bus(pci_get_bus(d), piix4_update_bus_hotplug, s);
    } else {
        piix4_update_bus_hotplug(pci_get_bus(d), s);
    }
}

static void piix4_pm_add_propeties(PIIX4PMState *s)
@@ -536,6 +536,7 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)

    piix4_acpi_system_hot_add_init(pci_address_space_io(dev),
                                   pci_get_bus(dev), s);
    qbus_set_hotplug_handler(BUS(pci_get_bus(dev)), DEVICE(s), &error_abort);

    piix4_pm_add_propeties(s);
}
@@ -702,6 +703,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
     */
    dc->user_creatable = false;
    dc->hotpluggable = false;
    hc->pre_plug = piix4_device_pre_plug_cb;
    hc->plug = piix4_device_plug_cb;
    hc->unplug_request = piix4_device_unplug_request_cb;
    hc->unplug = piix4_device_unplug_cb;
+9 −31
Original line number Diff line number Diff line
@@ -366,36 +366,6 @@ static void acpi_dsdt_add_power_button(Aml *scope)
    aml_append(scope, dev);
}

/* RSDP */
static GArray *
build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset)
{
    AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
    unsigned xsdt_pa_size = sizeof(rsdp->xsdt_physical_address);
    unsigned xsdt_pa_offset =
        (char *)&rsdp->xsdt_physical_address - rsdp_table->data;

    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
                             true /* fseg memory */);

    memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
    memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, sizeof(rsdp->oem_id));
    rsdp->length = cpu_to_le32(sizeof(*rsdp));
    rsdp->revision = 0x02;

    /* Address to be filled by Guest linker */
    bios_linker_loader_add_pointer(linker,
        ACPI_BUILD_RSDP_FILE, xsdt_pa_offset, xsdt_pa_size,
        ACPI_BUILD_TABLE_FILE, xsdt_tbl_offset);

    /* Checksum to be filled by Guest linker */
    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
        (char *)rsdp - rsdp_table->data, sizeof *rsdp,
        (char *)&rsdp->checksum - rsdp_table->data);

    return rsdp_table;
}

static void
build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
{
@@ -854,7 +824,15 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
    build_xsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);

    /* RSDP is in FSEG memory, so allocate it separately */
    build_rsdp(tables->rsdp, tables->linker, xsdt);
    {
        AcpiRsdpData rsdp_data = {
            .revision = 2,
            .oem_id = ACPI_BUILD_APPNAME6,
            .xsdt_tbl_offset = &xsdt,
            .rsdt_tbl_offset = NULL,
        };
        build_rsdp(tables->rsdp, tables->linker, &rsdp_data);
    }

    /* Cleanup memory that's no longer used. */
    g_array_free(table_offsets, true);
Loading