diff mbox series

[RFC,v4,09/49] multi-process: setup PCI host bridge for remote device

Message ID 21b8d0f06279f177f2daca8779ced48af14139ee.1571905346.git.jag.raman@oracle.com (mailing list archive)
State New, archived
Headers show
Series Initial support of multi-process qemu | expand

Commit Message

Jag Raman Oct. 24, 2019, 9:08 a.m. UTC
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 <jag.raman@oracle.com>
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
---
 hw/pci/Makefile.objs     |  2 +-
 include/remote/pcihost.h | 59 +++++++++++++++++++++++++++++++++
 remote/Makefile.objs     |  1 +
 remote/pcihost.c         | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 146 insertions(+), 1 deletion(-)
 create mode 100644 include/remote/pcihost.h
 create mode 100644 remote/pcihost.c

Comments

Stefan Hajnoczi Nov. 13, 2019, 4:07 p.m. UTC | #1
On Thu, Oct 24, 2019 at 05:08:50AM -0400, Jagannathan Raman wrote:
> +static void remote_host_realize(DeviceState *dev, Error **errp)
> +{
> +    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
> +    RemPCIHost *s = REMOTE_HOST_DEVICE(dev);
> +
> +    /*
> +     * TODO: the name of the bus would be provided by QEMU. Use
> +     * "pcie.0" for now.
> +     */
> +    pci->bus = pci_root_bus_new(DEVICE(s), "pcie.0",
> +                                s->mr_pci_mem, s->mr_sys_io,
> +                                0, TYPE_PCIE_BUS);

The PCI bus name could be a property and then whatever instantiates
RemPCIHost could set it.

Machine types usually hardcode the name because they assume there is
only one machine instance.  In the case of mpqemu this is an okay
starting point, but maybe multiple busses will become necessary if the
device emulation process handles multiple device instances - especially
if they are served to multiple guests like in a software-defined network
switch use case.
Jag Raman Nov. 18, 2019, 3:25 p.m. UTC | #2
On 11/13/2019 11:07 AM, Stefan Hajnoczi wrote:
> On Thu, Oct 24, 2019 at 05:08:50AM -0400, Jagannathan Raman wrote:
>> +static void remote_host_realize(DeviceState *dev, Error **errp)
>> +{
>> +    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
>> +    RemPCIHost *s = REMOTE_HOST_DEVICE(dev);
>> +
>> +    /*
>> +     * TODO: the name of the bus would be provided by QEMU. Use
>> +     * "pcie.0" for now.
>> +     */
>> +    pci->bus = pci_root_bus_new(DEVICE(s), "pcie.0",
>> +                                s->mr_pci_mem, s->mr_sys_io,
>> +                                0, TYPE_PCIE_BUS);
> 
> The PCI bus name could be a property and then whatever instantiates
> RemPCIHost could set it.
> 
> Machine types usually hardcode the name because they assume there is
> only one machine instance.  In the case of mpqemu this is an okay
> starting point, but maybe multiple busses will become necessary if the
> device emulation process handles multiple device instances - especially
> if they are served to multiple guests like in a software-defined network
> switch use case.

Are you referring to a case where a single remote process will emulate
devices from multiple guests?

We haven't thought about that application. But we will certainly add the
ability to specify the name of the bus as a parameter.

Thank you very much!
--
Jag

>
Stefan Hajnoczi Nov. 21, 2019, 10:37 a.m. UTC | #3
On Mon, Nov 18, 2019 at 10:25:59AM -0500, Jag Raman wrote:
> On 11/13/2019 11:07 AM, Stefan Hajnoczi wrote:
> > On Thu, Oct 24, 2019 at 05:08:50AM -0400, Jagannathan Raman wrote:
> > > +static void remote_host_realize(DeviceState *dev, Error **errp)
> > > +{
> > > +    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
> > > +    RemPCIHost *s = REMOTE_HOST_DEVICE(dev);
> > > +
> > > +    /*
> > > +     * TODO: the name of the bus would be provided by QEMU. Use
> > > +     * "pcie.0" for now.
> > > +     */
> > > +    pci->bus = pci_root_bus_new(DEVICE(s), "pcie.0",
> > > +                                s->mr_pci_mem, s->mr_sys_io,
> > > +                                0, TYPE_PCIE_BUS);
> > 
> > The PCI bus name could be a property and then whatever instantiates
> > RemPCIHost could set it.
> > 
> > Machine types usually hardcode the name because they assume there is
> > only one machine instance.  In the case of mpqemu this is an okay
> > starting point, but maybe multiple busses will become necessary if the
> > device emulation process handles multiple device instances - especially
> > if they are served to multiple guests like in a software-defined network
> > switch use case.
> 
> Are you referring to a case where a single remote process will emulate
> devices from multiple guests?
> 
> We haven't thought about that application. But we will certainly add the
> ability to specify the name of the bus as a parameter.

Sooner or later someone will want to run multiple devices in one device
emulation process, but it's not critical to support it in this patch
series.  I think it can be implemented later without breaking any stable
interfaces.

Stefan
diff mbox series

Patch

diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs
index 955be54..90693a7 100644
--- a/hw/pci/Makefile.objs
+++ b/hw/pci/Makefile.objs
@@ -13,6 +13,6 @@  common-obj-$(CONFIG_PCI_EXPRESS) += pcie_port.o pcie_host.o
 common-obj-$(call lnot,$(CONFIG_PCI)) += pci-stub.o
 common-obj-$(CONFIG_ALL) += pci-stub.o
 
-remote-pci-obj-$(CONFIG_MPQEMU) += pci.o pci_bridge.o
+remote-pci-obj-$(CONFIG_MPQEMU) += pci.o pci_bridge.o pci_host.o pcie_host.o
 remote-pci-obj-$(CONFIG_MPQEMU) += msi.o msix.o
 remote-pci-obj-$(CONFIG_MPQEMU) += pcie.o
diff --git a/include/remote/pcihost.h b/include/remote/pcihost.h
new file mode 100644
index 0000000..b3c711d
--- /dev/null
+++ b/include/remote/pcihost.h
@@ -0,0 +1,59 @@ 
+/*
+ * PCI Host for remote device
+ *
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef REMOTE_PCIHOST_H
+#define REMOTE_PCIHOST_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "exec/memory.h"
+#include "hw/pci/pcie_host.h"
+
+#define TYPE_REMOTE_HOST_DEVICE "remote-pcihost"
+#define REMOTE_HOST_DEVICE(obj) \
+    OBJECT_CHECK(RemPCIHost, (obj), TYPE_REMOTE_HOST_DEVICE)
+
+typedef struct RemPCIHost {
+    /*< private >*/
+    PCIExpressHost parent_obj;
+    /*< public >*/
+
+    /*
+     * Memory Controller Hub (MCH) may not be necessary for the emulation
+     * program. The two important reasons for implementing a PCI host in the
+     * emulation program are:
+     * - Provide a PCI bus for IO devices
+     * - Enable translation of guest PA to the PCI bar regions
+     *
+     * For both the above mentioned purposes, it doesn't look like we would
+     * need the MCH
+     */
+
+    MemoryRegion *mr_pci_mem;
+    MemoryRegion *mr_sys_mem;
+    MemoryRegion *mr_sys_io;
+} RemPCIHost;
+
+#endif
diff --git a/remote/Makefile.objs b/remote/Makefile.objs
index a9b2256..2757f5a 100644
--- a/remote/Makefile.objs
+++ b/remote/Makefile.objs
@@ -1 +1,2 @@ 
 remote-pci-obj-$(CONFIG_MPQEMU) += remote-main.o
+remote-pci-obj-$(CONFIG_MPQEMU) += pcihost.o
diff --git a/remote/pcihost.c b/remote/pcihost.c
new file mode 100644
index 0000000..0f43057
--- /dev/null
+++ b/remote/pcihost.c
@@ -0,0 +1,85 @@ 
+/*
+ * Remote PCI host device
+ *
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include "qemu/osdep.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/qdev-properties.h"
+#include "remote/pcihost.h"
+#include "exec/memory.h"
+
+static const char *remote_host_root_bus_path(PCIHostState *host_bridge,
+                                             PCIBus *rootbus)
+{
+    return "0000:00";
+}
+
+static void remote_host_realize(DeviceState *dev, Error **errp)
+{
+    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
+    RemPCIHost *s = REMOTE_HOST_DEVICE(dev);
+
+    /*
+     * TODO: the name of the bus would be provided by QEMU. Use
+     * "pcie.0" for now.
+     */
+    pci->bus = pci_root_bus_new(DEVICE(s), "pcie.0",
+                                s->mr_pci_mem, s->mr_sys_io,
+                                0, TYPE_PCIE_BUS);
+}
+
+static Property remote_host_props[] = {
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void remote_host_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
+
+    hc->root_bus_path = remote_host_root_bus_path;
+    dc->realize = remote_host_realize;
+    dc->props = remote_host_props;
+
+    dc->user_creatable = false;
+    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+    dc->fw_name = "pci";
+}
+
+static const TypeInfo remote_host_info = {
+    .name = TYPE_REMOTE_HOST_DEVICE,
+    .parent = TYPE_PCIE_HOST_BRIDGE,
+    .instance_size = sizeof(RemPCIHost),
+    .class_init = remote_host_class_init,
+};
+
+static void remote_machine_register(void)
+{
+    type_register_static(&remote_host_info);
+}
+
+type_init(remote_machine_register)