summaryrefslogtreecommitdiffstats
path: root/hw/remote/machine.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/remote/machine.c')
-rw-r--r--hw/remote/machine.c88
1 files changed, 85 insertions, 3 deletions
diff --git a/hw/remote/machine.c b/hw/remote/machine.c
index 92d71d47bb..75d550daae 100644
--- a/hw/remote/machine.c
+++ b/hw/remote/machine.c
@@ -20,6 +20,11 @@
#include "qapi/error.h"
#include "hw/pci/pci_host.h"
#include "hw/remote/iohub.h"
+#include "hw/remote/iommu.h"
+#include "hw/qdev-core.h"
+#include "hw/remote/iommu.h"
+#include "hw/remote/vfio-user-obj.h"
+#include "hw/pci/msi.h"
static void remote_machine_init(MachineState *machine)
{
@@ -49,25 +54,102 @@ static void remote_machine_init(MachineState *machine)
pci_host = PCI_HOST_BRIDGE(rem_host);
- remote_iohub_init(&s->iohub);
+ if (s->vfio_user) {
+ remote_iommu_setup(pci_host->bus);
- pci_bus_irqs(pci_host->bus, remote_iohub_set_irq, remote_iohub_map_irq,
- &s->iohub, REMOTE_IOHUB_NB_PIRQS);
+ msi_nonbroken = true;
+
+ vfu_object_set_bus_irq(pci_host->bus);
+ } else {
+ remote_iohub_init(&s->iohub);
+
+ pci_bus_irqs(pci_host->bus, remote_iohub_set_irq, remote_iohub_map_irq,
+ &s->iohub, REMOTE_IOHUB_NB_PIRQS);
+ }
+
+ qbus_set_hotplug_handler(BUS(pci_host->bus), OBJECT(s));
+}
+
+static bool remote_machine_get_vfio_user(Object *obj, Error **errp)
+{
+ RemoteMachineState *s = REMOTE_MACHINE(obj);
+
+ return s->vfio_user;
+}
+
+static void remote_machine_set_vfio_user(Object *obj, bool value, Error **errp)
+{
+ RemoteMachineState *s = REMOTE_MACHINE(obj);
+
+ if (phase_check(PHASE_MACHINE_CREATED)) {
+ error_setg(errp, "Error enabling vfio-user - machine already created");
+ return;
+ }
+
+ s->vfio_user = value;
+}
+
+static bool remote_machine_get_auto_shutdown(Object *obj, Error **errp)
+{
+ RemoteMachineState *s = REMOTE_MACHINE(obj);
+
+ return s->auto_shutdown;
+}
+
+static void remote_machine_set_auto_shutdown(Object *obj, bool value,
+ Error **errp)
+{
+ RemoteMachineState *s = REMOTE_MACHINE(obj);
+
+ s->auto_shutdown = value;
+}
+
+static void remote_machine_instance_init(Object *obj)
+{
+ RemoteMachineState *s = REMOTE_MACHINE(obj);
+
+ s->auto_shutdown = true;
+}
+
+static void remote_machine_dev_unplug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ qdev_unrealize(dev);
+
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+ remote_iommu_unplug_dev(PCI_DEVICE(dev));
+ }
}
static void remote_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
mc->init = remote_machine_init;
mc->desc = "Experimental remote machine";
+
+ hc->unplug = remote_machine_dev_unplug_cb;
+
+ object_class_property_add_bool(oc, "vfio-user",
+ remote_machine_get_vfio_user,
+ remote_machine_set_vfio_user);
+
+ object_class_property_add_bool(oc, "auto-shutdown",
+ remote_machine_get_auto_shutdown,
+ remote_machine_set_auto_shutdown);
}
static const TypeInfo remote_machine = {
.name = TYPE_REMOTE_MACHINE,
.parent = TYPE_MACHINE,
.instance_size = sizeof(RemoteMachineState),
+ .instance_init = remote_machine_instance_init,
.class_init = remote_machine_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
};
static void remote_machine_register_types(void)