From c10b4b3c0dcae2fe1836e534059b69e8bfce0e9f Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 17 Oct 2023 17:53:58 +0100 Subject: hw/i386/pc: support '-nic' for xen-net-device The default NIC creation seems a bit hackish to me. I don't understand why each platform has to call pci_nic_init_nofail() from a point in the code where it actually has a pointer to the PCI bus, and then we have the special cases for things like ne2k_isa. If qmp_device_add() can *find* the appropriate bus and instantiate the device on it, why can't we just do that from generic code for creating the default NICs too? But that isn't a yak I want to shave today. Add a xenbus field to the PCMachineState so that it can make its way from pc_basic_device_init() to pc_nic_init() and be handled as a special case like ne2k_isa is. Now we can launch emulated Xen guests with '-nic user'. Signed-off-by: David Woodhouse Reviewed-by: Paul Durrant --- hw/i386/pc.c | 11 ++++++++--- hw/i386/pc_piix.c | 2 +- hw/i386/pc_q35.c | 2 +- hw/xen/xen-bus.c | 4 +++- 4 files changed, 13 insertions(+), 6 deletions(-) (limited to 'hw') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 1aef21a..188bc9d 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1261,7 +1261,7 @@ void pc_basic_device_init(struct PCMachineState *pcms, if (pcms->bus) { pci_create_simple(pcms->bus, -1, "xen-platform"); } - xen_bus_init(); + pcms->xenbus = xen_bus_init(); xen_be_init(); } #endif @@ -1289,7 +1289,8 @@ void pc_basic_device_init(struct PCMachineState *pcms, pcms->vmport != ON_OFF_AUTO_ON); } -void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) +void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus, + BusState *xen_bus) { MachineClass *mc = MACHINE_CLASS(pcmc); int i; @@ -1299,7 +1300,11 @@ void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) NICInfo *nd = &nd_table[i]; const char *model = nd->model ? nd->model : mc->default_nic; - if (g_str_equal(model, "ne2k_isa")) { + if (xen_bus && (!nd->model || g_str_equal(model, "xen-net-device"))) { + DeviceState *dev = qdev_new("xen-net-device"); + qdev_set_nic_properties(dev, nd); + qdev_realize_and_unref(dev, xen_bus, &error_fatal); + } else if (g_str_equal(model, "ne2k_isa")) { pc_init_ne2k_isa(isa_bus, nd); } else { pci_nic_init_nofail(nd, pci_bus, model, NULL); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 26e161b..eace854 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -342,7 +342,7 @@ static void pc_init1(MachineState *machine, pc_basic_device_init(pcms, isa_bus, x86ms->gsi, rtc_state, true, 0x4); - pc_nic_init(pcmc, isa_bus, pci_bus); + pc_nic_init(pcmc, isa_bus, pci_bus, pcms->xenbus); if (pcmc->pci_enabled) { pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 597943f..4f3e541 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -340,7 +340,7 @@ static void pc_q35_init(MachineState *machine) /* the rest devices to which pci devfn is automatically assigned */ pc_vga_init(isa_bus, host_bus); - pc_nic_init(pcmc, isa_bus, host_bus); + pc_nic_init(pcmc, isa_bus, host_bus, pcms->xenbus); if (machine->nvdimms_state->is_enabled) { nvdimm_init_acpi_state(machine->nvdimms_state, system_io, diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index cc6f1b3..4973e7d 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -1133,11 +1133,13 @@ static void xen_register_types(void) type_init(xen_register_types) -void xen_bus_init(void) +BusState *xen_bus_init(void) { DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE); BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); qbus_set_bus_hotplug_handler(bus); + + return bus; } -- cgit v1.1