Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
We need a proxy device for virtio-pmem, and this device has to be the actual memory device so we can cleanly hotplug it. Forward memory device class functions either to the actual device or use properties of the virtio-pmem device to implement these in the proxy. virtio-pmem will only be compiled for selected, supported architectures (that can deal with virtio/pci devices being memory devices). An architecture that is prepared for that can simply enable CONFIG_VIRTIO_PMEM to make it work. As not all architectures support memory devices (and CONFIG_VIRTIO_PMEM will be enabled per supported architecture), we have to move the PCI proxy to a separate file. Signed-off-by: Pankaj Gupta <pagupta@redhat.com> [ split up patches, memory-device changes, move pci proxy] Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20190619094907.10131-5-pagupta@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
- Loading branch information
Showing
4 changed files
with
167 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* | ||
* Virtio PMEM PCI device | ||
* | ||
* Copyright (C) 2018-2019 Red Hat, Inc. | ||
* | ||
* Authors: | ||
* Pankaj Gupta <pagupta@redhat.com> | ||
* David Hildenbrand <david@redhat.com> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2. | ||
* See the COPYING file in the top-level directory. | ||
*/ | ||
|
||
#include "qemu/osdep.h" | ||
|
||
#include "virtio-pmem-pci.h" | ||
#include "hw/mem/memory-device.h" | ||
#include "qapi/error.h" | ||
|
||
static void virtio_pmem_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) | ||
{ | ||
VirtIOPMEMPCI *pmem_pci = VIRTIO_PMEM_PCI(vpci_dev); | ||
DeviceState *vdev = DEVICE(&pmem_pci->vdev); | ||
|
||
qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus)); | ||
object_property_set_bool(OBJECT(vdev), true, "realized", errp); | ||
} | ||
|
||
static void virtio_pmem_pci_set_addr(MemoryDeviceState *md, uint64_t addr, | ||
Error **errp) | ||
{ | ||
object_property_set_uint(OBJECT(md), addr, VIRTIO_PMEM_ADDR_PROP, errp); | ||
} | ||
|
||
static uint64_t virtio_pmem_pci_get_addr(const MemoryDeviceState *md) | ||
{ | ||
return object_property_get_uint(OBJECT(md), VIRTIO_PMEM_ADDR_PROP, | ||
&error_abort); | ||
} | ||
|
||
static MemoryRegion *virtio_pmem_pci_get_memory_region(MemoryDeviceState *md, | ||
Error **errp) | ||
{ | ||
VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md); | ||
VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev); | ||
VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem); | ||
|
||
return vpc->get_memory_region(pmem, errp); | ||
} | ||
|
||
static uint64_t virtio_pmem_pci_get_plugged_size(const MemoryDeviceState *md, | ||
Error **errp) | ||
{ | ||
VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md); | ||
VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev); | ||
VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem); | ||
MemoryRegion *mr = vpc->get_memory_region(pmem, errp); | ||
|
||
/* the plugged size corresponds to the region size */ | ||
return mr ? 0 : memory_region_size(mr); | ||
} | ||
|
||
static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState *md, | ||
MemoryDeviceInfo *info) | ||
{ | ||
VirtioPMEMDeviceInfo *vi = g_new0(VirtioPMEMDeviceInfo, 1); | ||
VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md); | ||
VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev); | ||
VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem); | ||
DeviceState *dev = DEVICE(md); | ||
|
||
if (dev->id) { | ||
vi->has_id = true; | ||
vi->id = g_strdup(dev->id); | ||
} | ||
|
||
/* let the real device handle everything else */ | ||
vpc->fill_device_info(pmem, vi); | ||
|
||
info->u.virtio_pmem.data = vi; | ||
info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM; | ||
} | ||
|
||
static void virtio_pmem_pci_class_init(ObjectClass *klass, void *data) | ||
{ | ||
DeviceClass *dc = DEVICE_CLASS(klass); | ||
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); | ||
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); | ||
MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(klass); | ||
|
||
k->realize = virtio_pmem_pci_realize; | ||
set_bit(DEVICE_CATEGORY_MISC, dc->categories); | ||
pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; | ||
pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_PMEM; | ||
pcidev_k->revision = VIRTIO_PCI_ABI_VERSION; | ||
pcidev_k->class_id = PCI_CLASS_OTHERS; | ||
|
||
mdc->get_addr = virtio_pmem_pci_get_addr; | ||
mdc->set_addr = virtio_pmem_pci_set_addr; | ||
mdc->get_plugged_size = virtio_pmem_pci_get_plugged_size; | ||
mdc->get_memory_region = virtio_pmem_pci_get_memory_region; | ||
mdc->fill_device_info = virtio_pmem_pci_fill_device_info; | ||
} | ||
|
||
static void virtio_pmem_pci_instance_init(Object *obj) | ||
{ | ||
VirtIOPMEMPCI *dev = VIRTIO_PMEM_PCI(obj); | ||
|
||
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), | ||
TYPE_VIRTIO_PMEM); | ||
} | ||
|
||
static const VirtioPCIDeviceTypeInfo virtio_pmem_pci_info = { | ||
.base_name = TYPE_VIRTIO_PMEM_PCI, | ||
.generic_name = "virtio-pmem-pci", | ||
.transitional_name = "virtio-pmem-pci-transitional", | ||
.non_transitional_name = "virtio-pmem-pci-non-transitional", | ||
.instance_size = sizeof(VirtIOPMEMPCI), | ||
.instance_init = virtio_pmem_pci_instance_init, | ||
.class_init = virtio_pmem_pci_class_init, | ||
.interfaces = (InterfaceInfo[]) { | ||
{ TYPE_MEMORY_DEVICE }, | ||
{ } | ||
}, | ||
}; | ||
|
||
static void virtio_pmem_pci_register_types(void) | ||
{ | ||
virtio_pci_types_register(&virtio_pmem_pci_info); | ||
} | ||
type_init(virtio_pmem_pci_register_types) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Virtio PMEM PCI device | ||
* | ||
* Copyright (C) 2018-2019 Red Hat, Inc. | ||
* | ||
* Authors: | ||
* Pankaj Gupta <pagupta@redhat.com> | ||
* David Hildenbrand <david@redhat.com> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2. | ||
* See the COPYING file in the top-level directory. | ||
*/ | ||
|
||
#ifndef QEMU_VIRTIO_PMEM_PCI_H | ||
#define QEMU_VIRTIO_PMEM_PCI_H | ||
|
||
#include "hw/virtio/virtio-pci.h" | ||
#include "hw/virtio/virtio-pmem.h" | ||
|
||
typedef struct VirtIOPMEMPCI VirtIOPMEMPCI; | ||
|
||
/* | ||
* virtio-pmem-pci: This extends VirtioPCIProxy. | ||
*/ | ||
#define TYPE_VIRTIO_PMEM_PCI "virtio-pmem-pci-base" | ||
#define VIRTIO_PMEM_PCI(obj) \ | ||
OBJECT_CHECK(VirtIOPMEMPCI, (obj), TYPE_VIRTIO_PMEM_PCI) | ||
|
||
struct VirtIOPMEMPCI { | ||
VirtIOPCIProxy parent_obj; | ||
VirtIOPMEM vdev; | ||
}; | ||
|
||
#endif /* QEMU_VIRTIO_PMEM_PCI_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters