aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2020-12-03 11:54:18 +0100
committerGerd Hoffmann <kraxel@redhat.com>2020-12-10 08:47:44 +0100
commit4d01b8994ca5ce7f48e85e48fb1d31e73699108b (patch)
treeda72f76a97eba3dce08a93373efa4b6f87a09e64 /hw
parente57e9ae7992bde44d7938ca9a2ec0aa9c5f0bbb6 (diff)
downloadqemu-4d01b8994ca5ce7f48e85e48fb1d31e73699108b.zip
qemu-4d01b8994ca5ce7f48e85e48fb1d31e73699108b.tar.gz
qemu-4d01b8994ca5ce7f48e85e48fb1d31e73699108b.tar.bz2
microvm: add second ioapic
Create second ioapic, route virtio-mmio IRQs to it, allow more virtio-mmio devices (24 instead of 8). Needs ACPI, enabled by default, can be turned off using -machine ioapic2=off Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Sergio Lopez <slp@redhat.com> Message-id: 20201203105423.10431-8-kraxel@redhat.com
Diffstat (limited to 'hw')
-rw-r--r--hw/i386/microvm.c56
1 files changed, 51 insertions, 5 deletions
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 829b376..5688608 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -145,32 +145,53 @@ static void create_gpex(MicrovmMachineState *mms)
}
}
+static int microvm_ioapics(MicrovmMachineState *mms)
+{
+ if (!x86_machine_is_acpi_enabled(X86_MACHINE(mms))) {
+ return 1;
+ }
+ if (mms->ioapic2 == ON_OFF_AUTO_OFF) {
+ return 1;
+ }
+ return 2;
+}
+
static void microvm_devices_init(MicrovmMachineState *mms)
{
X86MachineState *x86ms = X86_MACHINE(mms);
ISABus *isa_bus;
ISADevice *rtc_state;
GSIState *gsi_state;
+ int ioapics;
int i;
/* Core components */
-
+ ioapics = microvm_ioapics(mms);
gsi_state = g_malloc0(sizeof(*gsi_state));
- x86ms->gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
+ x86ms->gsi = qemu_allocate_irqs(gsi_handler, gsi_state,
+ IOAPIC_NUM_PINS * ioapics);
isa_bus = isa_bus_new(NULL, get_system_memory(), get_system_io(),
&error_abort);
isa_bus_irqs(isa_bus, x86ms->gsi);
ioapic_init_gsi(gsi_state, "machine");
+ if (ioapics > 1) {
+ x86ms->ioapic2 = ioapic_init_secondary(gsi_state);
+ }
kvmclock_create(true);
mms->virtio_irq_base = 5;
mms->virtio_num_transports = 8;
- if (x86_machine_is_acpi_enabled(x86ms)) {
- mms->pcie_irq_base = 12;
- mms->virtio_irq_base = 16;
+ if (x86ms->ioapic2) {
+ mms->pcie_irq_base = 16; /* 16 -> 19 */
+ /* use second ioapic (24 -> 47) for virtio-mmio irq lines */
+ mms->virtio_irq_base = IO_APIC_SECONDARY_IRQBASE;
+ mms->virtio_num_transports = IOAPIC_NUM_PINS;
+ } else if (x86_machine_is_acpi_enabled(x86ms)) {
+ mms->pcie_irq_base = 12; /* 12 -> 15 */
+ mms->virtio_irq_base = 16; /* 16 -> 23 */
}
for (i = 0; i < mms->virtio_num_transports; i++) {
@@ -544,6 +565,23 @@ static void microvm_machine_set_pcie(Object *obj, Visitor *v, const char *name,
visit_type_OnOffAuto(v, name, &mms->pcie, errp);
}
+static void microvm_machine_get_ioapic2(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MicrovmMachineState *mms = MICROVM_MACHINE(obj);
+ OnOffAuto ioapic2 = mms->ioapic2;
+
+ visit_type_OnOffAuto(v, name, &ioapic2, errp);
+}
+
+static void microvm_machine_set_ioapic2(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MicrovmMachineState *mms = MICROVM_MACHINE(obj);
+
+ visit_type_OnOffAuto(v, name, &mms->ioapic2, errp);
+}
+
static bool microvm_machine_get_isa_serial(Object *obj, Error **errp)
{
MicrovmMachineState *mms = MICROVM_MACHINE(obj);
@@ -620,6 +658,7 @@ static void microvm_machine_initfn(Object *obj)
mms->pit = ON_OFF_AUTO_AUTO;
mms->rtc = ON_OFF_AUTO_AUTO;
mms->pcie = ON_OFF_AUTO_AUTO;
+ mms->ioapic2 = ON_OFF_AUTO_AUTO;
mms->isa_serial = true;
mms->option_roms = true;
mms->auto_kernel_cmdline = true;
@@ -693,6 +732,13 @@ static void microvm_class_init(ObjectClass *oc, void *data)
object_class_property_set_description(oc, MICROVM_MACHINE_PCIE,
"Enable PCIe");
+ object_class_property_add(oc, MICROVM_MACHINE_IOAPIC2, "OnOffAuto",
+ microvm_machine_get_ioapic2,
+ microvm_machine_set_ioapic2,
+ NULL, NULL);
+ object_class_property_set_description(oc, MICROVM_MACHINE_IOAPIC2,
+ "Enable second IO-APIC");
+
object_class_property_add_bool(oc, MICROVM_MACHINE_ISA_SERIAL,
microvm_machine_get_isa_serial,
microvm_machine_set_isa_serial);