Commit 949ca9e4 authored by Peter Maydell's avatar Peter Maydell
Browse files

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



pc, virtio, misc bugfixes

A bunch of minor bugfixes all over the place.

changes from v2:
    added cpu hotplug rework
    added default vga type switch
    more fixes
changes from v1:
    fix for test re-generation script
    add missing acks to two patches

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

# gpg: Signature made Mon 03 Nov 2014 16:33:13 GMT using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream: (28 commits)
  vga: flip qemu 2.2 pc machine types from cirrus to stdvga
  vga: add default display to machine class
  vhost-user: fix mmap offset calculation
  hw/i386/acpi-build.c: Fix memory leak in acpi_build_tables_cleanup()
  smbios: Encode UUID according to SMBIOS specification
  pc: Add pc_compat_2_1() function
  hw/virtio/vring/event_idx: fix the vring_avail_event error
  hw/pci: fixed hotplug crash when using rombar=0 with devices having romfile
  hw/pci: fixed error flow in pci_qdev_init
  -machine vmport=off: Allow disabling of VMWare ioport emulation
  acpi/cpu-hotplug: introduce helper function to keep bit setting in one place
  cpu-hotplug: rename function for better readability
  qom/cpu: remove the unused CPU hot-plug notifier
  pc: Update rtc_cmos in pc_cpu_plug
  pc: add cpu hotplug handler to PC_MACHINE
  acpi:piix4: convert cpu hotplug to hotplug_handler API
  acpi:ich9: convert cpu hotplug to hotplug_handler API
  acpi/cpu: add cpu hotplug callback function to match hotplug_handler API
  acpi: create separate file for TCPA log
  tests: fix rebuild-expected-aml.sh for acpi-test rename
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 47e8acb4 d43f0d64
Loading
Loading
Loading
Loading
+23 −11
Original line number Diff line number Diff line
@@ -36,28 +36,40 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
    },
};

void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
                                     Error **errp)
{
    CPUClass *k = CPU_GET_CLASS(cpu);
    int64_t cpu_id;

    *gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS;
    cpu_id = k->get_arch_id(CPU(cpu));
    g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
    cpu_id = k->get_arch_id(cpu);
    if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) {
        error_setg(errp, "acpi: invalid cpu id: %" PRIi64, cpu_id);
        return;
    }

    g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
}

void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
                      AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
{
    acpi_set_cpu_present_bit(g, CPU(dev), errp);
    if (*errp != NULL) {
        return;
    }

    ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
    acpi_update_sci(ar, irq);
}

void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
                           AcpiCpuHotplug *gpe_cpu, uint16_t base)
{
    CPUState *cpu;

    CPU_FOREACH(cpu) {
        CPUClass *cc = CPU_GET_CLASS(cpu);
        int64_t id = cc->get_arch_id(cpu);

        g_assert((id / 8) < ACPI_GPE_PROC_LEN);
        gpe_cpu->sts[id / 8] |= (1 << (id % 8));
        acpi_set_cpu_present_bit(gpe_cpu, cpu, &error_abort);
    }
    memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
                          gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
+4 −13
Original line number Diff line number Diff line
@@ -209,15 +209,6 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
    acpi_pm1_evt_power_down(&pm->acpi_regs);
}

static void ich9_cpu_added_req(Notifier *n, void *opaque)
{
    ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier);

    assert(pm != NULL);
    AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
    acpi_update_sci(&pm->acpi_regs, pm->irq);
}

void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
                  qemu_irq sci_irq)
{
@@ -244,10 +235,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
    pm->powerdown_notifier.notify = pm_powerdown_req;
    qemu_register_powerdown_notifier(&pm->powerdown_notifier);

    AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
    acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
                          &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
    pm->cpu_added_notifier.notify = ich9_cpu_added_req;
    qemu_register_cpu_added_notifier(&pm->cpu_added_notifier);

    if (pm->acpi_memory_hotplug.is_enabled) {
        acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
@@ -304,6 +293,8 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp)
        object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
        acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
                            dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
        acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev, errp);
    } else {
        error_setg(errp, "acpi: device plug request for not supported device"
                   " type: %s", object_get_typename(OBJECT(dev)));
+4 −14
Original line number Diff line number Diff line
@@ -83,7 +83,6 @@ typedef struct PIIX4PMState {
    uint8_t s4_val;

    AcpiCpuHotplug gpe_cpu;
    Notifier cpu_added_notifier;

    MemHotplugState acpi_memory_hotplug;
} PIIX4PMState;
@@ -348,6 +347,8 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
        acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
                                  errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
        acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, dev, errp);
    } else {
        error_setg(errp, "acpi: device plug request for not supported device"
                   " type: %s", object_get_typename(OBJECT(dev)));
@@ -544,15 +545,6 @@ static const MemoryRegionOps piix4_gpe_ops = {
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void piix4_cpu_added_req(Notifier *n, void *opaque)
{
    PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier);

    assert(s != NULL);
    AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
    acpi_update_sci(&s->ar, s->irq);
}

static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
                                           PCIBus *bus, PIIX4PMState *s)
{
@@ -563,10 +555,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
    acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent,
                    s->use_acpi_pci_hotplug);

    AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
    acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
                          PIIX4_CPU_HOTPLUG_IO_BASE);
    s->cpu_added_notifier.notify = piix4_cpu_added_req;
    qemu_register_cpu_added_notifier(&s->cpu_added_notifier);

    if (s->acpi_memory_hotplug.is_enabled) {
        acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
+17 −11
Original line number Diff line number Diff line
@@ -249,6 +249,7 @@ static void acpi_get_pci_info(PcPciInfo *info)

#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
#define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
#define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"

static void
build_header(GArray *linker, GArray *table_data,
@@ -1214,27 +1215,28 @@ build_hpet(GArray *table_data, GArray *linker)
}

static void
build_tpm_tcpa(GArray *table_data, GArray *linker)
build_tpm_tcpa(GArray *table_data, GArray *linker, GArray *tcpalog)
{
    Acpi20Tcpa *tcpa = acpi_data_push(table_data, sizeof *tcpa);
    /* the log area will come right after the TCPA table */
    uint64_t log_area_start_address = acpi_data_len(table_data);
    uint64_t log_area_start_address = acpi_data_len(tcpalog);

    tcpa->platform_class = cpu_to_le16(TPM_TCPA_ACPI_CLASS_CLIENT);
    tcpa->log_area_minimum_length = cpu_to_le32(TPM_LOG_AREA_MINIMUM_SIZE);
    tcpa->log_area_start_address = cpu_to_le64(log_area_start_address);

    bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, 1,
                             false /* high memory */);

    /* log area start address to be filled by Guest linker */
    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
                                   ACPI_BUILD_TABLE_FILE,
                                   ACPI_BUILD_TPMLOG_FILE,
                                   table_data, &tcpa->log_area_start_address,
                                   sizeof(tcpa->log_area_start_address));

    build_header(linker, table_data,
                 (void *)tcpa, "TCPA", sizeof(*tcpa), 2);

    /* now only get the log area and with that modify table_data */
    acpi_data_push(table_data, TPM_LOG_AREA_MINIMUM_SIZE);
    acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE);
}

static void
@@ -1485,6 +1487,7 @@ typedef
struct AcpiBuildTables {
    GArray *table_data;
    GArray *rsdp;
    GArray *tcpalog;
    GArray *linker;
} AcpiBuildTables;

@@ -1492,17 +1495,17 @@ static inline void acpi_build_tables_init(AcpiBuildTables *tables)
{
    tables->rsdp = g_array_new(false, true /* clear */, 1);
    tables->table_data = g_array_new(false, true /* clear */, 1);
    tables->tcpalog = g_array_new(false, true /* clear */, 1);
    tables->linker = bios_linker_loader_init();
}

static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
{
    void *linker_data = bios_linker_loader_cleanup(tables->linker);
    if (mfre) {
    g_free(linker_data);
    }
    g_array_free(tables->rsdp, mfre);
    g_array_free(tables->table_data, mfre);
    g_array_free(tables->table_data, true);
    g_array_free(tables->tcpalog, mfre);
}

