summaryrefslogtreecommitdiffstats
path: root/hw/i386/pc.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/i386/pc.c')
-rw-r--r--hw/i386/pc.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 1eb1db0372..2baff4a660 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -30,6 +30,7 @@
#include "hw/block/fdc.h"
#include "hw/ide.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "monitor/monitor.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/timer/hpet.h"
@@ -1006,7 +1007,6 @@ static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id,
}
qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
- object_unref(OBJECT(cpu));
object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err);
object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
@@ -1025,7 +1025,9 @@ static const char *current_cpu_model;
void pc_hot_add_cpu(const int64_t id, Error **errp)
{
DeviceState *icc_bridge;
+ X86CPU *cpu;
int64_t apic_id = x86_cpu_apic_id_from_index(id);
+ Error *local_err = NULL;
if (id < 0) {
error_setg(errp, "Invalid CPU id: %" PRIi64, id);
@@ -1053,7 +1055,12 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
icc_bridge = DEVICE(object_resolve_path_type("icc-bridge",
TYPE_ICC_BRIDGE, NULL));
- pc_new_cpu(current_cpu_model, apic_id, icc_bridge, errp);
+ cpu = pc_new_cpu(current_cpu_model, apic_id, icc_bridge, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ object_unref(OBJECT(cpu));
}
void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge)
@@ -1087,6 +1094,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge)
error_report_err(error);
exit(1);
}
+ object_unref(OBJECT(cpu));
}
/* map APIC MMIO area if CPU has APIC */
@@ -1119,6 +1127,25 @@ void pc_guest_info_machine_done(Notifier *notifier, void *data)
PcGuestInfoState *guest_info_state = container_of(notifier,
PcGuestInfoState,
machine_done);
+ PCIBus *bus = find_i440fx();
+
+ if (bus) {
+ int extra_hosts = 0;
+
+ QLIST_FOREACH(bus, &bus->child, sibling) {
+ /* look for expander root buses */
+ if (pci_bus_is_root(bus)) {
+ extra_hosts++;
+ }
+ }
+ if (extra_hosts && guest_info_state->info.fw_cfg) {
+ uint64_t *val = g_malloc(sizeof(*val));
+ *val = cpu_to_le64(extra_hosts);
+ fw_cfg_add_file(guest_info_state->info.fw_cfg,
+ "etc/extra-pci-roots", val, sizeof(*val));
+ }
+ }
+
acpi_setup(&guest_info_state->info);
}
@@ -1345,9 +1372,9 @@ FWCfgState *pc_memory_init(MachineState *machine,
return fw_cfg;
}
-qemu_irq *pc_allocate_cpu_irq(void)
+qemu_irq pc_allocate_cpu_irq(void)
{
- return qemu_allocate_irqs(pic_irq_request, NULL, 1);
+ return qemu_allocate_irq(pic_irq_request, NULL, 0);
}
DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)