* [Qemu-devel] [PATCH 1/7] virtio-pmem: add virtio device
2019-05-23 10:24 [Qemu-devel] [PATCH 0/7] Qemu virtio pmem device Pankaj Gupta
@ 2019-05-23 10:24 ` Pankaj Gupta
2019-05-23 13:21 ` Eric Blake
2019-06-04 13:15 ` Cornelia Huck
2019-05-23 10:24 ` [Qemu-devel] [PATCH 2/7] virtio-pci: Allow to specify additional interfaces for the base type Pankaj Gupta
` (5 subsequent siblings)
6 siblings, 2 replies; 12+ messages in thread
From: Pankaj Gupta @ 2019-05-23 10:24 UTC (permalink / raw)
To: qemu-devel
Cc: kwolf, aarcange, cohuck, xiaoguangrong.eric, mst, pagupta, riel,
david, armbru, ehabkost, lcapitulino, stefanha, pbonzini,
imammedo, dan.j.williams, nilal, dgilbert, rth
This is the implementation of virtio-pmem device. Support will require
machine changes for the architectures that will support it, so it will
not yet be compiled. It can be unlocked with VIRTIO_PMEM_SUPPORTED per
machine and disabled globally via VIRTIO_PMEM.
We cannot use the "addr" property as that is already used e.g. for
virtio-pci/pci devices. And we will have e.g. virtio-pmem-pci as a proxy.
So we have to choose a different one (unfortunately). "memaddr" it is.
That name should ideally be used by all other virtio-* based memory
devices in the future.
-device virtio-pmem-pci,id=p0,bus=bux0,addr=0x01,memaddr=0x1000000...
Acked-by: Markus Armbruster <armbru@redhat.com>
[ QAPI bits ]
Signed-off-by: Pankaj Gupta <pagupta@redhat.com>
[ MemoryDevice/MemoryRegion changes, cleanups, addr property "memaddr",
split up patches, unplug handler ]
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/virtio/Kconfig | 10 +++
hw/virtio/Makefile.objs | 1 +
hw/virtio/virtio-pmem.c | 190 ++++++++++++++++++++++++++++++++++++++++
include/hw/virtio/virtio-pmem.h | 49 +++++++++++
qapi/misc.json | 28 +++++-
5 files changed, 277 insertions(+), 1 deletion(-)
create mode 100644 hw/virtio/virtio-pmem.c
create mode 100644 include/hw/virtio/virtio-pmem.h
diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index e0452de4ba..3724ff8bac 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -29,3 +29,13 @@ config VIRTIO_CRYPTO
bool
default y
depends on VIRTIO
+
+config VIRTIO_PMEM_SUPPORTED
+ bool
+
+config VIRTIO_PMEM
+ bool
+ default y
+ depends on VIRTIO
+ depends on VIRTIO_PMEM_SUPPORTED
+ select MEM_DEVICE
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index f2ab667a21..a5bdbb16aa 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -12,6 +12,7 @@ common-obj-$(CONFIG_VIRTIO_MMIO) += virtio-mmio.o
obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
obj-$(call land,$(CONFIG_VIRTIO_CRYPTO),$(CONFIG_VIRTIO_PCI)) += virtio-crypto-pci.o
+obj-$(CONFIG_VIRTIO_PMEM) += virtio-pmem.o
obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
ifeq ($(CONFIG_VIRTIO_PCI),y)
diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c
new file mode 100644
index 0000000000..c462d2c942
--- /dev/null
+++ b/hw/virtio/virtio-pmem.c
@@ -0,0 +1,190 @@
+/*
+ * Virtio PMEM 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 "qapi/error.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "hw/virtio/virtio-pmem.h"
+#include "hw/virtio/virtio-access.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_pmem.h"
+#include "block/aio.h"
+#include "block/thread-pool.h"
+
+typedef struct VirtIODeviceRequest {
+ VirtQueueElement elem;
+ int fd;
+ VirtIOPMEM *pmem;
+ VirtIODevice *vdev;
+ struct virtio_pmem_req req;
+ struct virtio_pmem_resp resp;
+} VirtIODeviceRequest;
+
+static int worker_cb(void *opaque)
+{
+ VirtIODeviceRequest *req_data = opaque;
+ int err = 0;
+
+ /* flush raw backing image */
+ err = fsync(req_data->fd);
+ if (err != 0) {
+ err = 1;
+ }
+
+ virtio_stw_p(req_data->vdev, &req_data->resp.ret, err);
+
+ return 0;
+}
+
+static void done_cb(void *opaque, int ret)
+{
+ VirtIODeviceRequest *req_data = opaque;
+ int len = iov_from_buf(req_data->elem.in_sg, req_data->elem.in_num, 0,
+ &req_data->resp, sizeof(struct virtio_pmem_resp));
+
+ /* Callbacks are serialized, so no need to use atomic ops. */
+ virtqueue_push(req_data->pmem->rq_vq, &req_data->elem, len);
+ virtio_notify((VirtIODevice *)req_data->pmem, req_data->pmem->rq_vq);
+ g_free(req_data);
+}
+
+static void virtio_pmem_flush(VirtIODevice *vdev, VirtQueue *vq)
+{
+ VirtIODeviceRequest *req_data;
+ VirtIOPMEM *pmem = VIRTIO_PMEM(vdev);
+ HostMemoryBackend *backend = MEMORY_BACKEND(pmem->memdev);
+ ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());
+
+ req_data = virtqueue_pop(vq, sizeof(VirtIODeviceRequest));
+ if (!req_data) {
+ virtio_error(vdev, "virtio-pmem missing request data");
+ return;
+ }
+
+ if (req_data->elem.out_num < 1 || req_data->elem.in_num < 1) {
+ virtio_error(vdev, "virtio-pmem request not proper");
+ g_free(req_data);
+ return;
+ }
+ req_data->fd = memory_region_get_fd(&backend->mr);
+ req_data->pmem = pmem;
+ req_data->vdev = vdev;
+ thread_pool_submit_aio(pool, worker_cb, req_data, done_cb, req_data);
+}
+
+static void virtio_pmem_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+ VirtIOPMEM *pmem = VIRTIO_PMEM(vdev);
+ struct virtio_pmem_config *pmemcfg = (struct virtio_pmem_config *) config;
+
+ virtio_stq_p(vdev, &pmemcfg->start, pmem->start);
+ virtio_stq_p(vdev, &pmemcfg->size, memory_region_size(&pmem->memdev->mr));
+}
+
+static uint64_t virtio_pmem_get_features(VirtIODevice *vdev, uint64_t features,
+ Error **errp)
+{
+ return features;
+}
+
+static void virtio_pmem_realize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VirtIOPMEM *pmem = VIRTIO_PMEM(dev);
+
+ if (!pmem->memdev) {
+ error_setg(errp, "virtio-pmem memdev not set");
+ return;
+ }
+
+ if (host_memory_backend_is_mapped(pmem->memdev)) {
+ char *path = object_get_canonical_path_component(OBJECT(pmem->memdev));
+ error_setg(errp, "can't use already busy memdev: %s", path);
+ g_free(path);
+ return;
+ }
+
+ host_memory_backend_set_mapped(pmem->memdev, true);
+ virtio_init(vdev, TYPE_VIRTIO_PMEM, VIRTIO_ID_PMEM,
+ sizeof(struct virtio_pmem_config));
+ pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush);
+}
+
+static void virtio_pmem_unrealize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VirtIOPMEM *pmem = VIRTIO_PMEM(dev);
+
+ host_memory_backend_set_mapped(pmem->memdev, false);
+ pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush);
+ virtio_cleanup(vdev);
+}
+
+static void virtio_pmem_fill_device_info(const VirtIOPMEM *pmem,
+ VirtioPMEMDeviceInfo *vi)
+{
+ vi->memaddr = pmem->start;
+ vi->size = pmem->memdev ? memory_region_size(&pmem->memdev->mr) : 0;
+ vi->memdev = object_get_canonical_path(OBJECT(pmem->memdev));
+}
+
+static MemoryRegion *virtio_pmem_get_memory_region(VirtIOPMEM *pmem,
+ Error **errp)
+{
+ if (!pmem->memdev) {
+ error_setg(errp, "'%s' property must be set", VIRTIO_PMEM_MEMDEV_PROP);
+ return NULL;
+ }
+
+ return &pmem->memdev->mr;
+}
+
+static Property virtio_pmem_properties[] = {
+ DEFINE_PROP_UINT64(VIRTIO_PMEM_ADDR_PROP, VirtIOPMEM, start, 0),
+ DEFINE_PROP_LINK(VIRTIO_PMEM_MEMDEV_PROP, VirtIOPMEM, memdev,
+ TYPE_MEMORY_BACKEND, HostMemoryBackend *),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_pmem_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+ VirtIOPMEMClass *vpc = VIRTIO_PMEM_CLASS(klass);
+
+ dc->props = virtio_pmem_properties;
+
+ vdc->realize = virtio_pmem_realize;
+ vdc->unrealize = virtio_pmem_unrealize;
+ vdc->get_config = virtio_pmem_get_config;
+ vdc->get_features = virtio_pmem_get_features;
+
+ vpc->fill_device_info = virtio_pmem_fill_device_info;
+ vpc->get_memory_region = virtio_pmem_get_memory_region;
+}
+
+static TypeInfo virtio_pmem_info = {
+ .name = TYPE_VIRTIO_PMEM,
+ .parent = TYPE_VIRTIO_DEVICE,
+ .class_size = sizeof(VirtIOPMEMClass),
+ .class_init = virtio_pmem_class_init,
+ .instance_size = sizeof(VirtIOPMEM),
+};
+
+static void virtio_register_types(void)
+{
+ type_register_static(&virtio_pmem_info);
+}
+
+type_init(virtio_register_types)
diff --git a/include/hw/virtio/virtio-pmem.h b/include/hw/virtio/virtio-pmem.h
new file mode 100644
index 0000000000..19b6ee6d75
--- /dev/null
+++ b/include/hw/virtio/virtio-pmem.h
@@ -0,0 +1,49 @@
+/*
+ * Virtio PMEM 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 HW_VIRTIO_PMEM_H
+#define HW_VIRTIO_PMEM_H
+
+#include "hw/virtio/virtio.h"
+#include "sysemu/hostmem.h"
+
+#define TYPE_VIRTIO_PMEM "virtio-pmem"
+
+#define VIRTIO_PMEM(obj) \
+ OBJECT_CHECK(VirtIOPMEM, (obj), TYPE_VIRTIO_PMEM)
+#define VIRTIO_PMEM_CLASS(oc) \
+ OBJECT_CLASS_CHECK(VirtIOPMEMClass, (oc), TYPE_VIRTIO_PMEM)
+#define VIRTIO_PMEM_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(VirtIOPMEMClass, (obj), TYPE_VIRTIO_PMEM)
+
+#define VIRTIO_PMEM_ADDR_PROP "memaddr"
+#define VIRTIO_PMEM_MEMDEV_PROP "memdev"
+
+typedef struct VirtIOPMEM {
+ VirtIODevice parent_obj;
+
+ VirtQueue *rq_vq;
+ uint64_t start;
+ HostMemoryBackend *memdev;
+} VirtIOPMEM;
+
+typedef struct VirtIOPMEMClass {
+ /* private */
+ VirtIODevice parent;
+
+ /* public */
+ void (*fill_device_info)(const VirtIOPMEM *pmem, VirtioPMEMDeviceInfo *vi);
+ MemoryRegion *(*get_memory_region)(VirtIOPMEM *pmem, Error **errp);
+} VirtIOPMEMClass;
+
+#endif
diff --git a/qapi/misc.json b/qapi/misc.json
index 8b3ca4fdd3..605c347003 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -2742,16 +2742,42 @@
}
}
+##
+# @VirtioPMEMDeviceInfo:
+#
+# VirtioPMEM state information
+#
+# @id: device's ID
+#
+# @memaddr: physical address in memory, where device is mapped
+#
+# @size: size of memory that the device provides
+#
+# @memdev: memory backend linked with device
+#
+# Since: 4.0
+##
+{ 'struct': 'VirtioPMEMDeviceInfo',
+ 'data': { '*id': 'str',
+ 'memaddr': 'size',
+ 'size': 'size',
+ 'memdev': 'str'
+ }
+}
+
##
# @MemoryDeviceInfo:
#
# Union containing information about a memory device
#
+# nvdimm is included since 2.12. virtio-pmem is included since 4.0.
+#
# Since: 2.1
##
{ 'union': 'MemoryDeviceInfo',
'data': { 'dimm': 'PCDIMMDeviceInfo',
- 'nvdimm': 'PCDIMMDeviceInfo'
+ 'nvdimm': 'PCDIMMDeviceInfo',
+ 'virtio-pmem': 'VirtioPMEMDeviceInfo'
}
}
--
2.14.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH 1/7] virtio-pmem: add virtio device
2019-05-23 10:24 ` [Qemu-devel] [PATCH 1/7] virtio-pmem: add virtio device Pankaj Gupta
@ 2019-05-23 13:21 ` Eric Blake
2019-05-24 6:01 ` Pankaj Gupta
2019-06-04 13:15 ` Cornelia Huck
1 sibling, 1 reply; 12+ messages in thread
From: Eric Blake @ 2019-05-23 13:21 UTC (permalink / raw)
To: Pankaj Gupta, qemu-devel
Cc: kwolf, aarcange, cohuck, xiaoguangrong.eric, mst, riel, david,
armbru, ehabkost, lcapitulino, stefanha, pbonzini, imammedo,
dan.j.williams, nilal, dgilbert, rth
[-- Attachment #1: Type: text/plain, Size: 2331 bytes --]
On 5/23/19 5:24 AM, Pankaj Gupta wrote:
> This is the implementation of virtio-pmem device. Support will require
> machine changes for the architectures that will support it, so it will
> not yet be compiled. It can be unlocked with VIRTIO_PMEM_SUPPORTED per
> machine and disabled globally via VIRTIO_PMEM.
>
> We cannot use the "addr" property as that is already used e.g. for
> virtio-pci/pci devices. And we will have e.g. virtio-pmem-pci as a proxy.
> So we have to choose a different one (unfortunately). "memaddr" it is.
> That name should ideally be used by all other virtio-* based memory
> devices in the future.
> -device virtio-pmem-pci,id=p0,bus=bux0,addr=0x01,memaddr=0x1000000...
>
> Acked-by: Markus Armbruster <armbru@redhat.com>
> [ QAPI bits ]
> Signed-off-by: Pankaj Gupta <pagupta@redhat.com>
> [ MemoryDevice/MemoryRegion changes, cleanups, addr property "memaddr",
> split up patches, unplug handler ]
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
> +++ b/qapi/misc.json
> @@ -2742,16 +2742,42 @@
> }
> }
>
> +##
> +# @VirtioPMEMDeviceInfo:
> +#
> +# VirtioPMEM state information
> +#
> +# @id: device's ID
> +#
> +# @memaddr: physical address in memory, where device is mapped
> +#
> +# @size: size of memory that the device provides
> +#
> +# @memdev: memory backend linked with device
> +#
> +# Since: 4.0
You've missed 4.0; this should be 4.1.
> +##
> +{ 'struct': 'VirtioPMEMDeviceInfo',
> + 'data': { '*id': 'str',
Why is id optional? Does it make sense to have a device without an id?
> + 'memaddr': 'size',
> + 'size': 'size',
> + 'memdev': 'str'
> + }
> +}
> +
> ##
> # @MemoryDeviceInfo:
> #
> # Union containing information about a memory device
> #
> +# nvdimm is included since 2.12. virtio-pmem is included since 4.0.
4.1
> +#
> # Since: 2.1
> ##
> { 'union': 'MemoryDeviceInfo',
> 'data': { 'dimm': 'PCDIMMDeviceInfo',
> - 'nvdimm': 'PCDIMMDeviceInfo'
> + 'nvdimm': 'PCDIMMDeviceInfo',
> + 'virtio-pmem': 'VirtioPMEMDeviceInfo'
> }
> }
>
>
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization: qemu.org | libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH 1/7] virtio-pmem: add virtio device
2019-05-23 13:21 ` Eric Blake
@ 2019-05-24 6:01 ` Pankaj Gupta
0 siblings, 0 replies; 12+ messages in thread
From: Pankaj Gupta @ 2019-05-24 6:01 UTC (permalink / raw)
To: Eric Blake
Cc: kwolf, aarcange, cohuck, xiaoguangrong eric, mst, armbru, riel,
david, qemu-devel, ehabkost, lcapitulino, stefanha, pbonzini,
imammedo, dan j williams, nilal, dgilbert, rth
>
> On 5/23/19 5:24 AM, Pankaj Gupta wrote:
> > This is the implementation of virtio-pmem device. Support will require
> > machine changes for the architectures that will support it, so it will
> > not yet be compiled. It can be unlocked with VIRTIO_PMEM_SUPPORTED per
> > machine and disabled globally via VIRTIO_PMEM.
> >
> > We cannot use the "addr" property as that is already used e.g. for
> > virtio-pci/pci devices. And we will have e.g. virtio-pmem-pci as a proxy.
> > So we have to choose a different one (unfortunately). "memaddr" it is.
> > That name should ideally be used by all other virtio-* based memory
> > devices in the future.
> > -device virtio-pmem-pci,id=p0,bus=bux0,addr=0x01,memaddr=0x1000000...
> >
> > Acked-by: Markus Armbruster <armbru@redhat.com>
> > [ QAPI bits ]
> > Signed-off-by: Pankaj Gupta <pagupta@redhat.com>
> > [ MemoryDevice/MemoryRegion changes, cleanups, addr property "memaddr",
> > split up patches, unplug handler ]
> > Signed-off-by: David Hildenbrand <david@redhat.com>
> > ---
>
> > +++ b/qapi/misc.json
> > @@ -2742,16 +2742,42 @@
> > }
> > }
> >
> > +##
> > +# @VirtioPMEMDeviceInfo:
> > +#
> > +# VirtioPMEM state information
> > +#
> > +# @id: device's ID
> > +#
> > +# @memaddr: physical address in memory, where device is mapped
> > +#
> > +# @size: size of memory that the device provides
> > +#
> > +# @memdev: memory backend linked with device
> > +#
> > +# Since: 4.0
>
> You've missed 4.0; this should be 4.1.
Yes. Will update.
>
> > +##
> > +{ 'struct': 'VirtioPMEMDeviceInfo',
> > + 'data': { '*id': 'str',
>
> Why is id optional? Does it make sense to have a device without an id?
I think that's how it has been for both NVDIMM and DIMM. And it works
fine with optional 'id', but requires unique 'id' for underlying memory device.
That means its okay to keep 'id' optional for root dimm/nvdimm/virtio-pmem
devices.
Thanks,
Pankaj
>
> > + 'memaddr': 'size',
> > + 'size': 'size',
> > + 'memdev': 'str'
> > + }
> > +}
> > +
> > ##
> > # @MemoryDeviceInfo:
> > #
> > # Union containing information about a memory device
> > #
> > +# nvdimm is included since 2.12. virtio-pmem is included since 4.0.
>
> 4.1
o.k
>
> > +#
> > # Since: 2.1
> > ##
> > { 'union': 'MemoryDeviceInfo',
> > 'data': { 'dimm': 'PCDIMMDeviceInfo',
> > - 'nvdimm': 'PCDIMMDeviceInfo'
> > + 'nvdimm': 'PCDIMMDeviceInfo',
> > + 'virtio-pmem': 'VirtioPMEMDeviceInfo'
> > }
> > }
> >
> >
>
> --
> Eric Blake, Principal Software Engineer
> Red Hat, Inc. +1-919-301-3226
> Virtualization: qemu.org | libvirt.org
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH 1/7] virtio-pmem: add virtio device
2019-05-23 10:24 ` [Qemu-devel] [PATCH 1/7] virtio-pmem: add virtio device Pankaj Gupta
2019-05-23 13:21 ` Eric Blake
@ 2019-06-04 13:15 ` Cornelia Huck
2019-06-10 5:09 ` Pankaj Gupta
1 sibling, 1 reply; 12+ messages in thread
From: Cornelia Huck @ 2019-06-04 13:15 UTC (permalink / raw)
To: Pankaj Gupta
Cc: kwolf, aarcange, xiaoguangrong.eric, mst, armbru, riel, david,
qemu-devel, ehabkost, lcapitulino, stefanha, pbonzini, imammedo,
dan.j.williams, nilal, dgilbert, rth
On Thu, 23 May 2019 15:54:43 +0530
Pankaj Gupta <pagupta@redhat.com> wrote:
> This is the implementation of virtio-pmem device. Support will require
> machine changes for the architectures that will support it, so it will
> not yet be compiled. It can be unlocked with VIRTIO_PMEM_SUPPORTED per
> machine and disabled globally via VIRTIO_PMEM.
>
> We cannot use the "addr" property as that is already used e.g. for
> virtio-pci/pci devices. And we will have e.g. virtio-pmem-pci as a proxy.
> So we have to choose a different one (unfortunately). "memaddr" it is.
> That name should ideally be used by all other virtio-* based memory
> devices in the future.
> -device virtio-pmem-pci,id=p0,bus=bux0,addr=0x01,memaddr=0x1000000...
>
> Acked-by: Markus Armbruster <armbru@redhat.com>
> [ QAPI bits ]
> Signed-off-by: Pankaj Gupta <pagupta@redhat.com>
> [ MemoryDevice/MemoryRegion changes, cleanups, addr property "memaddr",
> split up patches, unplug handler ]
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
> hw/virtio/Kconfig | 10 +++
> hw/virtio/Makefile.objs | 1 +
> hw/virtio/virtio-pmem.c | 190 ++++++++++++++++++++++++++++++++++++++++
> include/hw/virtio/virtio-pmem.h | 49 +++++++++++
> qapi/misc.json | 28 +++++-
> 5 files changed, 277 insertions(+), 1 deletion(-)
> create mode 100644 hw/virtio/virtio-pmem.c
> create mode 100644 include/hw/virtio/virtio-pmem.h
> diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c
> new file mode 100644
> index 0000000000..c462d2c942
> --- /dev/null
> +++ b/hw/virtio/virtio-pmem.c
> @@ -0,0 +1,190 @@
> +static void virtio_pmem_unrealize(DeviceState *dev, Error **errp)
> +{
> + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> + VirtIOPMEM *pmem = VIRTIO_PMEM(dev);
> +
> + host_memory_backend_set_mapped(pmem->memdev, false);
> + pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush);
Adding a queue during unrealize looks weird... copy/paste error?
> + virtio_cleanup(vdev);
> +}
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH 1/7] virtio-pmem: add virtio device
2019-06-04 13:15 ` Cornelia Huck
@ 2019-06-10 5:09 ` Pankaj Gupta
0 siblings, 0 replies; 12+ messages in thread
From: Pankaj Gupta @ 2019-06-10 5:09 UTC (permalink / raw)
To: Cornelia Huck
Cc: kwolf, aarcange, nilal, xiaoguangrong eric, riel, rth, mst,
david, armbru, qemu-devel, stefanha, imammedo, pbonzini,
dan j williams, lcapitulino, dgilbert, ehabkost
>
> > This is the implementation of virtio-pmem device. Support will require
> > machine changes for the architectures that will support it, so it will
> > not yet be compiled. It can be unlocked with VIRTIO_PMEM_SUPPORTED per
> > machine and disabled globally via VIRTIO_PMEM.
> >
> > We cannot use the "addr" property as that is already used e.g. for
> > virtio-pci/pci devices. And we will have e.g. virtio-pmem-pci as a proxy.
> > So we have to choose a different one (unfortunately). "memaddr" it is.
> > That name should ideally be used by all other virtio-* based memory
> > devices in the future.
> > -device virtio-pmem-pci,id=p0,bus=bux0,addr=0x01,memaddr=0x1000000...
> >
> > Acked-by: Markus Armbruster <armbru@redhat.com>
> > [ QAPI bits ]
> > Signed-off-by: Pankaj Gupta <pagupta@redhat.com>
> > [ MemoryDevice/MemoryRegion changes, cleanups, addr property "memaddr",
> > split up patches, unplug handler ]
> > Signed-off-by: David Hildenbrand <david@redhat.com>
> > ---
> > hw/virtio/Kconfig | 10 +++
> > hw/virtio/Makefile.objs | 1 +
> > hw/virtio/virtio-pmem.c | 190
> > ++++++++++++++++++++++++++++++++++++++++
> > include/hw/virtio/virtio-pmem.h | 49 +++++++++++
> > qapi/misc.json | 28 +++++-
> > 5 files changed, 277 insertions(+), 1 deletion(-)
> > create mode 100644 hw/virtio/virtio-pmem.c
> > create mode 100644 include/hw/virtio/virtio-pmem.h
>
> > diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c
> > new file mode 100644
> > index 0000000000..c462d2c942
> > --- /dev/null
> > +++ b/hw/virtio/virtio-pmem.c
> > @@ -0,0 +1,190 @@
>
> > +static void virtio_pmem_unrealize(DeviceState *dev, Error **errp)
> > +{
> > + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> > + VirtIOPMEM *pmem = VIRTIO_PMEM(dev);
> > +
> > + host_memory_backend_set_mapped(pmem->memdev, false);
> > + pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush);
>
> Adding a queue during unrealize looks weird... copy/paste error?
Yes. Thanks for catching this. Will correct in v2.
Thanks,
Pankaj
>
> > + virtio_cleanup(vdev);
> > +}
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 2/7] virtio-pci: Allow to specify additional interfaces for the base type
2019-05-23 10:24 [Qemu-devel] [PATCH 0/7] Qemu virtio pmem device Pankaj Gupta
2019-05-23 10:24 ` [Qemu-devel] [PATCH 1/7] virtio-pmem: add virtio device Pankaj Gupta
@ 2019-05-23 10:24 ` Pankaj Gupta
2019-05-23 10:24 ` [Qemu-devel] [PATCH 3/7] virtio-pmem: sync linux headers Pankaj Gupta
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Pankaj Gupta @ 2019-05-23 10:24 UTC (permalink / raw)
To: qemu-devel
Cc: kwolf, aarcange, cohuck, xiaoguangrong.eric, mst, pagupta, riel,
david, armbru, ehabkost, lcapitulino, stefanha, pbonzini,
imammedo, dan.j.williams, nilal, dgilbert, rth
From: David Hildenbrand <david@redhat.com>
Let's allow to specify additional interfaces for the base type (e.g.
later TYPE_MEMORY_DEVICE), something that was possible before the
rework of virtio PCI device instantiation.
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/virtio/virtio-pci.c | 1 +
hw/virtio/virtio-pci.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index cb44e19b67..0ac451ed0f 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1939,6 +1939,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t)
.class_init = virtio_pci_base_class_init,
.class_data = (void *)t,
.abstract = true,
+ .interfaces = t->interfaces,
};
TypeInfo generic_type_info = {
.name = t->generic_name,
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 18581854ca..292275acb1 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -233,6 +233,7 @@ typedef struct VirtioPCIDeviceTypeInfo {
size_t class_size;
void (*instance_init)(Object *obj);
void (*class_init)(ObjectClass *klass, void *data);
+ InterfaceInfo *interfaces;
} VirtioPCIDeviceTypeInfo;
/* Register virtio-pci type(s). @t must be static. */
--
2.14.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 3/7] virtio-pmem: sync linux headers
2019-05-23 10:24 [Qemu-devel] [PATCH 0/7] Qemu virtio pmem device Pankaj Gupta
2019-05-23 10:24 ` [Qemu-devel] [PATCH 1/7] virtio-pmem: add virtio device Pankaj Gupta
2019-05-23 10:24 ` [Qemu-devel] [PATCH 2/7] virtio-pci: Allow to specify additional interfaces for the base type Pankaj Gupta
@ 2019-05-23 10:24 ` Pankaj Gupta
2019-05-23 10:24 ` [Qemu-devel] [PATCH 4/7] virtio-pci: Proxy for virtio-pmem Pankaj Gupta
` (3 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Pankaj Gupta @ 2019-05-23 10:24 UTC (permalink / raw)
To: qemu-devel
Cc: kwolf, aarcange, cohuck, xiaoguangrong.eric, mst, pagupta, riel,
david, armbru, ehabkost, lcapitulino, stefanha, pbonzini,
imammedo, dan.j.williams, nilal, dgilbert, rth
Sync linux headers for virtio pmem.
Signed-off-by: Pankaj Gupta <pagupta@redhat.com>
---
include/standard-headers/linux/virtio_ids.h | 1 +
include/standard-headers/linux/virtio_pmem.h | 35 ++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
create mode 100644 include/standard-headers/linux/virtio_pmem.h
diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
index 6d5c3b2d4f..32b2f94d1f 100644
--- a/include/standard-headers/linux/virtio_ids.h
+++ b/include/standard-headers/linux/virtio_ids.h
@@ -43,5 +43,6 @@
#define VIRTIO_ID_INPUT 18 /* virtio input */
#define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */
#define VIRTIO_ID_CRYPTO 20 /* virtio crypto */
+#define VIRTIO_ID_PMEM 27 /* virtio pmem */
#endif /* _LINUX_VIRTIO_IDS_H */
diff --git a/include/standard-headers/linux/virtio_pmem.h b/include/standard-headers/linux/virtio_pmem.h
new file mode 100644
index 0000000000..7a3e2fe524
--- /dev/null
+++ b/include/standard-headers/linux/virtio_pmem.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/*
+ * Definitions for virtio-pmem devices.
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * Author(s): Pankaj Gupta <pagupta@redhat.com>
+ */
+
+#ifndef _UAPI_LINUX_VIRTIO_PMEM_H
+#define _UAPI_LINUX_VIRTIO_PMEM_H
+
+#include <linux/types.h>
+#include <linux/virtio_types.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+
+struct virtio_pmem_config {
+ __le64 start;
+ __le64 size;
+};
+
+#define VIRTIO_PMEM_REQ_TYPE_FLUSH 0
+
+struct virtio_pmem_resp {
+ /* Host return status corresponding to flush request */
+ __virtio32 ret;
+};
+
+struct virtio_pmem_req {
+ /* command type */
+ __virtio32 type;
+};
+
+#endif
--
2.14.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 4/7] virtio-pci: Proxy for virtio-pmem
2019-05-23 10:24 [Qemu-devel] [PATCH 0/7] Qemu virtio pmem device Pankaj Gupta
` (2 preceding siblings ...)
2019-05-23 10:24 ` [Qemu-devel] [PATCH 3/7] virtio-pmem: sync linux headers Pankaj Gupta
@ 2019-05-23 10:24 ` Pankaj Gupta
2019-05-23 10:24 ` [Qemu-devel] [PATCH 5/7] hmp: Handle virtio-pmem when printing memory device infos Pankaj Gupta
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Pankaj Gupta @ 2019-05-23 10:24 UTC (permalink / raw)
To: qemu-devel
Cc: kwolf, aarcange, cohuck, xiaoguangrong.eric, mst, pagupta, riel,
david, armbru, ehabkost, lcapitulino, stefanha, pbonzini,
imammedo, dan.j.williams, nilal, dgilbert, rth
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>
---
hw/virtio/Makefile.objs | 1 +
hw/virtio/virtio-pmem-pci.c | 131 ++++++++++++++++++++++++++++++++++++++++++++
hw/virtio/virtio-pmem-pci.h | 34 ++++++++++++
include/hw/pci/pci.h | 1 +
4 files changed, 167 insertions(+)
create mode 100644 hw/virtio/virtio-pmem-pci.c
create mode 100644 hw/virtio/virtio-pmem-pci.h
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 5857e3b8e1..964ce78607 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -13,6 +13,7 @@ obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
obj-$(call land,$(CONFIG_VIRTIO_CRYPTO),$(CONFIG_VIRTIO_PCI)) += virtio-crypto-pci.o
obj-$(CONFIG_VIRTIO_PMEM) += virtio-pmem.o
+common-obj-$(call land,$(CONFIG_VIRTIO_PMEM),$(CONFIG_VIRTIO_PCI)) += virtio-pmem-pci.o
obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
ifeq ($(CONFIG_VIRTIO_PCI),y)
diff --git a/hw/virtio/virtio-pmem-pci.c b/hw/virtio/virtio-pmem-pci.c
new file mode 100644
index 0000000000..8b2d0dbccc
--- /dev/null
+++ b/hw/virtio/virtio-pmem-pci.c
@@ -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)
diff --git a/hw/virtio/virtio-pmem-pci.h b/hw/virtio/virtio-pmem-pci.h
new file mode 100644
index 0000000000..616abef093
--- /dev/null
+++ b/hw/virtio/virtio-pmem-pci.h
@@ -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 */
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index edf44de21d..097feb2cb7 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -85,6 +85,7 @@ extern bool pci_available;
#define PCI_DEVICE_ID_VIRTIO_RNG 0x1005
#define PCI_DEVICE_ID_VIRTIO_9P 0x1009
#define PCI_DEVICE_ID_VIRTIO_VSOCK 0x1012
+#define PCI_DEVICE_ID_VIRTIO_PMEM 0x1013
#define PCI_VENDOR_ID_REDHAT 0x1b36
#define PCI_DEVICE_ID_REDHAT_BRIDGE 0x0001
--
2.14.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 5/7] hmp: Handle virtio-pmem when printing memory device infos
2019-05-23 10:24 [Qemu-devel] [PATCH 0/7] Qemu virtio pmem device Pankaj Gupta
` (3 preceding siblings ...)
2019-05-23 10:24 ` [Qemu-devel] [PATCH 4/7] virtio-pci: Proxy for virtio-pmem Pankaj Gupta
@ 2019-05-23 10:24 ` Pankaj Gupta
2019-05-23 10:24 ` [Qemu-devel] [PATCH 6/7] numa: Handle virtio-pmem in NUMA stats Pankaj Gupta
2019-05-23 10:24 ` [Qemu-devel] [PATCH 7/7] pc: Support for virtio-pmem-pci Pankaj Gupta
6 siblings, 0 replies; 12+ messages in thread
From: Pankaj Gupta @ 2019-05-23 10:24 UTC (permalink / raw)
To: qemu-devel
Cc: kwolf, aarcange, cohuck, xiaoguangrong.eric, mst, pagupta, riel,
david, armbru, ehabkost, lcapitulino, stefanha, pbonzini,
imammedo, dan.j.williams, nilal, dgilbert, rth
From: David Hildenbrand <david@redhat.com>
Print the memory device info just like for PCDIMM/NVDIMM.
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hmp.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/hmp.c b/hmp.c
index 92941142af..e1866bc7f1 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2650,6 +2650,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
Error *err = NULL;
MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
MemoryDeviceInfoList *info;
+ VirtioPMEMDeviceInfo *vpi;
MemoryDeviceInfo *value;
PCDIMMDeviceInfo *di;
@@ -2659,19 +2660,9 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
if (value) {
switch (value->type) {
case MEMORY_DEVICE_INFO_KIND_DIMM:
- di = value->u.dimm.data;
- break;
-
case MEMORY_DEVICE_INFO_KIND_NVDIMM:
- di = value->u.nvdimm.data;
- break;
-
- default:
- di = NULL;
- break;
- }
-
- if (di) {
+ di = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ?
+ value->u.dimm.data : value->u.nvdimm.data;
monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
MemoryDeviceInfoKind_str(value->type),
di->id ? di->id : "");
@@ -2684,6 +2675,18 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
di->hotplugged ? "true" : "false");
monitor_printf(mon, " hotpluggable: %s\n",
di->hotpluggable ? "true" : "false");
+ break;
+ case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM:
+ vpi = value->u.virtio_pmem.data;
+ monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
+ MemoryDeviceInfoKind_str(value->type),
+ vpi->id ? vpi->id : "");
+ monitor_printf(mon, " memaddr: 0x%" PRIx64 "\n", vpi->memaddr);
+ monitor_printf(mon, " size: %" PRIu64 "\n", vpi->size);
+ monitor_printf(mon, " memdev: %s\n", vpi->memdev);
+ break;
+ default:
+ g_assert_not_reached();
}
}
}
--
2.14.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 6/7] numa: Handle virtio-pmem in NUMA stats
2019-05-23 10:24 [Qemu-devel] [PATCH 0/7] Qemu virtio pmem device Pankaj Gupta
` (4 preceding siblings ...)
2019-05-23 10:24 ` [Qemu-devel] [PATCH 5/7] hmp: Handle virtio-pmem when printing memory device infos Pankaj Gupta
@ 2019-05-23 10:24 ` Pankaj Gupta
2019-05-23 10:24 ` [Qemu-devel] [PATCH 7/7] pc: Support for virtio-pmem-pci Pankaj Gupta
6 siblings, 0 replies; 12+ messages in thread
From: Pankaj Gupta @ 2019-05-23 10:24 UTC (permalink / raw)
To: qemu-devel
Cc: kwolf, aarcange, cohuck, xiaoguangrong.eric, mst, pagupta, riel,
david, armbru, ehabkost, lcapitulino, stefanha, pbonzini,
imammedo, dan.j.williams, nilal, dgilbert, rth
From: David Hildenbrand <david@redhat.com>
Account the memory to node 0 for now. Once (if ever) virtio-pmem
supports NUMA, we can account it to the right node.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
numa.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/numa.c b/numa.c
index 3875e1efda..42cca616e7 100644
--- a/numa.c
+++ b/numa.c
@@ -549,6 +549,7 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[])
MemoryDeviceInfoList *info_list = qmp_memory_device_list();
MemoryDeviceInfoList *info;
PCDIMMDeviceInfo *pcdimm_info;
+ VirtioPMEMDeviceInfo *vpi;
for (info = info_list; info; info = info->next) {
MemoryDeviceInfo *value = info->value;
@@ -556,22 +557,21 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[])
if (value) {
switch (value->type) {
case MEMORY_DEVICE_INFO_KIND_DIMM:
- pcdimm_info = value->u.dimm.data;
- break;
-
case MEMORY_DEVICE_INFO_KIND_NVDIMM:
- pcdimm_info = value->u.nvdimm.data;
- break;
-
- default:
- pcdimm_info = NULL;
- break;
- }
-
- if (pcdimm_info) {
+ pcdimm_info = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ?
+ value->u.dimm.data : value->u.nvdimm.data;
node_mem[pcdimm_info->node].node_mem += pcdimm_info->size;
node_mem[pcdimm_info->node].node_plugged_mem +=
pcdimm_info->size;
+ break;
+ case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM:
+ vpi = value->u.virtio_pmem.data;
+ /* TODO: once we support numa, assign to right node */
+ node_mem[0].node_mem += vpi->size;
+ node_mem[0].node_plugged_mem += vpi->size;
+ break;
+ default:
+ g_assert_not_reached();
}
}
}
--
2.14.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 7/7] pc: Support for virtio-pmem-pci
2019-05-23 10:24 [Qemu-devel] [PATCH 0/7] Qemu virtio pmem device Pankaj Gupta
` (5 preceding siblings ...)
2019-05-23 10:24 ` [Qemu-devel] [PATCH 6/7] numa: Handle virtio-pmem in NUMA stats Pankaj Gupta
@ 2019-05-23 10:24 ` Pankaj Gupta
6 siblings, 0 replies; 12+ messages in thread
From: Pankaj Gupta @ 2019-05-23 10:24 UTC (permalink / raw)
To: qemu-devel
Cc: kwolf, aarcange, cohuck, xiaoguangrong.eric, mst, pagupta, riel,
david, armbru, ehabkost, lcapitulino, stefanha, pbonzini,
imammedo, dan.j.williams, nilal, dgilbert, rth
From: David Hildenbrand <david@redhat.com>
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>
---
hw/i386/Kconfig | 1 +
hw/i386/pc.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index 9817888216..4ddf2a9c55 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -30,6 +30,7 @@ config PC
# For ACPI builder:
select SERIAL_ISA
select ACPI_VMGENID
+ select VIRTIO_PMEM_SUPPORTED
config PC_PCI
bool
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d98b737b8f..3b2ad42699 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -77,6 +77,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
@@ -2398,6 +2400,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)
{
@@ -2405,6 +2466,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);
}
}
@@ -2415,6 +2478,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);
}
}
@@ -2425,6 +2490,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)));
@@ -2438,6 +2505,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)));
@@ -2448,7 +2517,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);
}
--
2.14.5
^ permalink raw reply related [flat|nested] 12+ messages in thread