mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
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: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJUV65JAAoJECgfDbjSjVRpqzgIAJJDaU95xdtl/snSJVbSGsgR 2YW8mC8pjkZnV8fbu7F1vOTJSpAhj0eeXaDTqtbBhgAqBlqQ5tWAT9xDnUIlBlHN GVTWzWaifVOGMj087Ovvy9+4NyfsuvTlf3aOjvLfqlaDqI5dbZQAyIdHNFyV7Qy9 txgAcERp+caZ4rN8XgAv82KV1JGj8PXermTgLJ+DcqYxhwWm66eEviQ+f+F5YImJ CJQ6HFPXjclxHCuyKBL334SIwq8IfYyUUkIsGgKCNuHPUud7r2rqsIlRfeZBwLf9 igUgf4iPQL5TNVq9qwQmnTK6ddHTqHZmGyu902WxHK/N0EDq4dLw8diqFhZxo9Y= =f7Rb -----END PGP SIGNATURE----- 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: Michael 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: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
949ca9e479
|
@ -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,
|
||||
AcpiCpuHotplug *gpe_cpu, uint16_t base)
|
||||
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);
|
||||
|
|
|
@ -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),
|
||||
&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);
|
||||
acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
|
||||
&pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
|
||||
|
||||
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)));
|
||||
|
|
|
@ -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,
|
||||
PIIX4_CPU_HOTPLUG_IO_BASE);
|
||||
s->cpu_added_notifier.notify = piix4_cpu_added_req;
|
||||
qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
|
||||
acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
|
||||
PIIX4_CPU_HOTPLUG_IO_BASE);
|
||||
|
||||
if (s->acpi_memory_hotplug.is_enabled) {
|
||||
acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
|
||||
|
|
|
@ -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_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.
|
||||
|
|
67
hw/i386/pc.c
67
hw/i386/pc.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ static bool has_acpi_build = true;
|
|||
static int legacy_acpi_table_size;
|
||||
static bool smbios_defaults = true;
|
||||
static bool smbios_legacy_mode;
|
||||
static bool smbios_uuid_encoded = true;
|
||||
/* Make sure that guest addresses aligned at 1Gbyte boundaries get mapped to
|
||||
* host addresses aligned at 1Gbyte boundaries. This way we can use 1GByte
|
||||
* pages in the host.
|
||||
|
@ -172,7 +173,7 @@ static void pc_init1(MachineState *machine,
|
|||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
/* These values are guest ABI, do not change */
|
||||
smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)",
|
||||
mc->name, smbios_legacy_mode);
|
||||
mc->name, smbios_legacy_mode, smbios_uuid_encoded);
|
||||
}
|
||||
|
||||
/* allocate ram and load rom/bios */
|
||||
|
@ -266,7 +267,7 @@ static void pc_init1(MachineState *machine,
|
|||
}
|
||||
|
||||
pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order,
|
||||
floppy, idebus[0], idebus[1], rtc_state);
|
||||
machine, floppy, idebus[0], idebus[1], rtc_state);
|
||||
|
||||
if (pci_enabled && usb_enabled(false)) {
|
||||
pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
|
||||
|
@ -302,8 +303,14 @@ static void pc_init_pci(MachineState *machine)
|
|||
pc_init1(machine, 1, 1);
|
||||
}
|
||||
|
||||
static void pc_compat_2_1(MachineState *machine)
|
||||
{
|
||||
smbios_uuid_encoded = false;
|
||||
}
|
||||
|
||||
static void pc_compat_2_0(MachineState *machine)
|
||||
{
|
||||
pc_compat_2_1(machine);
|
||||
/* This value depends on the actual DSDT and SSDT compiled into
|
||||
* the source QEMU; unfortunately it depends on the binary and
|
||||
* not on the machine type, so we cannot make pc-i440fx-1.7 work on
|
||||
|
@ -368,6 +375,12 @@ static void pc_compat_1_2(MachineState *machine)
|
|||
x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
|
||||
}
|
||||
|
||||
static void pc_init_pci_2_1(MachineState *machine)
|
||||
{
|
||||
pc_compat_2_1(machine);
|
||||
pc_init_pci(machine);
|
||||
}
|
||||
|
||||
static void pc_init_pci_2_0(MachineState *machine)
|
||||
{
|
||||
pc_compat_2_0(machine);
|
||||
|
@ -451,12 +464,14 @@ static void pc_xen_hvm_init(MachineState *machine)
|
|||
|
||||
#define PC_I440FX_MACHINE_OPTIONS \
|
||||
PC_DEFAULT_MACHINE_OPTIONS, \
|
||||
.family = "pc_piix", \
|
||||
.desc = "Standard PC (i440FX + PIIX, 1996)", \
|
||||
.hot_add_cpu = pc_hot_add_cpu
|
||||
|
||||
#define PC_I440FX_2_2_MACHINE_OPTIONS \
|
||||
PC_I440FX_MACHINE_OPTIONS, \
|
||||
.default_machine_opts = "firmware=bios-256k.bin"
|
||||
.default_machine_opts = "firmware=bios-256k.bin", \
|
||||
.default_display = "std"
|
||||
|
||||
static QEMUMachine pc_i440fx_machine_v2_2 = {
|
||||
PC_I440FX_2_2_MACHINE_OPTIONS,
|
||||
|
@ -466,14 +481,16 @@ static QEMUMachine pc_i440fx_machine_v2_2 = {
|
|||
.is_default = 1,
|
||||
};
|
||||
|
||||
#define PC_I440FX_2_1_MACHINE_OPTIONS PC_I440FX_2_2_MACHINE_OPTIONS
|
||||
#define PC_I440FX_2_1_MACHINE_OPTIONS \
|
||||
PC_I440FX_MACHINE_OPTIONS, \
|
||||
.default_machine_opts = "firmware=bios-256k.bin"
|
||||
|
||||
static QEMUMachine pc_i440fx_machine_v2_1 = {
|
||||
PC_I440FX_2_1_MACHINE_OPTIONS,
|
||||
.name = "pc-i440fx-2.1",
|
||||
.init = pc_init_pci,
|
||||
.init = pc_init_pci_2_1,
|
||||
.compat_props = (GlobalProperty[]) {
|
||||
PC_COMPAT_2_1,
|
||||
HW_COMPAT_2_1,
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
|
@ -661,7 +678,7 @@ static QEMUMachine pc_machine_v1_1 = {
|
|||
.property = "class",\
|
||||
.value = stringify(PCI_CLASS_MEMORY_RAM),\
|
||||
},{\
|
||||
.driver = "apic",\
|
||||
.driver = "apic-common",\
|
||||
.property = "vapic",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
static bool has_acpi_build = true;
|
||||
static bool smbios_defaults = true;
|
||||
static bool smbios_legacy_mode;
|
||||
static bool smbios_uuid_encoded = true;
|
||||
/* Make sure that guest addresses aligned at 1Gbyte boundaries get mapped to
|
||||
* host addresses aligned at 1Gbyte boundaries. This way we can use 1GByte
|
||||
* pages in the host.
|
||||
|
@ -163,7 +164,7 @@ static void pc_q35_init(MachineState *machine)
|
|||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
/* These values are guest ABI, do not change */
|
||||
smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)",
|
||||
mc->name, smbios_legacy_mode);
|
||||
mc->name, smbios_legacy_mode, smbios_uuid_encoded);
|
||||
}
|
||||
|
||||
/* allocate ram and load rom/bios */
|
||||
|
@ -271,7 +272,7 @@ static void pc_q35_init(MachineState *machine)
|
|||
8, NULL, 0);
|
||||
|
||||
pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order,
|
||||
floppy, idebus[0], idebus[1], rtc_state);
|
||||
machine, floppy, idebus[0], idebus[1], rtc_state);
|
||||
|
||||
/* the rest devices to which pci devfn is automatically assigned */
|
||||
pc_vga_init(isa_bus, host_bus);
|
||||
|
@ -281,8 +282,14 @@ static void pc_q35_init(MachineState *machine)
|
|||
}
|
||||
}
|
||||
|
||||
static void pc_compat_2_1(MachineState *machine)
|
||||
{
|
||||
smbios_uuid_encoded = false;
|
||||
}
|
||||
|
||||
static void pc_compat_2_0(MachineState *machine)
|
||||
{
|
||||
pc_compat_2_1(machine);
|
||||
smbios_legacy_mode = true;
|
||||
has_reserved_memory = false;
|
||||
pc_set_legacy_acpi_data_size();
|
||||
|
@ -316,6 +323,12 @@ static void pc_compat_1_4(MachineState *machine)
|
|||
x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
|
||||
}
|
||||
|
||||
static void pc_q35_init_2_1(MachineState *machine)
|
||||
{
|
||||
pc_compat_2_1(machine);
|
||||
pc_q35_init(machine);
|
||||
}
|
||||
|
||||
static void pc_q35_init_2_0(MachineState *machine)
|
||||
{
|
||||
pc_compat_2_0(machine);
|
||||
|
@ -348,13 +361,15 @@ static void pc_q35_init_1_4(MachineState *machine)
|
|||
|
||||
#define PC_Q35_MACHINE_OPTIONS \
|
||||
PC_DEFAULT_MACHINE_OPTIONS, \
|
||||
.family = "pc_q35", \
|
||||
.desc = "Standard PC (Q35 + ICH9, 2009)", \
|
||||
.hot_add_cpu = pc_hot_add_cpu, \
|
||||
.units_per_default_bus = 1
|
||||
|
||||
#define PC_Q35_2_2_MACHINE_OPTIONS \
|
||||
PC_Q35_MACHINE_OPTIONS, \
|
||||
.default_machine_opts = "firmware=bios-256k.bin"
|
||||
.default_machine_opts = "firmware=bios-256k.bin", \
|
||||
.default_display = "std"
|
||||
|
||||
static QEMUMachine pc_q35_machine_v2_2 = {
|
||||
PC_Q35_2_2_MACHINE_OPTIONS,
|
||||
|
@ -363,14 +378,16 @@ static QEMUMachine pc_q35_machine_v2_2 = {
|
|||
.init = pc_q35_init,
|
||||
};
|
||||
|
||||
#define PC_Q35_2_1_MACHINE_OPTIONS PC_Q35_2_2_MACHINE_OPTIONS
|
||||
#define PC_Q35_2_1_MACHINE_OPTIONS \
|
||||
PC_Q35_MACHINE_OPTIONS, \
|
||||
.default_machine_opts = "firmware=bios-256k.bin"
|
||||
|
||||
static QEMUMachine pc_q35_machine_v2_1 = {
|
||||
PC_Q35_2_1_MACHINE_OPTIONS,
|
||||
.name = "pc-q35-2.1",
|
||||
.init = pc_q35_init,
|
||||
.init = pc_q35_init_2_1,
|
||||
.compat_props = (GlobalProperty[]) {
|
||||
PC_COMPAT_2_1,
|
||||
HW_COMPAT_2_1,
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
|
|
|
@ -48,6 +48,7 @@ struct smbios_table {
|
|||
static uint8_t *smbios_entries;
|
||||
static size_t smbios_entries_len;
|
||||
static bool smbios_legacy = true;
|
||||
static bool smbios_uuid_encoded = true;
|
||||
/* end: legacy structures & constants for <= 2.0 machines */
|
||||
|
||||
|
||||
|
@ -391,6 +392,11 @@ static void smbios_build_type_1_fields(void)
|
|||
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
|
||||
type1.family);
|
||||
if (qemu_uuid_set) {
|
||||
/* We don't encode the UUID in the "wire format" here because this
|
||||
* function is for legacy mode and needs to keep the guest ABI, and
|
||||
* because we don't know what's the SMBIOS version advertised by the
|
||||
* BIOS.
|
||||
*/
|
||||
smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
|
||||
qemu_uuid, 16);
|
||||
}
|
||||
|
@ -523,6 +529,19 @@ static void smbios_build_type_0_table(void)
|
|||
SMBIOS_BUILD_TABLE_POST;
|
||||
}
|
||||
|
||||
/* Encode UUID from the big endian encoding described on RFC4122 to the wire
|
||||
* format specified by SMBIOS version 2.6.
|
||||
*/
|
||||
static void smbios_encode_uuid(struct smbios_uuid *uuid, const uint8_t *buf)
|
||||
{
|
||||
memcpy(uuid, buf, 16);
|
||||
if (smbios_uuid_encoded) {
|
||||
uuid->time_low = bswap32(uuid->time_low);
|
||||
uuid->time_mid = bswap16(uuid->time_mid);
|
||||
uuid->time_hi_and_version = bswap16(uuid->time_hi_and_version);
|
||||
}
|
||||
}
|
||||
|
||||
static void smbios_build_type_1_table(void)
|
||||
{
|
||||
SMBIOS_BUILD_TABLE_PRE(1, 0x100, true); /* required */
|
||||
|
@ -532,9 +551,9 @@ static void smbios_build_type_1_table(void)
|
|||
SMBIOS_TABLE_SET_STR(1, version_str, type1.version);
|
||||
SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial);
|
||||
if (qemu_uuid_set) {
|
||||
memcpy(t->uuid, qemu_uuid, 16);
|
||||
smbios_encode_uuid(&t->uuid, qemu_uuid);
|
||||
} else {
|
||||
memset(t->uuid, 0, 16);
|
||||
memset(&t->uuid, 0, 16);
|
||||
}
|
||||
t->wake_up_type = 0x06; /* power switch */
|
||||
SMBIOS_TABLE_SET_STR(1, sku_number_str, type1.sku);
|
||||
|
@ -746,10 +765,12 @@ void smbios_set_cpuid(uint32_t version, uint32_t features)
|
|||
}
|
||||
|
||||
void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
const char *version, bool legacy_mode)
|
||||
const char *version, bool legacy_mode,
|
||||
bool uuid_encoded)
|
||||
{
|
||||
smbios_have_defaults = true;
|
||||
smbios_legacy = legacy_mode;
|
||||
smbios_uuid_encoded = uuid_encoded;
|
||||
|
||||
/* drop unwanted version of command-line file blob(s) */
|
||||
if (smbios_legacy) {
|
||||
|
@ -821,7 +842,7 @@ void smbios_get_tables(uint8_t **tables, size_t *tables_len,
|
|||
smbios_build_type_2_table();
|
||||
smbios_build_type_3_table();
|
||||
|
||||
smbios_smp_sockets = smp_cpus / (smp_cores * smp_threads);
|
||||
smbios_smp_sockets = DIV_ROUND_UP(smp_cpus, smp_cores * smp_threads);
|
||||
assert(smbios_smp_sockets >= 1);
|
||||
|
||||
for (i = 0; i < smbios_smp_sockets; i++) {
|
||||
|
|
16
hw/pci/pci.c
16
hw/pci/pci.c
|
@ -1776,7 +1776,12 @@ static int pci_qdev_init(DeviceState *qdev)
|
|||
pci_dev->romfile = g_strdup(pc->romfile);
|
||||
is_default_rom = true;
|
||||
}
|
||||
pci_add_option_rom(pci_dev, is_default_rom);
|
||||
|
||||
rc = pci_add_option_rom(pci_dev, is_default_rom);
|
||||
if (rc != 0) {
|
||||
pci_unregister_device(DEVICE(pci_dev));
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1937,6 +1942,15 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
|
|||
* for 0.11 compatibility.
|
||||
*/
|
||||
int class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
|
||||
|
||||
/*
|
||||
* Hot-plugged devices can't use the option ROM
|
||||
* if the rom bar is disabled.
|
||||
*/
|
||||
if (DEVICE(pdev)->hotplugged) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (class == 0x0300) {
|
||||
rom_add_vga(pdev->romfile);
|
||||
} else {
|
||||
|
|
|
@ -529,7 +529,7 @@ bool pcie_cap_is_arifwd_enabled(const PCIDevice *dev)
|
|||
}
|
||||
|
||||
/**************************************************************************
|
||||
* pci express extended capability allocation functions
|
||||
* pci express extended capability list management functions
|
||||
* uint16_t ext_cap_id (16 bit)
|
||||
* uint8_t cap_ver (4 bit)
|
||||
* uint16_t cap_offset (12 bit)
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
#include "trace.h"
|
||||
#include "hw/nmi.h"
|
||||
|
||||
#include "hw/compat.h"
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
/* SLOF memory layout:
|
||||
|
@ -1689,10 +1691,15 @@ static const TypeInfo spapr_machine_info = {
|
|||
static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
static GlobalProperty compat_props[] = {
|
||||
HW_COMPAT_2_1,
|
||||
{ /* end of list */ }
|
||||
};
|
||||
|
||||
mc->name = "pseries-2.1";
|
||||
mc->desc = "pSeries Logical Partition (PAPR compliant) v2.1";
|
||||
mc->is_default = 0;
|
||||
mc->compat_props = compat_props;
|
||||
}
|
||||
|
||||
static const TypeInfo spapr_machine_2_1_info = {
|
||||
|
|
|
@ -352,10 +352,6 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
|
||||
vring_avail_event(&vring->vr) = vring->vr.avail->idx;
|
||||
}
|
||||
|
||||
i = head;
|
||||
do {
|
||||
if (unlikely(i >= num)) {
|
||||
|
@ -392,6 +388,10 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
|
|||
|
||||
/* On success, increment avail index. */
|
||||
vring->last_avail_idx++;
|
||||
if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
|
||||
vring_avail_event(&vring->vr) = vring->last_avail_idx;
|
||||
}
|
||||
|
||||
return head;
|
||||
|
||||
out:
|
||||
|
|
|
@ -226,7 +226,7 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
|
|||
msg.memory.regions[fd_num].memory_size = reg->memory_size;
|
||||
msg.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
|
||||
msg.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
|
||||
(uintptr_t) qemu_get_ram_block_host_ptr(reg->guest_phys_addr);
|
||||
(uintptr_t) qemu_get_ram_block_host_ptr(ram_addr);
|
||||
assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
|
||||
fds[fd_num++] = fd;
|
||||
}
|
||||
|
|
|
@ -86,9 +86,6 @@
|
|||
* 12 is historical, and due to x86 page size. */
|
||||
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12
|
||||
|
||||
/* Flags track per-device state like workarounds for quirks in older guests. */
|
||||
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG (1 << 0)
|
||||
|
||||
static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
|
||||
VirtIOPCIProxy *dev);
|
||||
|
||||
|
@ -323,14 +320,6 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|||
proxy->pci_dev.config[PCI_COMMAND] |
|
||||
PCI_COMMAND_MASTER, 1);
|
||||
}
|
||||
|
||||
/* Linux before 2.6.34 sets the device as OK without enabling
|
||||
the PCI device bus master bit. In this case we need to disable
|
||||
some safety checks. */
|
||||
if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
|
||||
!(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
|
||||
proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
|
||||
}
|
||||
break;
|
||||
case VIRTIO_MSI_CONFIG_VECTOR:
|
||||
msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
|
||||
|
@ -483,8 +472,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
|
|||
pci_default_write_config(pci_dev, address, val, len);
|
||||
|
||||
if (range_covers_byte(address, len, PCI_COMMAND) &&
|
||||
!(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
|
||||
!(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
|
||||
!(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
|
||||
virtio_pci_stop_ioeventfd(proxy);
|
||||
virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
|
||||
}
|
||||
|
@ -895,11 +883,15 @@ static void virtio_pci_vmstate_change(DeviceState *d, bool running)
|
|||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||
|
||||
if (running) {
|
||||
/* Try to find out if the guest has bus master disabled, but is
|
||||
in ready state. Then we have a buggy guest OS. */
|
||||
if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
|
||||
/* Old QEMU versions did not set bus master enable on status write.
|
||||
* Detect DRIVER set and enable it.
|
||||
*/
|
||||
if ((proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION) &&
|
||||
(vdev->status & VIRTIO_CONFIG_S_DRIVER) &&
|
||||
!(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
|
||||
proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
|
||||
pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,
|
||||
proxy->pci_dev.config[PCI_COMMAND] |
|
||||
PCI_COMMAND_MASTER, 1);
|
||||
}
|
||||
virtio_pci_start_ioeventfd(proxy);
|
||||
} else {
|
||||
|
@ -1040,10 +1032,11 @@ static void virtio_pci_reset(DeviceState *qdev)
|
|||
virtio_pci_stop_ioeventfd(proxy);
|
||||
virtio_bus_reset(bus);
|
||||
msix_unuse_all_vectors(&proxy->pci_dev);
|
||||
proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
|
||||
}
|
||||
|
||||
static Property virtio_pci_properties[] = {
|
||||
DEFINE_PROP_BIT("virtio-pci-bus-master-bug-migration", VirtIOPCIProxy, flags,
|
||||
VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT, false),
|
||||
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
|
|
@ -53,6 +53,11 @@ typedef struct VirtioBusClass VirtioPCIBusClass;
|
|||
#define VIRTIO_PCI_BUS_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(VirtioPCIBusClass, klass, TYPE_VIRTIO_PCI_BUS)
|
||||
|
||||
/* Need to activate work-arounds for buggy guests at vmstate load. */
|
||||
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT 0
|
||||
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION \
|
||||
(1 << VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT)
|
||||
|
||||
/* Performance improves when virtqueue kick processing is decoupled from the
|
||||
* vcpu thread using ioeventfd for some devices. */
|
||||
#define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1
|
||||
|
|
|
@ -469,7 +469,7 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
|
|||
|
||||
i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
|
||||
if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
|
||||
vring_avail_event(vq, vring_avail_idx(vq));
|
||||
vring_avail_event(vq, vq->last_avail_idx);
|
||||
}
|
||||
|
||||
if (vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_INDIRECT) {
|
||||
|
|
|
@ -20,8 +20,9 @@ typedef struct AcpiCpuHotplug {
|
|||
uint8_t sts[ACPI_GPE_PROC_LEN];
|
||||
} AcpiCpuHotplug;
|
||||
|
||||
void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
|
||||
void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
|
||||
AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
|
||||
|
||||
void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
|
||||
AcpiCpuHotplug *gpe_cpu, uint16_t base);
|
||||
void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
|
||||
AcpiCpuHotplug *gpe_cpu, uint16_t base);
|
||||
#endif
|
||||
|
|
|
@ -47,7 +47,6 @@ typedef struct ICH9LPCPMRegs {
|
|||
Notifier powerdown_notifier;
|
||||
|
||||
AcpiCpuHotplug gpe_cpu;
|
||||
Notifier cpu_added_notifier;
|
||||
|
||||
MemHotplugState acpi_memory_hotplug;
|
||||
} ICH9LPCPMRegs;
|
||||
|
|
|
@ -19,6 +19,7 @@ typedef void QEMUMachineHotAddCPUFunc(const int64_t id, Error **errp);
|
|||
typedef int QEMUMachineGetKvmtypeFunc(const char *arg);
|
||||
|
||||
struct QEMUMachine {
|
||||
const char *family; /* NULL iff @name identifies a standalone machtype */
|
||||
const char *name;
|
||||
const char *alias;
|
||||
const char *desc;
|
||||
|
@ -39,6 +40,7 @@ struct QEMUMachine {
|
|||
int is_default;
|
||||
const char *default_machine_opts;
|
||||
const char *default_boot_order;
|
||||
const char *default_display;
|
||||
GlobalProperty *compat_props;
|
||||
const char *hw_version;
|
||||
};
|
||||
|
@ -76,6 +78,7 @@ struct MachineClass {
|
|||
ObjectClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
const char *family; /* NULL iff @name identifies a standalone machtype */
|
||||
const char *name;
|
||||
const char *alias;
|
||||
const char *desc;
|
||||
|
@ -98,6 +101,7 @@ struct MachineClass {
|
|||
int is_default;
|
||||
const char *default_machine_opts;
|
||||
const char *default_boot_order;
|
||||
const char *default_display;
|
||||
GlobalProperty *compat_props;
|
||||
const char *hw_version;
|
||||
|
||||
|
|
35
include/hw/compat.h
Normal file
35
include/hw/compat.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef HW_COMPAT_H
|
||||
#define HW_COMPAT_H
|
||||
|
||||
#define HW_COMPAT_2_1 \
|
||||
{\
|
||||
.driver = "intel-hda",\
|
||||
.property = "old_msi_addr",\
|
||||
.value = "on",\
|
||||
},{\
|
||||
.driver = "VGA",\
|
||||
.property = "qemu-extended-regs",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "secondary-vga",\
|
||||
.property = "qemu-extended-regs",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "virtio-scsi-pci",\
|
||||
.property = "any_layout",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "usb-mouse",\
|
||||
.property = "usb_version",\
|
||||
.value = stringify(1),\
|
||||
},{\
|
||||
.driver = "usb-kbd",\
|
||||
.property = "usb_version",\
|
||||
.value = stringify(1),\
|
||||
},{\
|
||||
.driver = "virtio-pci",\
|
||||
.property = "virtio-pci-bus-master-bug-migration",\
|
||||
.value = "on",\
|
||||
}
|
||||
|
||||
#endif /* HW_COMPAT_H */
|
|
@ -37,7 +37,7 @@
|
|||
#define VTD_PCI_DEVFN_MAX 256
|
||||
#define VTD_PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
|
||||
#define VTD_PCI_FUNC(devfn) ((devfn) & 0x07)
|
||||
#define VTD_SID_TO_BUS(sid) (((sid) >> 8) && 0xff)
|
||||
#define VTD_SID_TO_BUS(sid) (((sid) >> 8) & 0xff)
|
||||
#define VTD_SID_TO_DEVFN(sid) ((sid) & 0xff)
|
||||
|
||||
#define DMAR_REG_SIZE 0x230
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "sysemu/sysemu.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/compat.h"
|
||||
|
||||
#define HPET_INTCAP "hpet-intcap"
|
||||
|
||||
|
@ -33,6 +34,7 @@ struct PCMachineState {
|
|||
MemoryRegion hotplug_memory;
|
||||
|
||||
HotplugHandler *acpi_dev;
|
||||
ISADevice *rtc;
|
||||
|
||||
uint64_t max_ram_below_4g;
|
||||
bool vmport;
|
||||
|
@ -212,7 +214,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
|
|||
uint32 hpet_irqs);
|
||||
void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd);
|
||||
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 *ide0, BusState *ide1,
|
||||
ISADevice *s);
|
||||
void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus);
|
||||
|
@ -303,31 +305,8 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
|
|||
int e820_get_num_entries(void);
|
||||
bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
|
||||
|
||||
#define PC_COMPAT_2_1 \
|
||||
{\
|
||||
.driver = "intel-hda",\
|
||||
.property = "old_msi_addr",\
|
||||
.value = "on",\
|
||||
},{\
|
||||
.driver = "VGA",\
|
||||
.property = "qemu-extended-regs",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "secondary-vga",\
|
||||
.property = "qemu-extended-regs",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "usb-mouse",\
|
||||
.property = "usb_version",\
|
||||
.value = stringify(1),\
|
||||
},{\
|
||||
.driver = "usb-kbd",\
|
||||
.property = "usb_version",\
|
||||
.value = stringify(1),\
|
||||
}
|
||||
|
||||
#define PC_COMPAT_2_0 \
|
||||
PC_COMPAT_2_1, \
|
||||
HW_COMPAT_2_1, \
|
||||
{\
|
||||
.driver = "virtio-scsi-pci",\
|
||||
.property = "any_layout",\
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
void smbios_entry_add(QemuOpts *opts);
|
||||
void smbios_set_cpuid(uint32_t version, uint32_t features);
|
||||
void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
const char *version, bool legacy_mode);
|
||||
const char *version, bool legacy_mode,
|
||||
bool uuid_encoded);
|
||||
uint8_t *smbios_get_table_legacy(size_t *length);
|
||||
void smbios_get_tables(uint8_t **tables, size_t *tables_len,
|
||||
uint8_t **anchor, size_t *anchor_len);
|
||||
|
@ -72,6 +73,18 @@ struct smbios_type_0 {
|
|||
uint8_t embedded_controller_minor_release;
|
||||
} QEMU_PACKED;
|
||||
|
||||
/* UUID encoding. The time_* fields are little-endian, as specified by SMBIOS
|
||||
* version 2.6.
|
||||
*/
|
||||
struct smbios_uuid {
|
||||
uint32_t time_low;
|
||||
uint16_t time_mid;
|
||||
uint16_t time_hi_and_version;
|
||||
uint8_t clock_seq_hi_and_reserved;
|
||||
uint8_t clock_seq_low;
|
||||
uint8_t node[6];
|
||||
} QEMU_PACKED;
|
||||
|
||||
/* SMBIOS type 1 - System Information */
|
||||
struct smbios_type_1 {
|
||||
struct smbios_structure_header header;
|
||||
|
@ -79,7 +92,7 @@ struct smbios_type_1 {
|
|||
uint8_t product_name_str;
|
||||
uint8_t version_str;
|
||||
uint8_t serial_number_str;
|
||||
uint8_t uuid[16];
|
||||
struct smbios_uuid uuid;
|
||||
uint8_t wake_up_type;
|
||||
uint8_t sku_number_str;
|
||||
uint8_t family_str;
|
||||
|
|
|
@ -184,9 +184,6 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
|
|||
/* generic hotplug */
|
||||
void drive_hot_add(Monitor *mon, const QDict *qdict);
|
||||
|
||||
/* CPU hotplug */
|
||||
void qemu_register_cpu_added_notifier(Notifier *notifier);
|
||||
|
||||
/* pcie aer error injection */
|
||||
void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
|
||||
int do_pcie_aer_inject_error(Monitor *mon,
|
||||
|
|
10
qom/cpu.c
10
qom/cpu.c
|
@ -107,15 +107,6 @@ static void cpu_common_get_memory_mapping(CPUState *cpu,
|
|||
error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
|
||||
}
|
||||
|
||||
/* CPU hot-plug notifiers */
|
||||
static NotifierList cpu_added_notifiers =
|
||||
NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
|
||||
|
||||
void qemu_register_cpu_added_notifier(Notifier *notifier)
|
||||
{
|
||||
notifier_list_add(&cpu_added_notifiers, notifier);
|
||||
}
|
||||
|
||||
void cpu_reset_interrupt(CPUState *cpu, int mask)
|
||||
{
|
||||
cpu->interrupt_request &= ~mask;
|
||||
|
@ -312,7 +303,6 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp)
|
|||
|
||||
if (dev->hotplugged) {
|
||||
cpu_synchronize_post_init(cpu);
|
||||
notifier_list_notify(&cpu_added_notifiers, dev);
|
||||
cpu_resume(cpu);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,13 +139,16 @@ def aml_name_string(offset):
|
|||
offset += 1
|
||||
return offset;
|
||||
|
||||
# Given data offset, find 8 byte buffer offset
|
||||
def aml_data_buffer8(offset):
|
||||
#0x08 NameOp NameString DataRef
|
||||
expect = [0x11, 0x0B, 0x0A, 0x08]
|
||||
# Given data offset, find variable length byte buffer offset
|
||||
def aml_data_buffer(offset, length):
|
||||
#0x11 PkgLength BufferSize ByteList
|
||||
if (length > 63):
|
||||
die( "Name offset 0x%x: expected a one byte PkgLength (length<=63)" %
|
||||
(offset));
|
||||
expect = [0x11, length+3, 0x0A, length]
|
||||
if (aml[offset:offset+4] != expect):
|
||||
die( "Name offset 0x%x: expected %s actual %s" %
|
||||
(offset, aml[offset:offset+4], expect))
|
||||
(offset, expect, aml[offset:offset+4]))
|
||||
return offset + len(expect)
|
||||
|
||||
# Given data offset, find dword const offset
|
||||
|
@ -172,9 +175,9 @@ def aml_data_byte_const(offset):
|
|||
(offset, aml[offset]));
|
||||
return offset + 1;
|
||||
|
||||
# Find name'd buffer8
|
||||
def aml_name_buffer8(offset):
|
||||
return aml_data_buffer8(aml_name_string(offset) + 4)
|
||||
# Find name'd buffer
|
||||
def aml_name_buffer(offset, length):
|
||||
return aml_data_buffer(aml_name_string(offset) + 4, length)
|
||||
|
||||
# Given name offset, find dword const offset
|
||||
def aml_name_dword_const(offset):
|
||||
|
@ -308,7 +311,9 @@ def aml_package_start(offset):
|
|||
output[array] = aml
|
||||
continue
|
||||
if (directive == "ACPI_EXTRACT_NAME_BUFFER8"):
|
||||
offset = aml_name_buffer8(offset)
|
||||
offset = aml_name_buffer(offset, 8)
|
||||
elif (directive == "ACPI_EXTRACT_NAME_BUFFER16"):
|
||||
offset = aml_name_buffer(offset, 16)
|
||||
elif (directive == "ACPI_EXTRACT_NAME_DWORD_CONST"):
|
||||
offset = aml_name_dword_const(offset)
|
||||
elif (directive == "ACPI_EXTRACT_NAME_WORD_CONST"):
|
||||
|
|
|
@ -23,13 +23,13 @@ else
|
|||
exit 1;
|
||||
fi
|
||||
|
||||
if [ ! -e "tests/acpi-test" ]; then
|
||||
echo "Test: acpi-test is required! Run make check before this script."
|
||||
if [ ! -e "tests/bios-tables-test" ]; then
|
||||
echo "Test: bios-tables-test is required! Run make check before this script."
|
||||
echo "Run this script from the build directory."
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
TEST_ACPI_REBUILD_AML=y QTEST_QEMU_BINARY=$qemu tests/acpi-test
|
||||
TEST_ACPI_REBUILD_AML=y QTEST_QEMU_BINARY=$qemu tests/bios-tables-test
|
||||
|
||||
echo "The files were rebuilt and can be added to git."
|
||||
echo "However, if new files were created, please copy them manually" \
|
||||
|
|
46
vl.c
46
vl.c
|
@ -190,6 +190,9 @@ int nb_numa_nodes;
|
|||
int max_numa_nodeid;
|
||||
NodeInfo numa_info[MAX_NODES];
|
||||
|
||||
/* The bytes in qemu_uuid[] are in the order specified by RFC4122, _not_ in the
|
||||
* little-endian "wire format" described in the SMBIOS 2.6 specification.
|
||||
*/
|
||||
uint8_t qemu_uuid[16];
|
||||
bool qemu_uuid_set;
|
||||
|
||||
|
@ -1420,6 +1423,7 @@ static void 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;
|
||||
|
@ -1440,6 +1444,7 @@ static void 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;
|
||||
}
|
||||
|
@ -2492,7 +2497,41 @@ static int debugcon_parse(const char *devname)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static MachineClass *machine_parse(const char *name)
|
||||
static gint machine_class_cmp(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const MachineClass *mc1 = a, *mc2 = b;
|
||||
int res;
|
||||
|
||||
if (mc1->family == NULL) {
|
||||
if (mc2->family == NULL) {
|
||||
/* Compare standalone machine types against each other; they sort
|
||||
* in increasing order.
|
||||
*/
|
||||
return strcmp(object_class_get_name(OBJECT_CLASS(mc1)),
|
||||
object_class_get_name(OBJECT_CLASS(mc2)));
|
||||
}
|
||||
|
||||
/* Standalone machine types sort after families. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mc2->family == NULL) {
|
||||
/* Families sort before standalone machine types. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Families sort between each other alphabetically increasingly. */
|
||||
res = strcmp(mc1->family, mc2->family);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Within the same family, machine types sort in decreasing order. */
|
||||
return strcmp(object_class_get_name(OBJECT_CLASS(mc2)),
|
||||
object_class_get_name(OBJECT_CLASS(mc1)));
|
||||
}
|
||||
|
||||
static MachineClass *machine_parse(const char *name)
|
||||
{
|
||||
MachineClass *mc = NULL;
|
||||
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
|
||||
|
@ -2508,6 +2547,7 @@ static MachineClass *machine_parse(const char *name)
|
|||
error_printf("Use -machine help to list supported machines!\n");
|
||||
} else {
|
||||
printf("Supported machines are:\n");
|
||||
machines = g_slist_sort(machines, machine_class_cmp);
|
||||
for (el = machines; el; el = el->next) {
|
||||
MachineClass *mc = el->data;
|
||||
if (mc->alias) {
|
||||
|
@ -4189,7 +4229,9 @@ int main(int argc, char **argv, char **envp)
|
|||
|
||||
/* If no default VGA is requested, the default is "none". */
|
||||
if (default_vga) {
|
||||
if (cirrus_vga_available()) {
|
||||
if (machine_class->default_display) {
|
||||
vga_model = machine_class->default_display;
|
||||
} else if (cirrus_vga_available()) {
|
||||
vga_model = "cirrus";
|
||||
} else if (vga_available()) {
|
||||
vga_model = "std";
|
||||
|
|
Loading…
Reference in a new issue