xref: /qemu/hw/virtio/virtio-md-pci.c (revision dbdf841b2ed8b88d30a8a1f0c26029b2ebb93e76)
118129c15SDavid Hildenbrand /*
218129c15SDavid Hildenbrand  * Abstract virtio based memory device
318129c15SDavid Hildenbrand  *
418129c15SDavid Hildenbrand  * Copyright (C) 2023 Red Hat, Inc.
518129c15SDavid Hildenbrand  *
618129c15SDavid Hildenbrand  * Authors:
718129c15SDavid Hildenbrand  *  David Hildenbrand <david@redhat.com>
818129c15SDavid Hildenbrand  *
918129c15SDavid Hildenbrand  * This work is licensed under the terms of the GNU GPL, version 2.
1018129c15SDavid Hildenbrand  * See the COPYING file in the top-level directory.
1118129c15SDavid Hildenbrand  */
1218129c15SDavid Hildenbrand 
1318129c15SDavid Hildenbrand #include "qemu/osdep.h"
1418129c15SDavid Hildenbrand #include "hw/virtio/virtio-md-pci.h"
1518129c15SDavid Hildenbrand #include "hw/mem/memory-device.h"
16*dbdf841bSDavid Hildenbrand #include "qapi/error.h"
17*dbdf841bSDavid Hildenbrand 
18*dbdf841bSDavid Hildenbrand void virtio_md_pci_pre_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
19*dbdf841bSDavid Hildenbrand {
20*dbdf841bSDavid Hildenbrand     DeviceState *dev = DEVICE(vmd);
21*dbdf841bSDavid Hildenbrand     HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
22*dbdf841bSDavid Hildenbrand     MemoryDeviceState *md = MEMORY_DEVICE(vmd);
23*dbdf841bSDavid Hildenbrand     Error *local_err = NULL;
24*dbdf841bSDavid Hildenbrand 
25*dbdf841bSDavid Hildenbrand     if (!bus_handler && dev->hotplugged) {
26*dbdf841bSDavid Hildenbrand         /*
27*dbdf841bSDavid Hildenbrand          * Without a bus hotplug handler, we cannot control the plug/unplug
28*dbdf841bSDavid Hildenbrand          * order. We should never reach this point when hotplugging on x86,
29*dbdf841bSDavid Hildenbrand          * however, better add a safety net.
30*dbdf841bSDavid Hildenbrand          */
31*dbdf841bSDavid Hildenbrand         error_setg(errp, "hotplug of virtio based memory devices not supported"
32*dbdf841bSDavid Hildenbrand                    " on this bus.");
33*dbdf841bSDavid Hildenbrand         return;
34*dbdf841bSDavid Hildenbrand     }
35*dbdf841bSDavid Hildenbrand     /*
36*dbdf841bSDavid Hildenbrand      * First, see if we can plug this memory device at all. If that
37*dbdf841bSDavid Hildenbrand      * succeeds, branch of to the actual hotplug handler.
38*dbdf841bSDavid Hildenbrand      */
39*dbdf841bSDavid Hildenbrand     memory_device_pre_plug(md, ms, NULL, &local_err);
40*dbdf841bSDavid Hildenbrand     if (!local_err && bus_handler) {
41*dbdf841bSDavid Hildenbrand         hotplug_handler_pre_plug(bus_handler, dev, &local_err);
42*dbdf841bSDavid Hildenbrand     }
43*dbdf841bSDavid Hildenbrand     error_propagate(errp, local_err);
44*dbdf841bSDavid Hildenbrand }
45*dbdf841bSDavid Hildenbrand 
46*dbdf841bSDavid Hildenbrand void virtio_md_pci_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
47*dbdf841bSDavid Hildenbrand {
48*dbdf841bSDavid Hildenbrand     DeviceState *dev = DEVICE(vmd);
49*dbdf841bSDavid Hildenbrand     HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
50*dbdf841bSDavid Hildenbrand     MemoryDeviceState *md = MEMORY_DEVICE(vmd);
51*dbdf841bSDavid Hildenbrand     Error *local_err = NULL;
52*dbdf841bSDavid Hildenbrand 
53*dbdf841bSDavid Hildenbrand     /*
54*dbdf841bSDavid Hildenbrand      * Plug the memory device first and then branch off to the actual
55*dbdf841bSDavid Hildenbrand      * hotplug handler. If that one fails, we can easily undo the memory
56*dbdf841bSDavid Hildenbrand      * device bits.
57*dbdf841bSDavid Hildenbrand      */
58*dbdf841bSDavid Hildenbrand     memory_device_plug(md, ms);
59*dbdf841bSDavid Hildenbrand     if (bus_handler) {
60*dbdf841bSDavid Hildenbrand         hotplug_handler_plug(bus_handler, dev, &local_err);
61*dbdf841bSDavid Hildenbrand         if (local_err) {
62*dbdf841bSDavid Hildenbrand             memory_device_unplug(md, ms);
63*dbdf841bSDavid Hildenbrand         }
64*dbdf841bSDavid Hildenbrand     }
65*dbdf841bSDavid Hildenbrand     error_propagate(errp, local_err);
66*dbdf841bSDavid Hildenbrand }
67*dbdf841bSDavid Hildenbrand 
68*dbdf841bSDavid Hildenbrand void virtio_md_pci_unplug_request(VirtIOMDPCI *vmd, MachineState *ms,
69*dbdf841bSDavid Hildenbrand                                   Error **errp)
70*dbdf841bSDavid Hildenbrand {
71*dbdf841bSDavid Hildenbrand     /* We don't support hot unplug of virtio based memory devices */
72*dbdf841bSDavid Hildenbrand     error_setg(errp, "virtio based memory devices cannot be unplugged.");
73*dbdf841bSDavid Hildenbrand }
74*dbdf841bSDavid Hildenbrand 
75*dbdf841bSDavid Hildenbrand void virtio_md_pci_unplug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
76*dbdf841bSDavid Hildenbrand {
77*dbdf841bSDavid Hildenbrand     /* We don't support hot unplug of virtio based memory devices */
78*dbdf841bSDavid Hildenbrand }
7918129c15SDavid Hildenbrand 
8018129c15SDavid Hildenbrand static const TypeInfo virtio_md_pci_info = {
8118129c15SDavid Hildenbrand     .name = TYPE_VIRTIO_MD_PCI,
8218129c15SDavid Hildenbrand     .parent = TYPE_VIRTIO_PCI,
8318129c15SDavid Hildenbrand     .instance_size = sizeof(VirtIOMDPCI),
8418129c15SDavid Hildenbrand     .class_size = sizeof(VirtIOMDPCIClass),
8518129c15SDavid Hildenbrand     .abstract = true,
8618129c15SDavid Hildenbrand     .interfaces = (InterfaceInfo[]) {
8718129c15SDavid Hildenbrand         { TYPE_MEMORY_DEVICE },
8818129c15SDavid Hildenbrand         { }
8918129c15SDavid Hildenbrand     },
9018129c15SDavid Hildenbrand };
9118129c15SDavid Hildenbrand 
9218129c15SDavid Hildenbrand static void virtio_md_pci_register(void)
9318129c15SDavid Hildenbrand {
9418129c15SDavid Hildenbrand     type_register_static(&virtio_md_pci_info);
9518129c15SDavid Hildenbrand }
9618129c15SDavid Hildenbrand type_init(virtio_md_pci_register)
97