xref: /openbmc/qemu/hw/virtio/virtio-md-pci.c (revision dbdf841b)
1 /*
2  * Abstract virtio based memory device
3  *
4  * Copyright (C) 2023 Red Hat, Inc.
5  *
6  * Authors:
7  *  David Hildenbrand <david@redhat.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.
10  * See the COPYING file in the top-level directory.
11  */
12 
13 #include "qemu/osdep.h"
14 #include "hw/virtio/virtio-md-pci.h"
15 #include "hw/mem/memory-device.h"
16 #include "qapi/error.h"
17 
18 void virtio_md_pci_pre_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
19 {
20     DeviceState *dev = DEVICE(vmd);
21     HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
22     MemoryDeviceState *md = MEMORY_DEVICE(vmd);
23     Error *local_err = NULL;
24 
25     if (!bus_handler && dev->hotplugged) {
26         /*
27          * Without a bus hotplug handler, we cannot control the plug/unplug
28          * order. We should never reach this point when hotplugging on x86,
29          * however, better add a safety net.
30          */
31         error_setg(errp, "hotplug of virtio based memory devices not supported"
32                    " on this bus.");
33         return;
34     }
35     /*
36      * First, see if we can plug this memory device at all. If that
37      * succeeds, branch of to the actual hotplug handler.
38      */
39     memory_device_pre_plug(md, ms, NULL, &local_err);
40     if (!local_err && bus_handler) {
41         hotplug_handler_pre_plug(bus_handler, dev, &local_err);
42     }
43     error_propagate(errp, local_err);
44 }
45 
46 void virtio_md_pci_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
47 {
48     DeviceState *dev = DEVICE(vmd);
49     HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
50     MemoryDeviceState *md = MEMORY_DEVICE(vmd);
51     Error *local_err = NULL;
52 
53     /*
54      * Plug the memory device first and then branch off to the actual
55      * hotplug handler. If that one fails, we can easily undo the memory
56      * device bits.
57      */
58     memory_device_plug(md, ms);
59     if (bus_handler) {
60         hotplug_handler_plug(bus_handler, dev, &local_err);
61         if (local_err) {
62             memory_device_unplug(md, ms);
63         }
64     }
65     error_propagate(errp, local_err);
66 }
67 
68 void virtio_md_pci_unplug_request(VirtIOMDPCI *vmd, MachineState *ms,
69                                   Error **errp)
70 {
71     /* We don't support hot unplug of virtio based memory devices */
72     error_setg(errp, "virtio based memory devices cannot be unplugged.");
73 }
74 
75 void virtio_md_pci_unplug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
76 {
77     /* We don't support hot unplug of virtio based memory devices */
78 }
79 
80 static const TypeInfo virtio_md_pci_info = {
81     .name = TYPE_VIRTIO_MD_PCI,
82     .parent = TYPE_VIRTIO_PCI,
83     .instance_size = sizeof(VirtIOMDPCI),
84     .class_size = sizeof(VirtIOMDPCIClass),
85     .abstract = true,
86     .interfaces = (InterfaceInfo[]) {
87         { TYPE_MEMORY_DEVICE },
88         { }
89     },
90 };
91 
92 static void virtio_md_pci_register(void)
93 {
94     type_register_static(&virtio_md_pci_info);
95 }
96 type_init(virtio_md_pci_register)
97