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