typedef
@@ -1612,7 +1615,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
    }
    if (misc.has_tpm) {
        acpi_add_table(table_offsets, tables->table_data);
        build_tpm_tcpa(tables->table_data, tables->linker);
        build_tpm_tcpa(tables->table_data, tables->linker, tables->tcpalog);

        acpi_add_table(table_offsets, tables->table_data);
        build_tpm_ssdt(tables->table_data, tables->linker);
@@ -1778,6 +1781,9 @@ void acpi_setup(PcGuestInfo *guest_info)

    acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader");

    fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
                    tables.tcpalog->data, acpi_data_len(tables.tcpalog));

    /*
     * RSDP is small so it's easy to keep it immutable, no need to
     * bother with ROM blobs.
+45 −22
Original line number Diff line number Diff line
@@ -355,30 +355,15 @@ static void pc_cmos_init_late(void *opaque)
    qemu_unregister_reset(pc_cmos_init_late, opaque);
}

typedef struct RTCCPUHotplugArg {
    Notifier cpu_added_notifier;
    ISADevice *rtc_state;
} RTCCPUHotplugArg;

static void rtc_notify_cpu_added(Notifier *notifier, void *data)
{
    RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg,
                                         cpu_added_notifier);
    ISADevice *s = arg->rtc_state;

    /* increment the number of CPUs */
    rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1);
}

void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
                  const char *boot_device,
                  const char *boot_device, MachineState *machine,
                  ISADevice *floppy, BusState *idebus0, BusState *idebus1,
                  ISADevice *s)
{
    int val, nb, i;
    FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
    static pc_cmos_init_late_arg arg;
    static RTCCPUHotplugArg cpu_hotplug_cb;
    PCMachineState *pc_machine = PC_MACHINE(machine);

    /* various important CMOS locations needed by PC/Bochs bios */

@@ -417,10 +402,14 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,

    /* set the number of CPU */
    rtc_set_memory(s, 0x5f, smp_cpus - 1);
    /* init CPU hotplug notifier */
    cpu_hotplug_cb.rtc_state = s;
    cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
    qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);

    object_property_add_link(OBJECT(machine), "rtc_state",
                             TYPE_ISA_DEVICE,
                             (Object **)&pc_machine->rtc,
                             object_property_allow_set_link,
                             OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
    object_property_set_link(OBJECT(machine), OBJECT(s),
                             "rtc_state", &error_abort);

    if (set_boot_dev(s, boot_device)) {
        exit(1);
@@ -1516,6 +1505,7 @@ static void pc_generic_machine_class_init(ObjectClass *oc, void *data)
    MachineClass *mc = MACHINE_CLASS(oc);
    QEMUMachine *qm = data;

    mc->family = qm->family;
    mc->name = qm->name;
    mc->alias = qm->alias;
    mc->desc = qm->desc;
@@ -1536,6 +1526,7 @@ static void pc_generic_machine_class_init(ObjectClass *oc, void *data)
    mc->is_default = qm->is_default;
    mc->default_machine_opts = qm->default_machine_opts;
    mc->default_boot_order = qm->default_boot_order;
    mc->default_display = qm->default_display;
    mc->compat_props = qm->compat_props;
    mc->hw_version = qm->hw_version;
}
@@ -1617,11 +1608,42 @@ out:
    error_propagate(errp, local_err);
}

static void pc_cpu_plug(HotplugHandler *hotplug_dev,
                        DeviceState *dev, Error **errp)
{
    HotplugHandlerClass *hhc;
    Error *local_err = NULL;
    PCMachineState *pcms = PC_MACHINE(hotplug_dev);

    if (!dev->hotplugged) {
        goto out;
    }

    if (!pcms->acpi_dev) {
        error_setg(&local_err,
                   "cpu hotplug is not enabled: missing acpi device");
        goto out;
    }

    hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
    hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
    if (local_err) {
        goto out;
    }

    /* increment the number of CPUs */
    rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
out:
    error_propagate(errp, local_err);
}

static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
                                      DeviceState *dev, Error **errp)
{
    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
        pc_dimm_plug(hotplug_dev, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
        pc_cpu_plug(hotplug_dev, dev, errp);
    }
}

@@ -1630,7 +1652,8 @@ static HotplugHandler *pc_get_hotpug_handler(MachineState *machine,
{
    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);

    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
        object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
        return HOTPLUG_HANDLER(machine);
    }

Loading