From: Jagannathan Raman Date: Fri, 29 Jan 2021 16:46:06 +0000 (-0500) Subject: multi-process: setup PCI host bridge for remote device X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=6fbd84d63299b86e2a60ee7f257838d411112b87;p=qmiga%2Fqemu.git multi-process: setup PCI host bridge for remote device PCI host bridge is setup for the remote device process. It is implemented using remote-pcihost object. It is an extension of the PCI host bridge setup by QEMU. Remote-pcihost configures a PCI bus which could be used by the remote PCI device to latch on to. Signed-off-by: Jagannathan Raman Signed-off-by: John G Johnson Signed-off-by: Elena Ufimtseva Reviewed-by: Stefan Hajnoczi Message-id: 0871ba857abb2eafacde07e7fe66a3f12415bfb2.1611938319.git.jag.raman@oracle.com [Added PCI_EXPRESS condition in hw/remote/Kconfig since remote-pcihost needs PCIe. This solves "make check" failure on s390x. Fix suggested by Philippe Mathieu-Daudé and Thomas Huth . --Stefan] Signed-off-by: Stefan Hajnoczi --- diff --git a/MAINTAINERS b/MAINTAINERS index 1658397762..4a19e20815 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3207,6 +3207,8 @@ M: John G Johnson S: Maintained F: docs/devel/multi-process.rst F: docs/system/multi-process.rst +F: hw/pci-host/remote.c +F: include/hw/pci-host/remote.h Build and test automation ------------------------- diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig index eb03f0489d..8b8c763c28 100644 --- a/hw/pci-host/Kconfig +++ b/hw/pci-host/Kconfig @@ -65,3 +65,6 @@ config PCI_POWERNV select PCI_EXPRESS select MSI_NONBROKEN select PCIE_PORT + +config REMOTE_PCIHOST + bool diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build index da9d1a9964..1847c69905 100644 --- a/hw/pci-host/meson.build +++ b/hw/pci-host/meson.build @@ -9,6 +9,7 @@ pci_ss.add(when: 'CONFIG_PCI_EXPRESS_XILINX', if_true: files('xilinx-pcie.c')) pci_ss.add(when: 'CONFIG_PCI_I440FX', if_true: files('i440fx.c')) pci_ss.add(when: 'CONFIG_PCI_SABRE', if_true: files('sabre.c')) pci_ss.add(when: 'CONFIG_XEN_IGD_PASSTHROUGH', if_true: files('xen_igd_pt.c')) +pci_ss.add(when: 'CONFIG_REMOTE_PCIHOST', if_true: files('remote.c')) # PPC devices pci_ss.add(when: 'CONFIG_PREP_PCI', if_true: files('prep.c')) diff --git a/hw/pci-host/remote.c b/hw/pci-host/remote.c new file mode 100644 index 0000000000..eee45444ef --- /dev/null +++ b/hw/pci-host/remote.c @@ -0,0 +1,75 @@ +/* + * Remote PCI host device + * + * Unlike PCI host devices that model physical hardware, the purpose + * of this PCI host is to host multi-process QEMU devices. + * + * Multi-process QEMU extends the PCI host of a QEMU machine into a + * remote process. Any PCI device attached to the remote process is + * visible in the QEMU guest. This allows existing QEMU device models + * to be reused in the remote process. + * + * This PCI host is purely a container for PCI devices. It's fake in the + * sense that the guest never sees this PCI host and has no way of + * accessing it. Its job is just to provide the environment that QEMU + * PCI device models need when running in a remote process. + * + * Copyright © 2018, 2021 Oracle and/or its affiliates. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" + +#include "hw/pci/pci.h" +#include "hw/pci/pci_host.h" +#include "hw/pci/pcie_host.h" +#include "hw/qdev-properties.h" +#include "hw/pci-host/remote.h" +#include "exec/memory.h" + +static const char *remote_pcihost_root_bus_path(PCIHostState *host_bridge, + PCIBus *rootbus) +{ + return "0000:00"; +} + +static void remote_pcihost_realize(DeviceState *dev, Error **errp) +{ + PCIHostState *pci = PCI_HOST_BRIDGE(dev); + RemotePCIHost *s = REMOTE_PCIHOST(dev); + + pci->bus = pci_root_bus_new(DEVICE(s), "remote-pci", + s->mr_pci_mem, s->mr_sys_io, + 0, TYPE_PCIE_BUS); +} + +static void remote_pcihost_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); + + hc->root_bus_path = remote_pcihost_root_bus_path; + dc->realize = remote_pcihost_realize; + + dc->user_creatable = false; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->fw_name = "pci"; +} + +static const TypeInfo remote_pcihost_info = { + .name = TYPE_REMOTE_PCIHOST, + .parent = TYPE_PCIE_HOST_BRIDGE, + .instance_size = sizeof(RemotePCIHost), + .class_init = remote_pcihost_class_init, +}; + +static void remote_pcihost_register(void) +{ + type_register_static(&remote_pcihost_info); +} + +type_init(remote_pcihost_register) diff --git a/hw/remote/Kconfig b/hw/remote/Kconfig index 54844467a0..08c16e235f 100644 --- a/hw/remote/Kconfig +++ b/hw/remote/Kconfig @@ -1,3 +1,4 @@ config MULTIPROCESS bool - depends on PCI && KVM + depends on PCI && PCI_EXPRESS && KVM + select REMOTE_PCIHOST diff --git a/include/hw/pci-host/remote.h b/include/hw/pci-host/remote.h new file mode 100644 index 0000000000..06b8a83a4b --- /dev/null +++ b/include/hw/pci-host/remote.h @@ -0,0 +1,29 @@ +/* + * PCI Host for remote device + * + * Copyright © 2018, 2021 Oracle and/or its affiliates. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef REMOTE_PCIHOST_H +#define REMOTE_PCIHOST_H + +#include "exec/memory.h" +#include "hw/pci/pcie_host.h" + +#define TYPE_REMOTE_PCIHOST "remote-pcihost" +OBJECT_DECLARE_SIMPLE_TYPE(RemotePCIHost, REMOTE_PCIHOST) + +struct RemotePCIHost { + /*< private >*/ + PCIExpressHost parent_obj; + /*< public >*/ + + MemoryRegion *mr_pci_mem; + MemoryRegion *mr_sys_io; +}; + +#endif