pc: Support for virtio-pmem-pci
Override the device hotplug handler to properly handle the memory device part via virtio-pmem-pci callbacks from the machine hotplug handler and forward to the actual PCI bus hotplug handler. As PCI hotplug has not been properly factored out into hotplug handlers, most magic is performed in the (un)realize functions. Also some PCI host buses don't have a PCI hotplug handler at all yet, just to be sure that we alway have a hotplug handler on x86, add a simple error check. Unlocking virtio-pmem will unlock virtio-pmem-pci. Signed-off-by: David Hildenbrand <david@redhat.com> [ Disable virtio-pmem hotunplug ] Signed-off-by: Pankaj Gupta <pagupta@redhat.com> Message-Id: <20190619094907.10131-8-pagupta@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
cae02c3480
commit
a0a49813f7
@ -30,6 +30,7 @@ config PC
|
||||
# For ACPI builder:
|
||||
select SERIAL_ISA
|
||||
select ACPI_VMGENID
|
||||
select VIRTIO_PMEM_SUPPORTED
|
||||
|
||||
config PC_PCI
|
||||
bool
|
||||
|
72
hw/i386/pc.c
72
hw/i386/pc.c
@ -79,6 +79,8 @@
|
||||
#include "hw/i386/intel_iommu.h"
|
||||
#include "hw/net/ne2000-isa.h"
|
||||
#include "standard-headers/asm-x86/bootparam.h"
|
||||
#include "hw/virtio/virtio-pmem-pci.h"
|
||||
#include "hw/mem/memory-device.h"
|
||||
|
||||
/* debug PC/ISA interrupts */
|
||||
//#define DEBUG_IRQ
|
||||
@ -2395,6 +2397,65 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
numa_cpu_pre_plug(cpu_slot, dev, errp);
|
||||
}
|
||||
|
||||
static void pc_virtio_pmem_pci_pre_plug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (!hotplug_dev2) {
|
||||
/*
|
||||
* Without a bus hotplug handler, we cannot control the plug/unplug
|
||||
* order. This should never be the case on x86, however better add
|
||||
* a safety net.
|
||||
*/
|
||||
error_setg(errp, "virtio-pmem-pci not supported on this bus.");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* First, see if we can plug this memory device at all. If that
|
||||
* succeeds, branch of to the actual hotplug handler.
|
||||
*/
|
||||
memory_device_pre_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev), NULL,
|
||||
&local_err);
|
||||
if (!local_err) {
|
||||
hotplug_handler_pre_plug(hotplug_dev2, dev, &local_err);
|
||||
}
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
static void pc_virtio_pmem_pci_plug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
/*
|
||||
* Plug the memory device first and then branch off to the actual
|
||||
* hotplug handler. If that one fails, we can easily undo the memory
|
||||
* device bits.
|
||||
*/
|
||||
memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
|
||||
hotplug_handler_plug(hotplug_dev2, dev, &local_err);
|
||||
if (local_err) {
|
||||
memory_device_unplug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
|
||||
}
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
static void pc_virtio_pmem_pci_unplug_request(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
/* We don't support virtio pmem hot unplug */
|
||||
error_setg(errp, "virtio pmem device unplug not supported.");
|
||||
}
|
||||
|
||||
static void pc_virtio_pmem_pci_unplug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
/* We don't support virtio pmem hot unplug */
|
||||
}
|
||||
|
||||
static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
@ -2402,6 +2463,8 @@ static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
|
||||
pc_memory_pre_plug(hotplug_dev, dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
pc_cpu_pre_plug(hotplug_dev, dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI)) {
|
||||
pc_virtio_pmem_pci_pre_plug(hotplug_dev, dev, errp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2412,6 +2475,8 @@ static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||
pc_memory_plug(hotplug_dev, dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
pc_cpu_plug(hotplug_dev, dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI)) {
|
||||
pc_virtio_pmem_pci_plug(hotplug_dev, dev, errp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2422,6 +2487,8 @@ static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
pc_memory_unplug_request(hotplug_dev, dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
pc_cpu_unplug_request_cb(hotplug_dev, dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI)) {
|
||||
pc_virtio_pmem_pci_unplug_request(hotplug_dev, dev, errp);
|
||||
} else {
|
||||
error_setg(errp, "acpi: device unplug request for not supported device"
|
||||
" type: %s", object_get_typename(OBJECT(dev)));
|
||||
@ -2435,6 +2502,8 @@ static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
|
||||
pc_memory_unplug(hotplug_dev, dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
pc_cpu_unplug_cb(hotplug_dev, dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI)) {
|
||||
pc_virtio_pmem_pci_unplug(hotplug_dev, dev, errp);
|
||||
} else {
|
||||
error_setg(errp, "acpi: device unplug for not supported device"
|
||||
" type: %s", object_get_typename(OBJECT(dev)));
|
||||
@ -2445,7 +2514,8 @@ static HotplugHandler *pc_get_hotplug_handler(MachineState *machine,
|
||||
DeviceState *dev)
|
||||
{
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
|
||||
object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
object_dynamic_cast(OBJECT(dev), TYPE_CPU) ||
|
||||
object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI)) {
|
||||
return HOTPLUG_HANDLER(machine);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user