* [PATCH v4 1/3] virtio: Add virtio_fs linux headers
2019-09-30 10:51 [PATCH v4 0/3] Add virtio-fs Dr. David Alan Gilbert (git)
@ 2019-09-30 10:51 ` Dr. David Alan Gilbert (git)
2019-10-05 22:00 ` [PULL 17/19] " Michael S. Tsirkin
2019-09-30 10:51 ` [PATCH v4 2/3] virtio: add vhost-user-fs base device Dr. David Alan Gilbert (git)
2019-09-30 10:51 ` [PATCH v4 3/3] virtio: add vhost-user-fs-pci device Dr. David Alan Gilbert (git)
2 siblings, 1 reply; 60+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-09-30 10:51 UTC (permalink / raw)
To: qemu-devel, mst; +Cc: mszeredi, cohuck, vgoyal, stefanha
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Pull in the virtio_fs.h linux header and the constant for the virtiofs
ID; by running scripts/update-linux-headers.sh against
Linus's tree 97f9a3c4eee55b0178b518ae7114a6a53372913d.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
include/standard-headers/linux/virtio_fs.h | 19 +++++++++++++++++++
include/standard-headers/linux/virtio_ids.h | 2 ++
2 files changed, 21 insertions(+)
create mode 100644 include/standard-headers/linux/virtio_fs.h
diff --git a/include/standard-headers/linux/virtio_fs.h b/include/standard-headers/linux/virtio_fs.h
new file mode 100644
index 0000000000..9d88817a6b
--- /dev/null
+++ b/include/standard-headers/linux/virtio_fs.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
+
+#ifndef _LINUX_VIRTIO_FS_H
+#define _LINUX_VIRTIO_FS_H
+
+#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_config.h"
+#include "standard-headers/linux/virtio_types.h"
+
+struct virtio_fs_config {
+ /* Filesystem name (UTF-8, not NUL-terminated, padded with NULs) */
+ uint8_t tag[36];
+
+ /* Number of request queues */
+ uint32_t num_request_queues;
+} QEMU_PACKED;
+
+#endif /* _LINUX_VIRTIO_FS_H */
diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
index 32b2f94d1f..585e07b273 100644
--- a/include/standard-headers/linux/virtio_ids.h
+++ b/include/standard-headers/linux/virtio_ids.h
@@ -43,6 +43,8 @@
#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_IOMMU 23 /* virtio IOMMU */
+#define VIRTIO_ID_FS 26 /* virtio filesystem */
#define VIRTIO_ID_PMEM 27 /* virtio pmem */
#endif /* _LINUX_VIRTIO_IDS_H */
--
2.21.0
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [PULL 17/19] virtio: Add virtio_fs linux headers
2019-09-30 10:51 ` [PATCH v4 1/3] virtio: Add virtio_fs linux headers Dr. David Alan Gilbert (git)
@ 2019-10-05 22:00 ` Michael S. Tsirkin
0 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 22:00 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Miklos Szeredi, Dr. David Alan Gilbert,
Stefan Hajnoczi, Vivek Goyal
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Pull in the virtio_fs.h linux header and the constant for the virtiofs
ID; by running scripts/update-linux-headers.sh against
Linus's tree 97f9a3c4eee55b0178b518ae7114a6a53372913d.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Message-Id: <20190930105135.27244-2-dgilbert@redhat.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
include/standard-headers/linux/virtio_fs.h | 19 +++++++++++++++++++
include/standard-headers/linux/virtio_ids.h | 2 ++
2 files changed, 21 insertions(+)
create mode 100644 include/standard-headers/linux/virtio_fs.h
diff --git a/include/standard-headers/linux/virtio_fs.h b/include/standard-headers/linux/virtio_fs.h
new file mode 100644
index 0000000000..9d88817a6b
--- /dev/null
+++ b/include/standard-headers/linux/virtio_fs.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
+
+#ifndef _LINUX_VIRTIO_FS_H
+#define _LINUX_VIRTIO_FS_H
+
+#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_config.h"
+#include "standard-headers/linux/virtio_types.h"
+
+struct virtio_fs_config {
+ /* Filesystem name (UTF-8, not NUL-terminated, padded with NULs) */
+ uint8_t tag[36];
+
+ /* Number of request queues */
+ uint32_t num_request_queues;
+} QEMU_PACKED;
+
+#endif /* _LINUX_VIRTIO_FS_H */
diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
index 32b2f94d1f..585e07b273 100644
--- a/include/standard-headers/linux/virtio_ids.h
+++ b/include/standard-headers/linux/virtio_ids.h
@@ -43,6 +43,8 @@
#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_IOMMU 23 /* virtio IOMMU */
+#define VIRTIO_ID_FS 26 /* virtio filesystem */
#define VIRTIO_ID_PMEM 27 /* virtio pmem */
#endif /* _LINUX_VIRTIO_IDS_H */
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [PATCH v4 2/3] virtio: add vhost-user-fs base device
2019-09-30 10:51 [PATCH v4 0/3] Add virtio-fs Dr. David Alan Gilbert (git)
2019-09-30 10:51 ` [PATCH v4 1/3] virtio: Add virtio_fs linux headers Dr. David Alan Gilbert (git)
@ 2019-09-30 10:51 ` Dr. David Alan Gilbert (git)
2019-09-30 11:06 ` Marc-André Lureau
` (2 more replies)
2019-09-30 10:51 ` [PATCH v4 3/3] virtio: add vhost-user-fs-pci device Dr. David Alan Gilbert (git)
2 siblings, 3 replies; 60+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-09-30 10:51 UTC (permalink / raw)
To: qemu-devel, mst; +Cc: mszeredi, cohuck, vgoyal, stefanha
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
The virtio-fs virtio device provides shared file system access using
the FUSE protocol carried over virtio.
The actual file server is implemented in an external vhost-user-fs device
backend process.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
configure | 13 ++
hw/virtio/Makefile.objs | 1 +
hw/virtio/vhost-user-fs.c | 299 ++++++++++++++++++++++++++++++
include/hw/virtio/vhost-user-fs.h | 45 +++++
4 files changed, 358 insertions(+)
create mode 100644 hw/virtio/vhost-user-fs.c
create mode 100644 include/hw/virtio/vhost-user-fs.h
diff --git a/configure b/configure
index 542f6aea3f..204cbe351e 100755
--- a/configure
+++ b/configure
@@ -381,6 +381,7 @@ vhost_crypto=""
vhost_scsi=""
vhost_vsock=""
vhost_user=""
+vhost_user_fs=""
kvm="no"
hax="no"
hvf="no"
@@ -1293,6 +1294,10 @@ for opt do
;;
--enable-vhost-vsock) vhost_vsock="yes"
;;
+ --disable-vhost-user-fs) vhost_user_fs="no"
+ ;;
+ --enable-vhost-user-fs) vhost_user_fs="yes"
+ ;;
--disable-opengl) opengl="no"
;;
--enable-opengl) opengl="yes"
@@ -2236,6 +2241,10 @@ test "$vhost_crypto" = "" && vhost_crypto=$vhost_user
if test "$vhost_crypto" = "yes" && test "$vhost_user" = "no"; then
error_exit "--enable-vhost-crypto requires --enable-vhost-user"
fi
+test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
+if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
+ error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
+fi
# OR the vhost-kernel and vhost-user values for simplicity
if test "$vhost_net" = ""; then
@@ -6377,6 +6386,7 @@ echo "vhost-crypto support $vhost_crypto"
echo "vhost-scsi support $vhost_scsi"
echo "vhost-vsock support $vhost_vsock"
echo "vhost-user support $vhost_user"
+echo "vhost-user-fs support $vhost_user_fs"
echo "Trace backends $trace_backends"
if have_backend "simple"; then
echo "Trace output file $trace_file-<pid>"
@@ -6873,6 +6883,9 @@ fi
if test "$vhost_user" = "yes" ; then
echo "CONFIG_VHOST_USER=y" >> $config_host_mak
fi
+if test "$vhost_user_fs" = "yes" ; then
+ echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
+fi
if test "$blobs" = "yes" ; then
echo "INSTALL_BLOBS=yes" >> $config_host_mak
fi
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 964ce78607..47ffbf22c4 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -11,6 +11,7 @@ common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
common-obj-$(CONFIG_VIRTIO_MMIO) += virtio-mmio.o
obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
+obj-$(CONFIG_VHOST_USER_FS) += vhost-user-fs.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
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
new file mode 100644
index 0000000000..f0df7f4746
--- /dev/null
+++ b/hw/virtio/vhost-user-fs.c
@@ -0,0 +1,299 @@
+/*
+ * Vhost-user filesystem virtio device
+ *
+ * Copyright 2018-2019 Red Hat, Inc.
+ *
+ * Authors:
+ * Stefan Hajnoczi <stefanha@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include <sys/ioctl.h>
+#include "standard-headers/linux/virtio_fs.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/virtio-access.h"
+#include "qemu/error-report.h"
+#include "hw/virtio/vhost-user-fs.h"
+#include "monitor/monitor.h"
+
+static void vuf_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+ struct virtio_fs_config fscfg = {};
+
+ memcpy((char *)fscfg.tag, fs->conf.tag,
+ MIN(strlen(fs->conf.tag) + 1, sizeof(fscfg.tag)));
+
+ virtio_stl_p(vdev, &fscfg.num_request_queues, fs->conf.num_request_queues);
+
+ memcpy(config, &fscfg, sizeof(fscfg));
+}
+
+static void vuf_start(VirtIODevice *vdev)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+ int ret;
+ int i;
+
+ if (!k->set_guest_notifiers) {
+ error_report("binding does not support guest notifiers");
+ return;
+ }
+
+ ret = vhost_dev_enable_notifiers(&fs->vhost_dev, vdev);
+ if (ret < 0) {
+ error_report("Error enabling host notifiers: %d", -ret);
+ return;
+ }
+
+ ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, true);
+ if (ret < 0) {
+ error_report("Error binding guest notifier: %d", -ret);
+ goto err_host_notifiers;
+ }
+
+ fs->vhost_dev.acked_features = vdev->guest_features;
+ ret = vhost_dev_start(&fs->vhost_dev, vdev);
+ if (ret < 0) {
+ error_report("Error starting vhost: %d", -ret);
+ goto err_guest_notifiers;
+ }
+
+ /*
+ * guest_notifier_mask/pending not used yet, so just unmask
+ * everything here. virtio-pci will do the right thing by
+ * enabling/disabling irqfd.
+ */
+ for (i = 0; i < fs->vhost_dev.nvqs; i++) {
+ vhost_virtqueue_mask(&fs->vhost_dev, vdev, i, false);
+ }
+
+ return;
+
+err_guest_notifiers:
+ k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
+err_host_notifiers:
+ vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
+}
+
+static void vuf_stop(VirtIODevice *vdev)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+ int ret;
+
+ if (!k->set_guest_notifiers) {
+ return;
+ }
+
+ vhost_dev_stop(&fs->vhost_dev, vdev);
+
+ ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
+ if (ret < 0) {
+ error_report("vhost guest notifier cleanup failed: %d", ret);
+ return;
+ }
+
+ vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
+}
+
+static void vuf_set_status(VirtIODevice *vdev, uint8_t status)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+ bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
+
+ if (!vdev->vm_running) {
+ should_start = false;
+ }
+
+ if (fs->vhost_dev.started == should_start) {
+ return;
+ }
+
+ if (should_start) {
+ vuf_start(vdev);
+ } else {
+ vuf_stop(vdev);
+ }
+}
+
+static uint64_t vuf_get_features(VirtIODevice *vdev,
+ uint64_t requested_features,
+ Error **errp)
+{
+ /* No feature bits used yet */
+ return requested_features;
+}
+
+static void vuf_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+ /*
+ * Not normally called; it's the daemon that handles the queue;
+ * however virtio's cleanup path can call this.
+ */
+}
+
+static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
+ bool mask)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+
+ vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
+}
+
+static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+
+ return vhost_virtqueue_pending(&fs->vhost_dev, idx);
+}
+
+static void vuf_device_realize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VHostUserFS *fs = VHOST_USER_FS(dev);
+ unsigned int i;
+ size_t len;
+ int ret;
+
+ if (!fs->conf.chardev.chr) {
+ error_setg(errp, "missing chardev");
+ return;
+ }
+
+ if (!fs->conf.tag) {
+ error_setg(errp, "missing tag property");
+ return;
+ }
+ len = strlen(fs->conf.tag);
+ if (len == 0) {
+ error_setg(errp, "tag property cannot be empty");
+ return;
+ }
+ if (len > sizeof_field(struct virtio_fs_config, tag)) {
+ error_setg(errp, "tag property must be %zu bytes or less",
+ sizeof_field(struct virtio_fs_config, tag));
+ return;
+ }
+
+ if (fs->conf.num_request_queues == 0) {
+ error_setg(errp, "num-request-queues property must be larger than 0");
+ return;
+ }
+
+ if (!is_power_of_2(fs->conf.queue_size)) {
+ error_setg(errp, "queue-size property must be a power of 2");
+ return;
+ }
+
+ if (fs->conf.queue_size > VIRTQUEUE_MAX_SIZE) {
+ error_setg(errp, "queue-size property must be %u or smaller",
+ VIRTQUEUE_MAX_SIZE);
+ return;
+ }
+
+ if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev, errp)) {
+ return;
+ }
+
+ virtio_init(vdev, "vhost-user-fs", VIRTIO_ID_FS,
+ sizeof(struct virtio_fs_config));
+
+ /* Hiprio queue */
+ virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
+
+ /* Request queues */
+ for (i = 0; i < fs->conf.num_request_queues; i++) {
+ virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
+ }
+
+ /* 1 high prio queue, plus the number configured */
+ fs->vhost_dev.nvqs = 1 + fs->conf.num_request_queues;
+ fs->vhost_dev.vqs = g_new0(struct vhost_virtqueue, fs->vhost_dev.nvqs);
+ ret = vhost_dev_init(&fs->vhost_dev, &fs->vhost_user,
+ VHOST_BACKEND_TYPE_USER, 0);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "vhost_dev_init failed");
+ goto err_virtio;
+ }
+
+ return;
+
+err_virtio:
+ vhost_user_cleanup(&fs->vhost_user);
+ virtio_cleanup(vdev);
+ g_free(fs->vhost_dev.vqs);
+ return;
+}
+
+static void vuf_device_unrealize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VHostUserFS *fs = VHOST_USER_FS(dev);
+
+ /* This will stop vhost backend if appropriate. */
+ vuf_set_status(vdev, 0);
+
+ vhost_dev_cleanup(&fs->vhost_dev);
+
+ vhost_user_cleanup(&fs->vhost_user);
+
+ virtio_cleanup(vdev);
+ g_free(fs->vhost_dev.vqs);
+ fs->vhost_dev.vqs = NULL;
+}
+
+static const VMStateDescription vuf_vmstate = {
+ .name = "vhost-user-fs",
+ .unmigratable = 1,
+};
+
+static Property vuf_properties[] = {
+ DEFINE_PROP_CHR("chardev", VHostUserFS, conf.chardev),
+ DEFINE_PROP_STRING("tag", VHostUserFS, conf.tag),
+ DEFINE_PROP_UINT16("num-request-queues", VHostUserFS,
+ conf.num_request_queues, 1),
+ DEFINE_PROP_UINT16("queue-size", VHostUserFS, conf.queue_size, 128),
+ DEFINE_PROP_STRING("vhostfd", VHostUserFS, conf.vhostfd),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vuf_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+
+ dc->props = vuf_properties;
+ dc->vmsd = &vuf_vmstate;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ vdc->realize = vuf_device_realize;
+ vdc->unrealize = vuf_device_unrealize;
+ vdc->get_features = vuf_get_features;
+ vdc->get_config = vuf_get_config;
+ vdc->set_status = vuf_set_status;
+ vdc->guest_notifier_mask = vuf_guest_notifier_mask;
+ vdc->guest_notifier_pending = vuf_guest_notifier_pending;
+}
+
+static const TypeInfo vuf_info = {
+ .name = TYPE_VHOST_USER_FS,
+ .parent = TYPE_VIRTIO_DEVICE,
+ .instance_size = sizeof(VHostUserFS),
+ .class_init = vuf_class_init,
+};
+
+static void vuf_register_types(void)
+{
+ type_register_static(&vuf_info);
+}
+
+type_init(vuf_register_types)
diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h
new file mode 100644
index 0000000000..539885b458
--- /dev/null
+++ b/include/hw/virtio/vhost-user-fs.h
@@ -0,0 +1,45 @@
+/*
+ * Vhost-user filesystem virtio device
+ *
+ * Copyright 2018-2019 Red Hat, Inc.
+ *
+ * Authors:
+ * Stefan Hajnoczi <stefanha@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ */
+
+#ifndef _QEMU_VHOST_USER_FS_H
+#define _QEMU_VHOST_USER_FS_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "chardev/char-fe.h"
+
+#define TYPE_VHOST_USER_FS "vhost-user-fs-device"
+#define VHOST_USER_FS(obj) \
+ OBJECT_CHECK(VHostUserFS, (obj), TYPE_VHOST_USER_FS)
+
+typedef struct {
+ CharBackend chardev;
+ char *tag;
+ uint16_t num_request_queues;
+ uint16_t queue_size;
+ char *vhostfd;
+} VHostUserFSConf;
+
+typedef struct {
+ /*< private >*/
+ VirtIODevice parent;
+ VHostUserFSConf conf;
+ struct vhost_virtqueue *vhost_vqs;
+ struct vhost_dev vhost_dev;
+ VhostUserState vhost_user;
+
+ /*< public >*/
+} VHostUserFS;
+
+#endif /* _QEMU_VHOST_USER_FS_H */
--
2.21.0
^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [PATCH v4 2/3] virtio: add vhost-user-fs base device
2019-09-30 10:51 ` [PATCH v4 2/3] virtio: add vhost-user-fs base device Dr. David Alan Gilbert (git)
@ 2019-09-30 11:06 ` Marc-André Lureau
2019-10-01 17:29 ` Dr. David Alan Gilbert
2019-10-05 22:00 ` [PULL 18/19] " Michael S. Tsirkin
2019-10-07 5:57 ` Igor Mammedov
2 siblings, 1 reply; 60+ messages in thread
From: Marc-André Lureau @ 2019-09-30 11:06 UTC (permalink / raw)
To: Dr. David Alan Gilbert (git)
Cc: mszeredi, Michael S. Tsirkin, Cornelia Huck, QEMU,
Stefan Hajnoczi, vgoyal
Hi
On Mon, Sep 30, 2019 at 2:52 PM Dr. David Alan Gilbert (git)
<dgilbert@redhat.com> wrote:
>
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> The virtio-fs virtio device provides shared file system access using
> the FUSE protocol carried over virtio.
> The actual file server is implemented in an external vhost-user-fs device
> backend process.
>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
> configure | 13 ++
> hw/virtio/Makefile.objs | 1 +
> hw/virtio/vhost-user-fs.c | 299 ++++++++++++++++++++++++++++++
> include/hw/virtio/vhost-user-fs.h | 45 +++++
> 4 files changed, 358 insertions(+)
> create mode 100644 hw/virtio/vhost-user-fs.c
> create mode 100644 include/hw/virtio/vhost-user-fs.h
>
> diff --git a/configure b/configure
> index 542f6aea3f..204cbe351e 100755
> --- a/configure
> +++ b/configure
> @@ -381,6 +381,7 @@ vhost_crypto=""
> vhost_scsi=""
> vhost_vsock=""
> vhost_user=""
> +vhost_user_fs=""
> kvm="no"
> hax="no"
> hvf="no"
> @@ -1293,6 +1294,10 @@ for opt do
> ;;
> --enable-vhost-vsock) vhost_vsock="yes"
> ;;
> + --disable-vhost-user-fs) vhost_user_fs="no"
> + ;;
> + --enable-vhost-user-fs) vhost_user_fs="yes"
> + ;;
> --disable-opengl) opengl="no"
> ;;
> --enable-opengl) opengl="yes"
> @@ -2236,6 +2241,10 @@ test "$vhost_crypto" = "" && vhost_crypto=$vhost_user
> if test "$vhost_crypto" = "yes" && test "$vhost_user" = "no"; then
> error_exit "--enable-vhost-crypto requires --enable-vhost-user"
> fi
> +test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
> +if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
> + error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
> +fi
>
> # OR the vhost-kernel and vhost-user values for simplicity
> if test "$vhost_net" = ""; then
> @@ -6377,6 +6386,7 @@ echo "vhost-crypto support $vhost_crypto"
> echo "vhost-scsi support $vhost_scsi"
> echo "vhost-vsock support $vhost_vsock"
> echo "vhost-user support $vhost_user"
> +echo "vhost-user-fs support $vhost_user_fs"
> echo "Trace backends $trace_backends"
> if have_backend "simple"; then
> echo "Trace output file $trace_file-<pid>"
> @@ -6873,6 +6883,9 @@ fi
> if test "$vhost_user" = "yes" ; then
> echo "CONFIG_VHOST_USER=y" >> $config_host_mak
> fi
> +if test "$vhost_user_fs" = "yes" ; then
> + echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
> +fi
> if test "$blobs" = "yes" ; then
> echo "INSTALL_BLOBS=yes" >> $config_host_mak
> fi
> diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> index 964ce78607..47ffbf22c4 100644
> --- a/hw/virtio/Makefile.objs
> +++ b/hw/virtio/Makefile.objs
> @@ -11,6 +11,7 @@ common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
> common-obj-$(CONFIG_VIRTIO_MMIO) += virtio-mmio.o
> obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
> obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
> +obj-$(CONFIG_VHOST_USER_FS) += vhost-user-fs.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
> diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> new file mode 100644
> index 0000000000..f0df7f4746
> --- /dev/null
> +++ b/hw/virtio/vhost-user-fs.c
> @@ -0,0 +1,299 @@
> +/*
> + * Vhost-user filesystem virtio device
> + *
> + * Copyright 2018-2019 Red Hat, Inc.
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version. See the COPYING file in the
> + * top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include <sys/ioctl.h>
> +#include "standard-headers/linux/virtio_fs.h"
> +#include "qapi/error.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/virtio/virtio-bus.h"
> +#include "hw/virtio/virtio-access.h"
> +#include "qemu/error-report.h"
> +#include "hw/virtio/vhost-user-fs.h"
> +#include "monitor/monitor.h"
> +
> +static void vuf_get_config(VirtIODevice *vdev, uint8_t *config)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> + struct virtio_fs_config fscfg = {};
> +
> + memcpy((char *)fscfg.tag, fs->conf.tag,
> + MIN(strlen(fs->conf.tag) + 1, sizeof(fscfg.tag)));
> +
> + virtio_stl_p(vdev, &fscfg.num_request_queues, fs->conf.num_request_queues);
> +
> + memcpy(config, &fscfg, sizeof(fscfg));
> +}
> +
> +static void vuf_start(VirtIODevice *vdev)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> + int ret;
> + int i;
> +
> + if (!k->set_guest_notifiers) {
> + error_report("binding does not support guest notifiers");
> + return;
> + }
> +
> + ret = vhost_dev_enable_notifiers(&fs->vhost_dev, vdev);
> + if (ret < 0) {
> + error_report("Error enabling host notifiers: %d", -ret);
> + return;
> + }
> +
> + ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, true);
> + if (ret < 0) {
> + error_report("Error binding guest notifier: %d", -ret);
> + goto err_host_notifiers;
> + }
> +
> + fs->vhost_dev.acked_features = vdev->guest_features;
> + ret = vhost_dev_start(&fs->vhost_dev, vdev);
> + if (ret < 0) {
> + error_report("Error starting vhost: %d", -ret);
> + goto err_guest_notifiers;
> + }
> +
> + /*
> + * guest_notifier_mask/pending not used yet, so just unmask
> + * everything here. virtio-pci will do the right thing by
> + * enabling/disabling irqfd.
> + */
> + for (i = 0; i < fs->vhost_dev.nvqs; i++) {
> + vhost_virtqueue_mask(&fs->vhost_dev, vdev, i, false);
> + }
> +
> + return;
> +
> +err_guest_notifiers:
> + k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
> +err_host_notifiers:
> + vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
> +}
> +
> +static void vuf_stop(VirtIODevice *vdev)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> + int ret;
> +
> + if (!k->set_guest_notifiers) {
> + return;
> + }
> +
> + vhost_dev_stop(&fs->vhost_dev, vdev);
> +
> + ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
> + if (ret < 0) {
> + error_report("vhost guest notifier cleanup failed: %d", ret);
> + return;
> + }
> +
> + vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
> +}
> +
> +static void vuf_set_status(VirtIODevice *vdev, uint8_t status)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> + bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
> +
> + if (!vdev->vm_running) {
> + should_start = false;
> + }
> +
> + if (fs->vhost_dev.started == should_start) {
> + return;
> + }
> +
> + if (should_start) {
> + vuf_start(vdev);
> + } else {
> + vuf_stop(vdev);
> + }
> +}
It looks like you could have benefited from backends/vhost-user.c
This would allow to factor out some common code and properties used by
vhost-user devices (currently gpu & input, but more could be
converted).
Advantage is that if we add a new mechanism, say to start helpers
(like I propose earlier), all devices using that could benefit it more
easily (in theory).
> +
> +static uint64_t vuf_get_features(VirtIODevice *vdev,
> + uint64_t requested_features,
> + Error **errp)
> +{
> + /* No feature bits used yet */
> + return requested_features;
> +}
> +
> +static void vuf_handle_output(VirtIODevice *vdev, VirtQueue *vq)
> +{
> + /*
> + * Not normally called; it's the daemon that handles the queue;
> + * however virtio's cleanup path can call this.
> + */
> +}
> +
> +static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
> + bool mask)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> +
> + vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
> +}
> +
> +static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> +
> + return vhost_virtqueue_pending(&fs->vhost_dev, idx);
> +}
> +
> +static void vuf_device_realize(DeviceState *dev, Error **errp)
> +{
> + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> + VHostUserFS *fs = VHOST_USER_FS(dev);
> + unsigned int i;
> + size_t len;
> + int ret;
> +
> + if (!fs->conf.chardev.chr) {
> + error_setg(errp, "missing chardev");
> + return;
> + }
> +
> + if (!fs->conf.tag) {
> + error_setg(errp, "missing tag property");
> + return;
> + }
> + len = strlen(fs->conf.tag);
> + if (len == 0) {
> + error_setg(errp, "tag property cannot be empty");
> + return;
> + }
> + if (len > sizeof_field(struct virtio_fs_config, tag)) {
> + error_setg(errp, "tag property must be %zu bytes or less",
> + sizeof_field(struct virtio_fs_config, tag));
> + return;
> + }
> +
> + if (fs->conf.num_request_queues == 0) {
> + error_setg(errp, "num-request-queues property must be larger than 0");
> + return;
> + }
> +
> + if (!is_power_of_2(fs->conf.queue_size)) {
> + error_setg(errp, "queue-size property must be a power of 2");
> + return;
> + }
> +
> + if (fs->conf.queue_size > VIRTQUEUE_MAX_SIZE) {
> + error_setg(errp, "queue-size property must be %u or smaller",
> + VIRTQUEUE_MAX_SIZE);
> + return;
> + }
> +
> + if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev, errp)) {
> + return;
> + }
> +
> + virtio_init(vdev, "vhost-user-fs", VIRTIO_ID_FS,
> + sizeof(struct virtio_fs_config));
> +
> + /* Hiprio queue */
> + virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
> +
> + /* Request queues */
> + for (i = 0; i < fs->conf.num_request_queues; i++) {
> + virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
> + }
> +
> + /* 1 high prio queue, plus the number configured */
> + fs->vhost_dev.nvqs = 1 + fs->conf.num_request_queues;
> + fs->vhost_dev.vqs = g_new0(struct vhost_virtqueue, fs->vhost_dev.nvqs);
> + ret = vhost_dev_init(&fs->vhost_dev, &fs->vhost_user,
> + VHOST_BACKEND_TYPE_USER, 0);
> + if (ret < 0) {
> + error_setg_errno(errp, -ret, "vhost_dev_init failed");
> + goto err_virtio;
> + }
> +
> + return;
> +
> +err_virtio:
> + vhost_user_cleanup(&fs->vhost_user);
> + virtio_cleanup(vdev);
> + g_free(fs->vhost_dev.vqs);
> + return;
> +}
> +
> +static void vuf_device_unrealize(DeviceState *dev, Error **errp)
> +{
> + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> + VHostUserFS *fs = VHOST_USER_FS(dev);
> +
> + /* This will stop vhost backend if appropriate. */
> + vuf_set_status(vdev, 0);
> +
> + vhost_dev_cleanup(&fs->vhost_dev);
> +
> + vhost_user_cleanup(&fs->vhost_user);
> +
> + virtio_cleanup(vdev);
> + g_free(fs->vhost_dev.vqs);
> + fs->vhost_dev.vqs = NULL;
> +}
> +
> +static const VMStateDescription vuf_vmstate = {
> + .name = "vhost-user-fs",
> + .unmigratable = 1,
> +};
> +
> +static Property vuf_properties[] = {
> + DEFINE_PROP_CHR("chardev", VHostUserFS, conf.chardev),
> + DEFINE_PROP_STRING("tag", VHostUserFS, conf.tag),
> + DEFINE_PROP_UINT16("num-request-queues", VHostUserFS,
> + conf.num_request_queues, 1),
> + DEFINE_PROP_UINT16("queue-size", VHostUserFS, conf.queue_size, 128),
> + DEFINE_PROP_STRING("vhostfd", VHostUserFS, conf.vhostfd),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vuf_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
> +
> + dc->props = vuf_properties;
> + dc->vmsd = &vuf_vmstate;
> + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> + vdc->realize = vuf_device_realize;
> + vdc->unrealize = vuf_device_unrealize;
> + vdc->get_features = vuf_get_features;
> + vdc->get_config = vuf_get_config;
> + vdc->set_status = vuf_set_status;
> + vdc->guest_notifier_mask = vuf_guest_notifier_mask;
> + vdc->guest_notifier_pending = vuf_guest_notifier_pending;
> +}
> +
> +static const TypeInfo vuf_info = {
> + .name = TYPE_VHOST_USER_FS,
> + .parent = TYPE_VIRTIO_DEVICE,
> + .instance_size = sizeof(VHostUserFS),
> + .class_init = vuf_class_init,
> +};
> +
> +static void vuf_register_types(void)
> +{
> + type_register_static(&vuf_info);
> +}
> +
> +type_init(vuf_register_types)
> diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h
> new file mode 100644
> index 0000000000..539885b458
> --- /dev/null
> +++ b/include/hw/virtio/vhost-user-fs.h
> @@ -0,0 +1,45 @@
> +/*
> + * Vhost-user filesystem virtio device
> + *
> + * Copyright 2018-2019 Red Hat, Inc.
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version. See the COPYING file in the
> + * top-level directory.
> + */
> +
> +#ifndef _QEMU_VHOST_USER_FS_H
> +#define _QEMU_VHOST_USER_FS_H
> +
> +#include "hw/virtio/virtio.h"
> +#include "hw/virtio/vhost.h"
> +#include "hw/virtio/vhost-user.h"
> +#include "chardev/char-fe.h"
> +
> +#define TYPE_VHOST_USER_FS "vhost-user-fs-device"
> +#define VHOST_USER_FS(obj) \
> + OBJECT_CHECK(VHostUserFS, (obj), TYPE_VHOST_USER_FS)
> +
> +typedef struct {
> + CharBackend chardev;
> + char *tag;
> + uint16_t num_request_queues;
> + uint16_t queue_size;
> + char *vhostfd;
> +} VHostUserFSConf;
> +
> +typedef struct {
> + /*< private >*/
> + VirtIODevice parent;
> + VHostUserFSConf conf;
> + struct vhost_virtqueue *vhost_vqs;
> + struct vhost_dev vhost_dev;
> + VhostUserState vhost_user;
> +
> + /*< public >*/
> +} VHostUserFS;
> +
> +#endif /* _QEMU_VHOST_USER_FS_H */
> --
> 2.21.0
>
>
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH v4 2/3] virtio: add vhost-user-fs base device
2019-09-30 11:06 ` Marc-André Lureau
@ 2019-10-01 17:29 ` Dr. David Alan Gilbert
2019-10-02 15:07 ` Marc-André Lureau
0 siblings, 1 reply; 60+ messages in thread
From: Dr. David Alan Gilbert @ 2019-10-01 17:29 UTC (permalink / raw)
To: Marc-André Lureau
Cc: mszeredi, Michael S. Tsirkin, Cornelia Huck, QEMU,
Stefan Hajnoczi, vgoyal
* Marc-André Lureau (marcandre.lureau@gmail.com) wrote:
> Hi
>
> On Mon, Sep 30, 2019 at 2:52 PM Dr. David Alan Gilbert (git)
> <dgilbert@redhat.com> wrote:
> >
> > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> >
> > The virtio-fs virtio device provides shared file system access using
> > the FUSE protocol carried over virtio.
> > The actual file server is implemented in an external vhost-user-fs device
> > backend process.
> >
> > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> > Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
> > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > ---
> > configure | 13 ++
> > hw/virtio/Makefile.objs | 1 +
> > hw/virtio/vhost-user-fs.c | 299 ++++++++++++++++++++++++++++++
> > include/hw/virtio/vhost-user-fs.h | 45 +++++
> > 4 files changed, 358 insertions(+)
> > create mode 100644 hw/virtio/vhost-user-fs.c
> > create mode 100644 include/hw/virtio/vhost-user-fs.h
> >
> > diff --git a/configure b/configure
> > index 542f6aea3f..204cbe351e 100755
> > --- a/configure
> > +++ b/configure
> > @@ -381,6 +381,7 @@ vhost_crypto=""
> > vhost_scsi=""
> > vhost_vsock=""
> > vhost_user=""
> > +vhost_user_fs=""
> > kvm="no"
> > hax="no"
> > hvf="no"
> > @@ -1293,6 +1294,10 @@ for opt do
> > ;;
> > --enable-vhost-vsock) vhost_vsock="yes"
> > ;;
> > + --disable-vhost-user-fs) vhost_user_fs="no"
> > + ;;
> > + --enable-vhost-user-fs) vhost_user_fs="yes"
> > + ;;
> > --disable-opengl) opengl="no"
> > ;;
> > --enable-opengl) opengl="yes"
> > @@ -2236,6 +2241,10 @@ test "$vhost_crypto" = "" && vhost_crypto=$vhost_user
> > if test "$vhost_crypto" = "yes" && test "$vhost_user" = "no"; then
> > error_exit "--enable-vhost-crypto requires --enable-vhost-user"
> > fi
> > +test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
> > +if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
> > + error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
> > +fi
> >
> > # OR the vhost-kernel and vhost-user values for simplicity
> > if test "$vhost_net" = ""; then
> > @@ -6377,6 +6386,7 @@ echo "vhost-crypto support $vhost_crypto"
> > echo "vhost-scsi support $vhost_scsi"
> > echo "vhost-vsock support $vhost_vsock"
> > echo "vhost-user support $vhost_user"
> > +echo "vhost-user-fs support $vhost_user_fs"
> > echo "Trace backends $trace_backends"
> > if have_backend "simple"; then
> > echo "Trace output file $trace_file-<pid>"
> > @@ -6873,6 +6883,9 @@ fi
> > if test "$vhost_user" = "yes" ; then
> > echo "CONFIG_VHOST_USER=y" >> $config_host_mak
> > fi
> > +if test "$vhost_user_fs" = "yes" ; then
> > + echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
> > +fi
> > if test "$blobs" = "yes" ; then
> > echo "INSTALL_BLOBS=yes" >> $config_host_mak
> > fi
> > diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> > index 964ce78607..47ffbf22c4 100644
> > --- a/hw/virtio/Makefile.objs
> > +++ b/hw/virtio/Makefile.objs
> > @@ -11,6 +11,7 @@ common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
> > common-obj-$(CONFIG_VIRTIO_MMIO) += virtio-mmio.o
> > obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
> > obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
> > +obj-$(CONFIG_VHOST_USER_FS) += vhost-user-fs.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
> > diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> > new file mode 100644
> > index 0000000000..f0df7f4746
> > --- /dev/null
> > +++ b/hw/virtio/vhost-user-fs.c
> > @@ -0,0 +1,299 @@
> > +/*
> > + * Vhost-user filesystem virtio device
> > + *
> > + * Copyright 2018-2019 Red Hat, Inc.
> > + *
> > + * Authors:
> > + * Stefan Hajnoczi <stefanha@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or
> > + * (at your option) any later version. See the COPYING file in the
> > + * top-level directory.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include <sys/ioctl.h>
> > +#include "standard-headers/linux/virtio_fs.h"
> > +#include "qapi/error.h"
> > +#include "hw/qdev-properties.h"
> > +#include "hw/virtio/virtio-bus.h"
> > +#include "hw/virtio/virtio-access.h"
> > +#include "qemu/error-report.h"
> > +#include "hw/virtio/vhost-user-fs.h"
> > +#include "monitor/monitor.h"
> > +
> > +static void vuf_get_config(VirtIODevice *vdev, uint8_t *config)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > + struct virtio_fs_config fscfg = {};
> > +
> > + memcpy((char *)fscfg.tag, fs->conf.tag,
> > + MIN(strlen(fs->conf.tag) + 1, sizeof(fscfg.tag)));
> > +
> > + virtio_stl_p(vdev, &fscfg.num_request_queues, fs->conf.num_request_queues);
> > +
> > + memcpy(config, &fscfg, sizeof(fscfg));
> > +}
> > +
> > +static void vuf_start(VirtIODevice *vdev)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> > + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> > + int ret;
> > + int i;
> > +
> > + if (!k->set_guest_notifiers) {
> > + error_report("binding does not support guest notifiers");
> > + return;
> > + }
> > +
> > + ret = vhost_dev_enable_notifiers(&fs->vhost_dev, vdev);
> > + if (ret < 0) {
> > + error_report("Error enabling host notifiers: %d", -ret);
> > + return;
> > + }
> > +
> > + ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, true);
> > + if (ret < 0) {
> > + error_report("Error binding guest notifier: %d", -ret);
> > + goto err_host_notifiers;
> > + }
> > +
> > + fs->vhost_dev.acked_features = vdev->guest_features;
> > + ret = vhost_dev_start(&fs->vhost_dev, vdev);
> > + if (ret < 0) {
> > + error_report("Error starting vhost: %d", -ret);
> > + goto err_guest_notifiers;
> > + }
> > +
> > + /*
> > + * guest_notifier_mask/pending not used yet, so just unmask
> > + * everything here. virtio-pci will do the right thing by
> > + * enabling/disabling irqfd.
> > + */
> > + for (i = 0; i < fs->vhost_dev.nvqs; i++) {
> > + vhost_virtqueue_mask(&fs->vhost_dev, vdev, i, false);
> > + }
> > +
> > + return;
> > +
> > +err_guest_notifiers:
> > + k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
> > +err_host_notifiers:
> > + vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
> > +}
> > +
> > +static void vuf_stop(VirtIODevice *vdev)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> > + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> > + int ret;
> > +
> > + if (!k->set_guest_notifiers) {
> > + return;
> > + }
> > +
> > + vhost_dev_stop(&fs->vhost_dev, vdev);
> > +
> > + ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
> > + if (ret < 0) {
> > + error_report("vhost guest notifier cleanup failed: %d", ret);
> > + return;
> > + }
> > +
> > + vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
> > +}
> > +
> > +static void vuf_set_status(VirtIODevice *vdev, uint8_t status)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > + bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
> > +
> > + if (!vdev->vm_running) {
> > + should_start = false;
> > + }
> > +
> > + if (fs->vhost_dev.started == should_start) {
> > + return;
> > + }
> > +
> > + if (should_start) {
> > + vuf_start(vdev);
> > + } else {
> > + vuf_stop(vdev);
> > + }
> > +}
>
> It looks like you could have benefited from backends/vhost-user.c
>
> This would allow to factor out some common code and properties used by
> vhost-user devices (currently gpu & input, but more could be
> converted).
>
> Advantage is that if we add a new mechanism, say to start helpers
> (like I propose earlier), all devices using that could benefit it more
> easily (in theory).
It looks like that came along after we originally wrote this;
is that something I can retrofit sometime later then without
breaking anything?
Dave
> > +
> > +static uint64_t vuf_get_features(VirtIODevice *vdev,
> > + uint64_t requested_features,
> > + Error **errp)
> > +{
> > + /* No feature bits used yet */
> > + return requested_features;
> > +}
> > +
> > +static void vuf_handle_output(VirtIODevice *vdev, VirtQueue *vq)
> > +{
> > + /*
> > + * Not normally called; it's the daemon that handles the queue;
> > + * however virtio's cleanup path can call this.
> > + */
> > +}
> > +
> > +static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
> > + bool mask)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > +
> > + vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
> > +}
> > +
> > +static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > +
> > + return vhost_virtqueue_pending(&fs->vhost_dev, idx);
> > +}
> > +
> > +static void vuf_device_realize(DeviceState *dev, Error **errp)
> > +{
> > + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> > + VHostUserFS *fs = VHOST_USER_FS(dev);
> > + unsigned int i;
> > + size_t len;
> > + int ret;
> > +
> > + if (!fs->conf.chardev.chr) {
> > + error_setg(errp, "missing chardev");
> > + return;
> > + }
> > +
> > + if (!fs->conf.tag) {
> > + error_setg(errp, "missing tag property");
> > + return;
> > + }
> > + len = strlen(fs->conf.tag);
> > + if (len == 0) {
> > + error_setg(errp, "tag property cannot be empty");
> > + return;
> > + }
> > + if (len > sizeof_field(struct virtio_fs_config, tag)) {
> > + error_setg(errp, "tag property must be %zu bytes or less",
> > + sizeof_field(struct virtio_fs_config, tag));
> > + return;
> > + }
> > +
> > + if (fs->conf.num_request_queues == 0) {
> > + error_setg(errp, "num-request-queues property must be larger than 0");
> > + return;
> > + }
> > +
> > + if (!is_power_of_2(fs->conf.queue_size)) {
> > + error_setg(errp, "queue-size property must be a power of 2");
> > + return;
> > + }
> > +
> > + if (fs->conf.queue_size > VIRTQUEUE_MAX_SIZE) {
> > + error_setg(errp, "queue-size property must be %u or smaller",
> > + VIRTQUEUE_MAX_SIZE);
> > + return;
> > + }
> > +
> > + if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev, errp)) {
> > + return;
> > + }
> > +
> > + virtio_init(vdev, "vhost-user-fs", VIRTIO_ID_FS,
> > + sizeof(struct virtio_fs_config));
> > +
> > + /* Hiprio queue */
> > + virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
> > +
> > + /* Request queues */
> > + for (i = 0; i < fs->conf.num_request_queues; i++) {
> > + virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
> > + }
> > +
> > + /* 1 high prio queue, plus the number configured */
> > + fs->vhost_dev.nvqs = 1 + fs->conf.num_request_queues;
> > + fs->vhost_dev.vqs = g_new0(struct vhost_virtqueue, fs->vhost_dev.nvqs);
> > + ret = vhost_dev_init(&fs->vhost_dev, &fs->vhost_user,
> > + VHOST_BACKEND_TYPE_USER, 0);
> > + if (ret < 0) {
> > + error_setg_errno(errp, -ret, "vhost_dev_init failed");
> > + goto err_virtio;
> > + }
> > +
> > + return;
> > +
> > +err_virtio:
> > + vhost_user_cleanup(&fs->vhost_user);
> > + virtio_cleanup(vdev);
> > + g_free(fs->vhost_dev.vqs);
> > + return;
> > +}
> > +
> > +static void vuf_device_unrealize(DeviceState *dev, Error **errp)
> > +{
> > + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> > + VHostUserFS *fs = VHOST_USER_FS(dev);
> > +
> > + /* This will stop vhost backend if appropriate. */
> > + vuf_set_status(vdev, 0);
> > +
> > + vhost_dev_cleanup(&fs->vhost_dev);
> > +
> > + vhost_user_cleanup(&fs->vhost_user);
> > +
> > + virtio_cleanup(vdev);
> > + g_free(fs->vhost_dev.vqs);
> > + fs->vhost_dev.vqs = NULL;
> > +}
> > +
> > +static const VMStateDescription vuf_vmstate = {
> > + .name = "vhost-user-fs",
> > + .unmigratable = 1,
> > +};
> > +
> > +static Property vuf_properties[] = {
> > + DEFINE_PROP_CHR("chardev", VHostUserFS, conf.chardev),
> > + DEFINE_PROP_STRING("tag", VHostUserFS, conf.tag),
> > + DEFINE_PROP_UINT16("num-request-queues", VHostUserFS,
> > + conf.num_request_queues, 1),
> > + DEFINE_PROP_UINT16("queue-size", VHostUserFS, conf.queue_size, 128),
> > + DEFINE_PROP_STRING("vhostfd", VHostUserFS, conf.vhostfd),
> > + DEFINE_PROP_END_OF_LIST(),
> > +};
> > +
> > +static void vuf_class_init(ObjectClass *klass, void *data)
> > +{
> > + DeviceClass *dc = DEVICE_CLASS(klass);
> > + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
> > +
> > + dc->props = vuf_properties;
> > + dc->vmsd = &vuf_vmstate;
> > + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> > + vdc->realize = vuf_device_realize;
> > + vdc->unrealize = vuf_device_unrealize;
> > + vdc->get_features = vuf_get_features;
> > + vdc->get_config = vuf_get_config;
> > + vdc->set_status = vuf_set_status;
> > + vdc->guest_notifier_mask = vuf_guest_notifier_mask;
> > + vdc->guest_notifier_pending = vuf_guest_notifier_pending;
> > +}
> > +
> > +static const TypeInfo vuf_info = {
> > + .name = TYPE_VHOST_USER_FS,
> > + .parent = TYPE_VIRTIO_DEVICE,
> > + .instance_size = sizeof(VHostUserFS),
> > + .class_init = vuf_class_init,
> > +};
> > +
> > +static void vuf_register_types(void)
> > +{
> > + type_register_static(&vuf_info);
> > +}
> > +
> > +type_init(vuf_register_types)
> > diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h
> > new file mode 100644
> > index 0000000000..539885b458
> > --- /dev/null
> > +++ b/include/hw/virtio/vhost-user-fs.h
> > @@ -0,0 +1,45 @@
> > +/*
> > + * Vhost-user filesystem virtio device
> > + *
> > + * Copyright 2018-2019 Red Hat, Inc.
> > + *
> > + * Authors:
> > + * Stefan Hajnoczi <stefanha@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or
> > + * (at your option) any later version. See the COPYING file in the
> > + * top-level directory.
> > + */
> > +
> > +#ifndef _QEMU_VHOST_USER_FS_H
> > +#define _QEMU_VHOST_USER_FS_H
> > +
> > +#include "hw/virtio/virtio.h"
> > +#include "hw/virtio/vhost.h"
> > +#include "hw/virtio/vhost-user.h"
> > +#include "chardev/char-fe.h"
> > +
> > +#define TYPE_VHOST_USER_FS "vhost-user-fs-device"
> > +#define VHOST_USER_FS(obj) \
> > + OBJECT_CHECK(VHostUserFS, (obj), TYPE_VHOST_USER_FS)
> > +
> > +typedef struct {
> > + CharBackend chardev;
> > + char *tag;
> > + uint16_t num_request_queues;
> > + uint16_t queue_size;
> > + char *vhostfd;
> > +} VHostUserFSConf;
> > +
> > +typedef struct {
> > + /*< private >*/
> > + VirtIODevice parent;
> > + VHostUserFSConf conf;
> > + struct vhost_virtqueue *vhost_vqs;
> > + struct vhost_dev vhost_dev;
> > + VhostUserState vhost_user;
> > +
> > + /*< public >*/
> > +} VHostUserFS;
> > +
> > +#endif /* _QEMU_VHOST_USER_FS_H */
> > --
> > 2.21.0
> >
> >
>
>
> --
> Marc-André Lureau
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH v4 2/3] virtio: add vhost-user-fs base device
2019-10-01 17:29 ` Dr. David Alan Gilbert
@ 2019-10-02 15:07 ` Marc-André Lureau
0 siblings, 0 replies; 60+ messages in thread
From: Marc-André Lureau @ 2019-10-02 15:07 UTC (permalink / raw)
To: Dr. David Alan Gilbert
Cc: mszeredi, Michael S. Tsirkin, Cornelia Huck, QEMU,
Stefan Hajnoczi, vgoyal
Hi
On Tue, Oct 1, 2019 at 9:29 PM Dr. David Alan Gilbert
<dgilbert@redhat.com> wrote:
>
> * Marc-André Lureau (marcandre.lureau@gmail.com) wrote:
> > Hi
> >
> > On Mon, Sep 30, 2019 at 2:52 PM Dr. David Alan Gilbert (git)
> > <dgilbert@redhat.com> wrote:
> > >
> > > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> > >
> > > The virtio-fs virtio device provides shared file system access using
> > > the FUSE protocol carried over virtio.
> > > The actual file server is implemented in an external vhost-user-fs device
> > > backend process.
> > >
> > > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> > > Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
> > > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > > ---
> > > configure | 13 ++
> > > hw/virtio/Makefile.objs | 1 +
> > > hw/virtio/vhost-user-fs.c | 299 ++++++++++++++++++++++++++++++
> > > include/hw/virtio/vhost-user-fs.h | 45 +++++
> > > 4 files changed, 358 insertions(+)
> > > create mode 100644 hw/virtio/vhost-user-fs.c
> > > create mode 100644 include/hw/virtio/vhost-user-fs.h
> > >
> > > diff --git a/configure b/configure
> > > index 542f6aea3f..204cbe351e 100755
> > > --- a/configure
> > > +++ b/configure
> > > @@ -381,6 +381,7 @@ vhost_crypto=""
> > > vhost_scsi=""
> > > vhost_vsock=""
> > > vhost_user=""
> > > +vhost_user_fs=""
> > > kvm="no"
> > > hax="no"
> > > hvf="no"
> > > @@ -1293,6 +1294,10 @@ for opt do
> > > ;;
> > > --enable-vhost-vsock) vhost_vsock="yes"
> > > ;;
> > > + --disable-vhost-user-fs) vhost_user_fs="no"
> > > + ;;
> > > + --enable-vhost-user-fs) vhost_user_fs="yes"
> > > + ;;
> > > --disable-opengl) opengl="no"
> > > ;;
> > > --enable-opengl) opengl="yes"
> > > @@ -2236,6 +2241,10 @@ test "$vhost_crypto" = "" && vhost_crypto=$vhost_user
> > > if test "$vhost_crypto" = "yes" && test "$vhost_user" = "no"; then
> > > error_exit "--enable-vhost-crypto requires --enable-vhost-user"
> > > fi
> > > +test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
> > > +if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
> > > + error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
> > > +fi
> > >
> > > # OR the vhost-kernel and vhost-user values for simplicity
> > > if test "$vhost_net" = ""; then
> > > @@ -6377,6 +6386,7 @@ echo "vhost-crypto support $vhost_crypto"
> > > echo "vhost-scsi support $vhost_scsi"
> > > echo "vhost-vsock support $vhost_vsock"
> > > echo "vhost-user support $vhost_user"
> > > +echo "vhost-user-fs support $vhost_user_fs"
> > > echo "Trace backends $trace_backends"
> > > if have_backend "simple"; then
> > > echo "Trace output file $trace_file-<pid>"
> > > @@ -6873,6 +6883,9 @@ fi
> > > if test "$vhost_user" = "yes" ; then
> > > echo "CONFIG_VHOST_USER=y" >> $config_host_mak
> > > fi
> > > +if test "$vhost_user_fs" = "yes" ; then
> > > + echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
> > > +fi
> > > if test "$blobs" = "yes" ; then
> > > echo "INSTALL_BLOBS=yes" >> $config_host_mak
> > > fi
> > > diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> > > index 964ce78607..47ffbf22c4 100644
> > > --- a/hw/virtio/Makefile.objs
> > > +++ b/hw/virtio/Makefile.objs
> > > @@ -11,6 +11,7 @@ common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
> > > common-obj-$(CONFIG_VIRTIO_MMIO) += virtio-mmio.o
> > > obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
> > > obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
> > > +obj-$(CONFIG_VHOST_USER_FS) += vhost-user-fs.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
> > > diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> > > new file mode 100644
> > > index 0000000000..f0df7f4746
> > > --- /dev/null
> > > +++ b/hw/virtio/vhost-user-fs.c
> > > @@ -0,0 +1,299 @@
> > > +/*
> > > + * Vhost-user filesystem virtio device
> > > + *
> > > + * Copyright 2018-2019 Red Hat, Inc.
> > > + *
> > > + * Authors:
> > > + * Stefan Hajnoczi <stefanha@redhat.com>
> > > + *
> > > + * This work is licensed under the terms of the GNU GPL, version 2 or
> > > + * (at your option) any later version. See the COPYING file in the
> > > + * top-level directory.
> > > + */
> > > +
> > > +#include "qemu/osdep.h"
> > > +#include <sys/ioctl.h>
> > > +#include "standard-headers/linux/virtio_fs.h"
> > > +#include "qapi/error.h"
> > > +#include "hw/qdev-properties.h"
> > > +#include "hw/virtio/virtio-bus.h"
> > > +#include "hw/virtio/virtio-access.h"
> > > +#include "qemu/error-report.h"
> > > +#include "hw/virtio/vhost-user-fs.h"
> > > +#include "monitor/monitor.h"
> > > +
> > > +static void vuf_get_config(VirtIODevice *vdev, uint8_t *config)
> > > +{
> > > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > > + struct virtio_fs_config fscfg = {};
> > > +
> > > + memcpy((char *)fscfg.tag, fs->conf.tag,
> > > + MIN(strlen(fs->conf.tag) + 1, sizeof(fscfg.tag)));
> > > +
> > > + virtio_stl_p(vdev, &fscfg.num_request_queues, fs->conf.num_request_queues);
> > > +
> > > + memcpy(config, &fscfg, sizeof(fscfg));
> > > +}
> > > +
> > > +static void vuf_start(VirtIODevice *vdev)
> > > +{
> > > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > > + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> > > + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> > > + int ret;
> > > + int i;
> > > +
> > > + if (!k->set_guest_notifiers) {
> > > + error_report("binding does not support guest notifiers");
> > > + return;
> > > + }
> > > +
> > > + ret = vhost_dev_enable_notifiers(&fs->vhost_dev, vdev);
> > > + if (ret < 0) {
> > > + error_report("Error enabling host notifiers: %d", -ret);
> > > + return;
> > > + }
> > > +
> > > + ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, true);
> > > + if (ret < 0) {
> > > + error_report("Error binding guest notifier: %d", -ret);
> > > + goto err_host_notifiers;
> > > + }
> > > +
> > > + fs->vhost_dev.acked_features = vdev->guest_features;
> > > + ret = vhost_dev_start(&fs->vhost_dev, vdev);
> > > + if (ret < 0) {
> > > + error_report("Error starting vhost: %d", -ret);
> > > + goto err_guest_notifiers;
> > > + }
> > > +
> > > + /*
> > > + * guest_notifier_mask/pending not used yet, so just unmask
> > > + * everything here. virtio-pci will do the right thing by
> > > + * enabling/disabling irqfd.
> > > + */
> > > + for (i = 0; i < fs->vhost_dev.nvqs; i++) {
> > > + vhost_virtqueue_mask(&fs->vhost_dev, vdev, i, false);
> > > + }
> > > +
> > > + return;
> > > +
> > > +err_guest_notifiers:
> > > + k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
> > > +err_host_notifiers:
> > > + vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
> > > +}
> > > +
> > > +static void vuf_stop(VirtIODevice *vdev)
> > > +{
> > > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > > + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> > > + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> > > + int ret;
> > > +
> > > + if (!k->set_guest_notifiers) {
> > > + return;
> > > + }
> > > +
> > > + vhost_dev_stop(&fs->vhost_dev, vdev);
> > > +
> > > + ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
> > > + if (ret < 0) {
> > > + error_report("vhost guest notifier cleanup failed: %d", ret);
> > > + return;
> > > + }
> > > +
> > > + vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
> > > +}
> > > +
> > > +static void vuf_set_status(VirtIODevice *vdev, uint8_t status)
> > > +{
> > > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > > + bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
> > > +
> > > + if (!vdev->vm_running) {
> > > + should_start = false;
> > > + }
> > > +
> > > + if (fs->vhost_dev.started == should_start) {
> > > + return;
> > > + }
> > > +
> > > + if (should_start) {
> > > + vuf_start(vdev);
> > > + } else {
> > > + vuf_stop(vdev);
> > > + }
> > > +}
> >
> > It looks like you could have benefited from backends/vhost-user.c
> >
> > This would allow to factor out some common code and properties used by
> > vhost-user devices (currently gpu & input, but more could be
> > converted).
> >
> > Advantage is that if we add a new mechanism, say to start helpers
> > (like I propose earlier), all devices using that could benefit it more
> > easily (in theory).
>
> It looks like that came along after we originally wrote this;
> is that something I can retrofit sometime later then without
> breaking anything?
I think so, this can be done later.
>
> Dave
>
> > > +
> > > +static uint64_t vuf_get_features(VirtIODevice *vdev,
> > > + uint64_t requested_features,
> > > + Error **errp)
> > > +{
> > > + /* No feature bits used yet */
> > > + return requested_features;
> > > +}
> > > +
> > > +static void vuf_handle_output(VirtIODevice *vdev, VirtQueue *vq)
> > > +{
> > > + /*
> > > + * Not normally called; it's the daemon that handles the queue;
> > > + * however virtio's cleanup path can call this.
> > > + */
> > > +}
> > > +
> > > +static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
> > > + bool mask)
> > > +{
> > > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > > +
> > > + vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
> > > +}
> > > +
> > > +static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
> > > +{
> > > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > > +
> > > + return vhost_virtqueue_pending(&fs->vhost_dev, idx);
> > > +}
> > > +
> > > +static void vuf_device_realize(DeviceState *dev, Error **errp)
> > > +{
> > > + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> > > + VHostUserFS *fs = VHOST_USER_FS(dev);
> > > + unsigned int i;
> > > + size_t len;
> > > + int ret;
> > > +
> > > + if (!fs->conf.chardev.chr) {
> > > + error_setg(errp, "missing chardev");
> > > + return;
> > > + }
> > > +
> > > + if (!fs->conf.tag) {
> > > + error_setg(errp, "missing tag property");
> > > + return;
> > > + }
> > > + len = strlen(fs->conf.tag);
> > > + if (len == 0) {
> > > + error_setg(errp, "tag property cannot be empty");
> > > + return;
> > > + }
> > > + if (len > sizeof_field(struct virtio_fs_config, tag)) {
> > > + error_setg(errp, "tag property must be %zu bytes or less",
> > > + sizeof_field(struct virtio_fs_config, tag));
> > > + return;
> > > + }
> > > +
> > > + if (fs->conf.num_request_queues == 0) {
> > > + error_setg(errp, "num-request-queues property must be larger than 0");
> > > + return;
> > > + }
> > > +
> > > + if (!is_power_of_2(fs->conf.queue_size)) {
> > > + error_setg(errp, "queue-size property must be a power of 2");
> > > + return;
> > > + }
> > > +
> > > + if (fs->conf.queue_size > VIRTQUEUE_MAX_SIZE) {
> > > + error_setg(errp, "queue-size property must be %u or smaller",
> > > + VIRTQUEUE_MAX_SIZE);
> > > + return;
> > > + }
> > > +
> > > + if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev, errp)) {
> > > + return;
> > > + }
> > > +
> > > + virtio_init(vdev, "vhost-user-fs", VIRTIO_ID_FS,
> > > + sizeof(struct virtio_fs_config));
> > > +
> > > + /* Hiprio queue */
> > > + virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
> > > +
> > > + /* Request queues */
> > > + for (i = 0; i < fs->conf.num_request_queues; i++) {
> > > + virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
> > > + }
> > > +
> > > + /* 1 high prio queue, plus the number configured */
> > > + fs->vhost_dev.nvqs = 1 + fs->conf.num_request_queues;
> > > + fs->vhost_dev.vqs = g_new0(struct vhost_virtqueue, fs->vhost_dev.nvqs);
> > > + ret = vhost_dev_init(&fs->vhost_dev, &fs->vhost_user,
> > > + VHOST_BACKEND_TYPE_USER, 0);
> > > + if (ret < 0) {
> > > + error_setg_errno(errp, -ret, "vhost_dev_init failed");
> > > + goto err_virtio;
> > > + }
> > > +
> > > + return;
> > > +
> > > +err_virtio:
> > > + vhost_user_cleanup(&fs->vhost_user);
> > > + virtio_cleanup(vdev);
> > > + g_free(fs->vhost_dev.vqs);
> > > + return;
> > > +}
> > > +
> > > +static void vuf_device_unrealize(DeviceState *dev, Error **errp)
> > > +{
> > > + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> > > + VHostUserFS *fs = VHOST_USER_FS(dev);
> > > +
> > > + /* This will stop vhost backend if appropriate. */
> > > + vuf_set_status(vdev, 0);
> > > +
> > > + vhost_dev_cleanup(&fs->vhost_dev);
> > > +
> > > + vhost_user_cleanup(&fs->vhost_user);
> > > +
> > > + virtio_cleanup(vdev);
> > > + g_free(fs->vhost_dev.vqs);
> > > + fs->vhost_dev.vqs = NULL;
> > > +}
> > > +
> > > +static const VMStateDescription vuf_vmstate = {
> > > + .name = "vhost-user-fs",
> > > + .unmigratable = 1,
> > > +};
> > > +
> > > +static Property vuf_properties[] = {
> > > + DEFINE_PROP_CHR("chardev", VHostUserFS, conf.chardev),
> > > + DEFINE_PROP_STRING("tag", VHostUserFS, conf.tag),
> > > + DEFINE_PROP_UINT16("num-request-queues", VHostUserFS,
> > > + conf.num_request_queues, 1),
> > > + DEFINE_PROP_UINT16("queue-size", VHostUserFS, conf.queue_size, 128),
> > > + DEFINE_PROP_STRING("vhostfd", VHostUserFS, conf.vhostfd),
> > > + DEFINE_PROP_END_OF_LIST(),
> > > +};
> > > +
> > > +static void vuf_class_init(ObjectClass *klass, void *data)
> > > +{
> > > + DeviceClass *dc = DEVICE_CLASS(klass);
> > > + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
> > > +
> > > + dc->props = vuf_properties;
> > > + dc->vmsd = &vuf_vmstate;
> > > + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> > > + vdc->realize = vuf_device_realize;
> > > + vdc->unrealize = vuf_device_unrealize;
> > > + vdc->get_features = vuf_get_features;
> > > + vdc->get_config = vuf_get_config;
> > > + vdc->set_status = vuf_set_status;
> > > + vdc->guest_notifier_mask = vuf_guest_notifier_mask;
> > > + vdc->guest_notifier_pending = vuf_guest_notifier_pending;
> > > +}
> > > +
> > > +static const TypeInfo vuf_info = {
> > > + .name = TYPE_VHOST_USER_FS,
> > > + .parent = TYPE_VIRTIO_DEVICE,
> > > + .instance_size = sizeof(VHostUserFS),
> > > + .class_init = vuf_class_init,
> > > +};
> > > +
> > > +static void vuf_register_types(void)
> > > +{
> > > + type_register_static(&vuf_info);
> > > +}
> > > +
> > > +type_init(vuf_register_types)
> > > diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h
> > > new file mode 100644
> > > index 0000000000..539885b458
> > > --- /dev/null
> > > +++ b/include/hw/virtio/vhost-user-fs.h
> > > @@ -0,0 +1,45 @@
> > > +/*
> > > + * Vhost-user filesystem virtio device
> > > + *
> > > + * Copyright 2018-2019 Red Hat, Inc.
> > > + *
> > > + * Authors:
> > > + * Stefan Hajnoczi <stefanha@redhat.com>
> > > + *
> > > + * This work is licensed under the terms of the GNU GPL, version 2 or
> > > + * (at your option) any later version. See the COPYING file in the
> > > + * top-level directory.
> > > + */
> > > +
> > > +#ifndef _QEMU_VHOST_USER_FS_H
> > > +#define _QEMU_VHOST_USER_FS_H
> > > +
> > > +#include "hw/virtio/virtio.h"
> > > +#include "hw/virtio/vhost.h"
> > > +#include "hw/virtio/vhost-user.h"
> > > +#include "chardev/char-fe.h"
> > > +
> > > +#define TYPE_VHOST_USER_FS "vhost-user-fs-device"
> > > +#define VHOST_USER_FS(obj) \
> > > + OBJECT_CHECK(VHostUserFS, (obj), TYPE_VHOST_USER_FS)
> > > +
> > > +typedef struct {
> > > + CharBackend chardev;
> > > + char *tag;
> > > + uint16_t num_request_queues;
> > > + uint16_t queue_size;
> > > + char *vhostfd;
> > > +} VHostUserFSConf;
> > > +
> > > +typedef struct {
> > > + /*< private >*/
> > > + VirtIODevice parent;
> > > + VHostUserFSConf conf;
> > > + struct vhost_virtqueue *vhost_vqs;
> > > + struct vhost_dev vhost_dev;
> > > + VhostUserState vhost_user;
> > > +
> > > + /*< public >*/
> > > +} VHostUserFS;
> > > +
> > > +#endif /* _QEMU_VHOST_USER_FS_H */
> > > --
> > > 2.21.0
> > >
> > >
> >
> >
> > --
> > Marc-André Lureau
> --
> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 60+ messages in thread
* [PULL 18/19] virtio: add vhost-user-fs base device
2019-09-30 10:51 ` [PATCH v4 2/3] virtio: add vhost-user-fs base device Dr. David Alan Gilbert (git)
2019-09-30 11:06 ` Marc-André Lureau
@ 2019-10-05 22:00 ` Michael S. Tsirkin
2019-10-07 5:57 ` Igor Mammedov
2 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 22:00 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Sebastien Boeuf, Dr. David Alan Gilbert, Stefan Hajnoczi
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
The virtio-fs virtio device provides shared file system access using
the FUSE protocol carried over virtio.
The actual file server is implemented in an external vhost-user-fs device
backend process.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-Id: <20190930105135.27244-3-dgilbert@redhat.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
configure | 13 ++
hw/virtio/Makefile.objs | 1 +
hw/virtio/vhost-user-fs.c | 299 ++++++++++++++++++++++++++++++
include/hw/virtio/vhost-user-fs.h | 45 +++++
4 files changed, 358 insertions(+)
create mode 100644 hw/virtio/vhost-user-fs.c
create mode 100644 include/hw/virtio/vhost-user-fs.h
diff --git a/configure b/configure
index 8f8446f52b..7bd01b201c 100755
--- a/configure
+++ b/configure
@@ -381,6 +381,7 @@ vhost_crypto=""
vhost_scsi=""
vhost_vsock=""
vhost_user=""
+vhost_user_fs=""
kvm="no"
hax="no"
hvf="no"
@@ -1293,6 +1294,10 @@ for opt do
;;
--enable-vhost-vsock) vhost_vsock="yes"
;;
+ --disable-vhost-user-fs) vhost_user_fs="no"
+ ;;
+ --enable-vhost-user-fs) vhost_user_fs="yes"
+ ;;
--disable-opengl) opengl="no"
;;
--enable-opengl) opengl="yes"
@@ -2236,6 +2241,10 @@ test "$vhost_crypto" = "" && vhost_crypto=$vhost_user
if test "$vhost_crypto" = "yes" && test "$vhost_user" = "no"; then
error_exit "--enable-vhost-crypto requires --enable-vhost-user"
fi
+test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
+if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
+ error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
+fi
# OR the vhost-kernel and vhost-user values for simplicity
if test "$vhost_net" = ""; then
@@ -6377,6 +6386,7 @@ echo "vhost-crypto support $vhost_crypto"
echo "vhost-scsi support $vhost_scsi"
echo "vhost-vsock support $vhost_vsock"
echo "vhost-user support $vhost_user"
+echo "vhost-user-fs support $vhost_user_fs"
echo "Trace backends $trace_backends"
if have_backend "simple"; then
echo "Trace output file $trace_file-<pid>"
@@ -6873,6 +6883,9 @@ fi
if test "$vhost_user" = "yes" ; then
echo "CONFIG_VHOST_USER=y" >> $config_host_mak
fi
+if test "$vhost_user_fs" = "yes" ; then
+ echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
+fi
if test "$blobs" = "yes" ; then
echo "INSTALL_BLOBS=yes" >> $config_host_mak
fi
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 964ce78607..47ffbf22c4 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -11,6 +11,7 @@ common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
common-obj-$(CONFIG_VIRTIO_MMIO) += virtio-mmio.o
obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
+obj-$(CONFIG_VHOST_USER_FS) += vhost-user-fs.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
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
new file mode 100644
index 0000000000..f0df7f4746
--- /dev/null
+++ b/hw/virtio/vhost-user-fs.c
@@ -0,0 +1,299 @@
+/*
+ * Vhost-user filesystem virtio device
+ *
+ * Copyright 2018-2019 Red Hat, Inc.
+ *
+ * Authors:
+ * Stefan Hajnoczi <stefanha@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include <sys/ioctl.h>
+#include "standard-headers/linux/virtio_fs.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/virtio-access.h"
+#include "qemu/error-report.h"
+#include "hw/virtio/vhost-user-fs.h"
+#include "monitor/monitor.h"
+
+static void vuf_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+ struct virtio_fs_config fscfg = {};
+
+ memcpy((char *)fscfg.tag, fs->conf.tag,
+ MIN(strlen(fs->conf.tag) + 1, sizeof(fscfg.tag)));
+
+ virtio_stl_p(vdev, &fscfg.num_request_queues, fs->conf.num_request_queues);
+
+ memcpy(config, &fscfg, sizeof(fscfg));
+}
+
+static void vuf_start(VirtIODevice *vdev)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+ int ret;
+ int i;
+
+ if (!k->set_guest_notifiers) {
+ error_report("binding does not support guest notifiers");
+ return;
+ }
+
+ ret = vhost_dev_enable_notifiers(&fs->vhost_dev, vdev);
+ if (ret < 0) {
+ error_report("Error enabling host notifiers: %d", -ret);
+ return;
+ }
+
+ ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, true);
+ if (ret < 0) {
+ error_report("Error binding guest notifier: %d", -ret);
+ goto err_host_notifiers;
+ }
+
+ fs->vhost_dev.acked_features = vdev->guest_features;
+ ret = vhost_dev_start(&fs->vhost_dev, vdev);
+ if (ret < 0) {
+ error_report("Error starting vhost: %d", -ret);
+ goto err_guest_notifiers;
+ }
+
+ /*
+ * guest_notifier_mask/pending not used yet, so just unmask
+ * everything here. virtio-pci will do the right thing by
+ * enabling/disabling irqfd.
+ */
+ for (i = 0; i < fs->vhost_dev.nvqs; i++) {
+ vhost_virtqueue_mask(&fs->vhost_dev, vdev, i, false);
+ }
+
+ return;
+
+err_guest_notifiers:
+ k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
+err_host_notifiers:
+ vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
+}
+
+static void vuf_stop(VirtIODevice *vdev)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+ int ret;
+
+ if (!k->set_guest_notifiers) {
+ return;
+ }
+
+ vhost_dev_stop(&fs->vhost_dev, vdev);
+
+ ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
+ if (ret < 0) {
+ error_report("vhost guest notifier cleanup failed: %d", ret);
+ return;
+ }
+
+ vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
+}
+
+static void vuf_set_status(VirtIODevice *vdev, uint8_t status)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+ bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
+
+ if (!vdev->vm_running) {
+ should_start = false;
+ }
+
+ if (fs->vhost_dev.started == should_start) {
+ return;
+ }
+
+ if (should_start) {
+ vuf_start(vdev);
+ } else {
+ vuf_stop(vdev);
+ }
+}
+
+static uint64_t vuf_get_features(VirtIODevice *vdev,
+ uint64_t requested_features,
+ Error **errp)
+{
+ /* No feature bits used yet */
+ return requested_features;
+}
+
+static void vuf_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+ /*
+ * Not normally called; it's the daemon that handles the queue;
+ * however virtio's cleanup path can call this.
+ */
+}
+
+static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
+ bool mask)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+
+ vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
+}
+
+static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
+{
+ VHostUserFS *fs = VHOST_USER_FS(vdev);
+
+ return vhost_virtqueue_pending(&fs->vhost_dev, idx);
+}
+
+static void vuf_device_realize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VHostUserFS *fs = VHOST_USER_FS(dev);
+ unsigned int i;
+ size_t len;
+ int ret;
+
+ if (!fs->conf.chardev.chr) {
+ error_setg(errp, "missing chardev");
+ return;
+ }
+
+ if (!fs->conf.tag) {
+ error_setg(errp, "missing tag property");
+ return;
+ }
+ len = strlen(fs->conf.tag);
+ if (len == 0) {
+ error_setg(errp, "tag property cannot be empty");
+ return;
+ }
+ if (len > sizeof_field(struct virtio_fs_config, tag)) {
+ error_setg(errp, "tag property must be %zu bytes or less",
+ sizeof_field(struct virtio_fs_config, tag));
+ return;
+ }
+
+ if (fs->conf.num_request_queues == 0) {
+ error_setg(errp, "num-request-queues property must be larger than 0");
+ return;
+ }
+
+ if (!is_power_of_2(fs->conf.queue_size)) {
+ error_setg(errp, "queue-size property must be a power of 2");
+ return;
+ }
+
+ if (fs->conf.queue_size > VIRTQUEUE_MAX_SIZE) {
+ error_setg(errp, "queue-size property must be %u or smaller",
+ VIRTQUEUE_MAX_SIZE);
+ return;
+ }
+
+ if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev, errp)) {
+ return;
+ }
+
+ virtio_init(vdev, "vhost-user-fs", VIRTIO_ID_FS,
+ sizeof(struct virtio_fs_config));
+
+ /* Hiprio queue */
+ virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
+
+ /* Request queues */
+ for (i = 0; i < fs->conf.num_request_queues; i++) {
+ virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
+ }
+
+ /* 1 high prio queue, plus the number configured */
+ fs->vhost_dev.nvqs = 1 + fs->conf.num_request_queues;
+ fs->vhost_dev.vqs = g_new0(struct vhost_virtqueue, fs->vhost_dev.nvqs);
+ ret = vhost_dev_init(&fs->vhost_dev, &fs->vhost_user,
+ VHOST_BACKEND_TYPE_USER, 0);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "vhost_dev_init failed");
+ goto err_virtio;
+ }
+
+ return;
+
+err_virtio:
+ vhost_user_cleanup(&fs->vhost_user);
+ virtio_cleanup(vdev);
+ g_free(fs->vhost_dev.vqs);
+ return;
+}
+
+static void vuf_device_unrealize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VHostUserFS *fs = VHOST_USER_FS(dev);
+
+ /* This will stop vhost backend if appropriate. */
+ vuf_set_status(vdev, 0);
+
+ vhost_dev_cleanup(&fs->vhost_dev);
+
+ vhost_user_cleanup(&fs->vhost_user);
+
+ virtio_cleanup(vdev);
+ g_free(fs->vhost_dev.vqs);
+ fs->vhost_dev.vqs = NULL;
+}
+
+static const VMStateDescription vuf_vmstate = {
+ .name = "vhost-user-fs",
+ .unmigratable = 1,
+};
+
+static Property vuf_properties[] = {
+ DEFINE_PROP_CHR("chardev", VHostUserFS, conf.chardev),
+ DEFINE_PROP_STRING("tag", VHostUserFS, conf.tag),
+ DEFINE_PROP_UINT16("num-request-queues", VHostUserFS,
+ conf.num_request_queues, 1),
+ DEFINE_PROP_UINT16("queue-size", VHostUserFS, conf.queue_size, 128),
+ DEFINE_PROP_STRING("vhostfd", VHostUserFS, conf.vhostfd),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vuf_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+
+ dc->props = vuf_properties;
+ dc->vmsd = &vuf_vmstate;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ vdc->realize = vuf_device_realize;
+ vdc->unrealize = vuf_device_unrealize;
+ vdc->get_features = vuf_get_features;
+ vdc->get_config = vuf_get_config;
+ vdc->set_status = vuf_set_status;
+ vdc->guest_notifier_mask = vuf_guest_notifier_mask;
+ vdc->guest_notifier_pending = vuf_guest_notifier_pending;
+}
+
+static const TypeInfo vuf_info = {
+ .name = TYPE_VHOST_USER_FS,
+ .parent = TYPE_VIRTIO_DEVICE,
+ .instance_size = sizeof(VHostUserFS),
+ .class_init = vuf_class_init,
+};
+
+static void vuf_register_types(void)
+{
+ type_register_static(&vuf_info);
+}
+
+type_init(vuf_register_types)
diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h
new file mode 100644
index 0000000000..539885b458
--- /dev/null
+++ b/include/hw/virtio/vhost-user-fs.h
@@ -0,0 +1,45 @@
+/*
+ * Vhost-user filesystem virtio device
+ *
+ * Copyright 2018-2019 Red Hat, Inc.
+ *
+ * Authors:
+ * Stefan Hajnoczi <stefanha@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ */
+
+#ifndef _QEMU_VHOST_USER_FS_H
+#define _QEMU_VHOST_USER_FS_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "chardev/char-fe.h"
+
+#define TYPE_VHOST_USER_FS "vhost-user-fs-device"
+#define VHOST_USER_FS(obj) \
+ OBJECT_CHECK(VHostUserFS, (obj), TYPE_VHOST_USER_FS)
+
+typedef struct {
+ CharBackend chardev;
+ char *tag;
+ uint16_t num_request_queues;
+ uint16_t queue_size;
+ char *vhostfd;
+} VHostUserFSConf;
+
+typedef struct {
+ /*< private >*/
+ VirtIODevice parent;
+ VHostUserFSConf conf;
+ struct vhost_virtqueue *vhost_vqs;
+ struct vhost_dev vhost_dev;
+ VhostUserState vhost_user;
+
+ /*< public >*/
+} VHostUserFS;
+
+#endif /* _QEMU_VHOST_USER_FS_H */
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [PULL 18/19] virtio: add vhost-user-fs base device
2019-09-30 10:51 ` [PATCH v4 2/3] virtio: add vhost-user-fs base device Dr. David Alan Gilbert (git)
2019-09-30 11:06 ` Marc-André Lureau
2019-10-05 22:00 ` [PULL 18/19] " Michael S. Tsirkin
@ 2019-10-07 5:57 ` Igor Mammedov
2019-10-07 7:28 ` Michael S. Tsirkin
2 siblings, 1 reply; 60+ messages in thread
From: Igor Mammedov @ 2019-10-07 5:57 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Peter Maydell, Sebastien Boeuf, qemu-devel, Stefan Hajnoczi,
Dr. David Alan Gilbert
On Sat, 5 Oct 2019 18:00:09 -0400
"Michael S. Tsirkin" <mst@redhat.com> wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> The virtio-fs virtio device provides shared file system access using
> the FUSE protocol carried over virtio.
> The actual file server is implemented in an external vhost-user-fs device
> backend process.
>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> Message-Id: <20190930105135.27244-3-dgilbert@redhat.com>
> Acked-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Michael,
looks like your script for sending pull req is still broken,
this patch in pull req has the same
Message-ID: <20190930105135.27244-3-dgilbert@redhat.com>
as the original email
[PATCH v4 2/3] virtio: add vhost-user-fs base device
even though body differs from original,
which breaks threading on email client side.
Could you fix it please?
> ---
> configure | 13 ++
> hw/virtio/Makefile.objs | 1 +
> hw/virtio/vhost-user-fs.c | 299 ++++++++++++++++++++++++++++++
> include/hw/virtio/vhost-user-fs.h | 45 +++++
> 4 files changed, 358 insertions(+)
> create mode 100644 hw/virtio/vhost-user-fs.c
> create mode 100644 include/hw/virtio/vhost-user-fs.h
>
> diff --git a/configure b/configure
> index 8f8446f52b..7bd01b201c 100755
> --- a/configure
> +++ b/configure
> @@ -381,6 +381,7 @@ vhost_crypto=""
> vhost_scsi=""
> vhost_vsock=""
> vhost_user=""
> +vhost_user_fs=""
> kvm="no"
> hax="no"
> hvf="no"
> @@ -1293,6 +1294,10 @@ for opt do
> ;;
> --enable-vhost-vsock) vhost_vsock="yes"
> ;;
> + --disable-vhost-user-fs) vhost_user_fs="no"
> + ;;
> + --enable-vhost-user-fs) vhost_user_fs="yes"
> + ;;
> --disable-opengl) opengl="no"
> ;;
> --enable-opengl) opengl="yes"
> @@ -2236,6 +2241,10 @@ test "$vhost_crypto" = "" && vhost_crypto=$vhost_user
> if test "$vhost_crypto" = "yes" && test "$vhost_user" = "no"; then
> error_exit "--enable-vhost-crypto requires --enable-vhost-user"
> fi
> +test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
> +if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
> + error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
> +fi
>
> # OR the vhost-kernel and vhost-user values for simplicity
> if test "$vhost_net" = ""; then
> @@ -6377,6 +6386,7 @@ echo "vhost-crypto support $vhost_crypto"
> echo "vhost-scsi support $vhost_scsi"
> echo "vhost-vsock support $vhost_vsock"
> echo "vhost-user support $vhost_user"
> +echo "vhost-user-fs support $vhost_user_fs"
> echo "Trace backends $trace_backends"
> if have_backend "simple"; then
> echo "Trace output file $trace_file-<pid>"
> @@ -6873,6 +6883,9 @@ fi
> if test "$vhost_user" = "yes" ; then
> echo "CONFIG_VHOST_USER=y" >> $config_host_mak
> fi
> +if test "$vhost_user_fs" = "yes" ; then
> + echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
> +fi
> if test "$blobs" = "yes" ; then
> echo "INSTALL_BLOBS=yes" >> $config_host_mak
> fi
> diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> index 964ce78607..47ffbf22c4 100644
> --- a/hw/virtio/Makefile.objs
> +++ b/hw/virtio/Makefile.objs
> @@ -11,6 +11,7 @@ common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
> common-obj-$(CONFIG_VIRTIO_MMIO) += virtio-mmio.o
> obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
> obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
> +obj-$(CONFIG_VHOST_USER_FS) += vhost-user-fs.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
> diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> new file mode 100644
> index 0000000000..f0df7f4746
> --- /dev/null
> +++ b/hw/virtio/vhost-user-fs.c
> @@ -0,0 +1,299 @@
> +/*
> + * Vhost-user filesystem virtio device
> + *
> + * Copyright 2018-2019 Red Hat, Inc.
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version. See the COPYING file in the
> + * top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include <sys/ioctl.h>
> +#include "standard-headers/linux/virtio_fs.h"
> +#include "qapi/error.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/virtio/virtio-bus.h"
> +#include "hw/virtio/virtio-access.h"
> +#include "qemu/error-report.h"
> +#include "hw/virtio/vhost-user-fs.h"
> +#include "monitor/monitor.h"
> +
> +static void vuf_get_config(VirtIODevice *vdev, uint8_t *config)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> + struct virtio_fs_config fscfg = {};
> +
> + memcpy((char *)fscfg.tag, fs->conf.tag,
> + MIN(strlen(fs->conf.tag) + 1, sizeof(fscfg.tag)));
> +
> + virtio_stl_p(vdev, &fscfg.num_request_queues, fs->conf.num_request_queues);
> +
> + memcpy(config, &fscfg, sizeof(fscfg));
> +}
> +
> +static void vuf_start(VirtIODevice *vdev)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> + int ret;
> + int i;
> +
> + if (!k->set_guest_notifiers) {
> + error_report("binding does not support guest notifiers");
> + return;
> + }
> +
> + ret = vhost_dev_enable_notifiers(&fs->vhost_dev, vdev);
> + if (ret < 0) {
> + error_report("Error enabling host notifiers: %d", -ret);
> + return;
> + }
> +
> + ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, true);
> + if (ret < 0) {
> + error_report("Error binding guest notifier: %d", -ret);
> + goto err_host_notifiers;
> + }
> +
> + fs->vhost_dev.acked_features = vdev->guest_features;
> + ret = vhost_dev_start(&fs->vhost_dev, vdev);
> + if (ret < 0) {
> + error_report("Error starting vhost: %d", -ret);
> + goto err_guest_notifiers;
> + }
> +
> + /*
> + * guest_notifier_mask/pending not used yet, so just unmask
> + * everything here. virtio-pci will do the right thing by
> + * enabling/disabling irqfd.
> + */
> + for (i = 0; i < fs->vhost_dev.nvqs; i++) {
> + vhost_virtqueue_mask(&fs->vhost_dev, vdev, i, false);
> + }
> +
> + return;
> +
> +err_guest_notifiers:
> + k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
> +err_host_notifiers:
> + vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
> +}
> +
> +static void vuf_stop(VirtIODevice *vdev)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> + int ret;
> +
> + if (!k->set_guest_notifiers) {
> + return;
> + }
> +
> + vhost_dev_stop(&fs->vhost_dev, vdev);
> +
> + ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
> + if (ret < 0) {
> + error_report("vhost guest notifier cleanup failed: %d", ret);
> + return;
> + }
> +
> + vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
> +}
> +
> +static void vuf_set_status(VirtIODevice *vdev, uint8_t status)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> + bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
> +
> + if (!vdev->vm_running) {
> + should_start = false;
> + }
> +
> + if (fs->vhost_dev.started == should_start) {
> + return;
> + }
> +
> + if (should_start) {
> + vuf_start(vdev);
> + } else {
> + vuf_stop(vdev);
> + }
> +}
> +
> +static uint64_t vuf_get_features(VirtIODevice *vdev,
> + uint64_t requested_features,
> + Error **errp)
> +{
> + /* No feature bits used yet */
> + return requested_features;
> +}
> +
> +static void vuf_handle_output(VirtIODevice *vdev, VirtQueue *vq)
> +{
> + /*
> + * Not normally called; it's the daemon that handles the queue;
> + * however virtio's cleanup path can call this.
> + */
> +}
> +
> +static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
> + bool mask)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> +
> + vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
> +}
> +
> +static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
> +{
> + VHostUserFS *fs = VHOST_USER_FS(vdev);
> +
> + return vhost_virtqueue_pending(&fs->vhost_dev, idx);
> +}
> +
> +static void vuf_device_realize(DeviceState *dev, Error **errp)
> +{
> + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> + VHostUserFS *fs = VHOST_USER_FS(dev);
> + unsigned int i;
> + size_t len;
> + int ret;
> +
> + if (!fs->conf.chardev.chr) {
> + error_setg(errp, "missing chardev");
> + return;
> + }
> +
> + if (!fs->conf.tag) {
> + error_setg(errp, "missing tag property");
> + return;
> + }
> + len = strlen(fs->conf.tag);
> + if (len == 0) {
> + error_setg(errp, "tag property cannot be empty");
> + return;
> + }
> + if (len > sizeof_field(struct virtio_fs_config, tag)) {
> + error_setg(errp, "tag property must be %zu bytes or less",
> + sizeof_field(struct virtio_fs_config, tag));
> + return;
> + }
> +
> + if (fs->conf.num_request_queues == 0) {
> + error_setg(errp, "num-request-queues property must be larger than 0");
> + return;
> + }
> +
> + if (!is_power_of_2(fs->conf.queue_size)) {
> + error_setg(errp, "queue-size property must be a power of 2");
> + return;
> + }
> +
> + if (fs->conf.queue_size > VIRTQUEUE_MAX_SIZE) {
> + error_setg(errp, "queue-size property must be %u or smaller",
> + VIRTQUEUE_MAX_SIZE);
> + return;
> + }
> +
> + if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev, errp)) {
> + return;
> + }
> +
> + virtio_init(vdev, "vhost-user-fs", VIRTIO_ID_FS,
> + sizeof(struct virtio_fs_config));
> +
> + /* Hiprio queue */
> + virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
> +
> + /* Request queues */
> + for (i = 0; i < fs->conf.num_request_queues; i++) {
> + virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
> + }
> +
> + /* 1 high prio queue, plus the number configured */
> + fs->vhost_dev.nvqs = 1 + fs->conf.num_request_queues;
> + fs->vhost_dev.vqs = g_new0(struct vhost_virtqueue, fs->vhost_dev.nvqs);
> + ret = vhost_dev_init(&fs->vhost_dev, &fs->vhost_user,
> + VHOST_BACKEND_TYPE_USER, 0);
> + if (ret < 0) {
> + error_setg_errno(errp, -ret, "vhost_dev_init failed");
> + goto err_virtio;
> + }
> +
> + return;
> +
> +err_virtio:
> + vhost_user_cleanup(&fs->vhost_user);
> + virtio_cleanup(vdev);
> + g_free(fs->vhost_dev.vqs);
> + return;
> +}
> +
> +static void vuf_device_unrealize(DeviceState *dev, Error **errp)
> +{
> + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> + VHostUserFS *fs = VHOST_USER_FS(dev);
> +
> + /* This will stop vhost backend if appropriate. */
> + vuf_set_status(vdev, 0);
> +
> + vhost_dev_cleanup(&fs->vhost_dev);
> +
> + vhost_user_cleanup(&fs->vhost_user);
> +
> + virtio_cleanup(vdev);
> + g_free(fs->vhost_dev.vqs);
> + fs->vhost_dev.vqs = NULL;
> +}
> +
> +static const VMStateDescription vuf_vmstate = {
> + .name = "vhost-user-fs",
> + .unmigratable = 1,
> +};
> +
> +static Property vuf_properties[] = {
> + DEFINE_PROP_CHR("chardev", VHostUserFS, conf.chardev),
> + DEFINE_PROP_STRING("tag", VHostUserFS, conf.tag),
> + DEFINE_PROP_UINT16("num-request-queues", VHostUserFS,
> + conf.num_request_queues, 1),
> + DEFINE_PROP_UINT16("queue-size", VHostUserFS, conf.queue_size, 128),
> + DEFINE_PROP_STRING("vhostfd", VHostUserFS, conf.vhostfd),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vuf_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
> +
> + dc->props = vuf_properties;
> + dc->vmsd = &vuf_vmstate;
> + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> + vdc->realize = vuf_device_realize;
> + vdc->unrealize = vuf_device_unrealize;
> + vdc->get_features = vuf_get_features;
> + vdc->get_config = vuf_get_config;
> + vdc->set_status = vuf_set_status;
> + vdc->guest_notifier_mask = vuf_guest_notifier_mask;
> + vdc->guest_notifier_pending = vuf_guest_notifier_pending;
> +}
> +
> +static const TypeInfo vuf_info = {
> + .name = TYPE_VHOST_USER_FS,
> + .parent = TYPE_VIRTIO_DEVICE,
> + .instance_size = sizeof(VHostUserFS),
> + .class_init = vuf_class_init,
> +};
> +
> +static void vuf_register_types(void)
> +{
> + type_register_static(&vuf_info);
> +}
> +
> +type_init(vuf_register_types)
> diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h
> new file mode 100644
> index 0000000000..539885b458
> --- /dev/null
> +++ b/include/hw/virtio/vhost-user-fs.h
> @@ -0,0 +1,45 @@
> +/*
> + * Vhost-user filesystem virtio device
> + *
> + * Copyright 2018-2019 Red Hat, Inc.
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version. See the COPYING file in the
> + * top-level directory.
> + */
> +
> +#ifndef _QEMU_VHOST_USER_FS_H
> +#define _QEMU_VHOST_USER_FS_H
> +
> +#include "hw/virtio/virtio.h"
> +#include "hw/virtio/vhost.h"
> +#include "hw/virtio/vhost-user.h"
> +#include "chardev/char-fe.h"
> +
> +#define TYPE_VHOST_USER_FS "vhost-user-fs-device"
> +#define VHOST_USER_FS(obj) \
> + OBJECT_CHECK(VHostUserFS, (obj), TYPE_VHOST_USER_FS)
> +
> +typedef struct {
> + CharBackend chardev;
> + char *tag;
> + uint16_t num_request_queues;
> + uint16_t queue_size;
> + char *vhostfd;
> +} VHostUserFSConf;
> +
> +typedef struct {
> + /*< private >*/
> + VirtIODevice parent;
> + VHostUserFSConf conf;
> + struct vhost_virtqueue *vhost_vqs;
> + struct vhost_dev vhost_dev;
> + VhostUserState vhost_user;
> +
> + /*< public >*/
> +} VHostUserFS;
> +
> +#endif /* _QEMU_VHOST_USER_FS_H */
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PULL 18/19] virtio: add vhost-user-fs base device
2019-10-07 5:57 ` Igor Mammedov
@ 2019-10-07 7:28 ` Michael S. Tsirkin
0 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-07 7:28 UTC (permalink / raw)
To: Igor Mammedov
Cc: Peter Maydell, Sebastien Boeuf, qemu-devel, Stefan Hajnoczi,
Dr. David Alan Gilbert
On Mon, Oct 07, 2019 at 07:57:04AM +0200, Igor Mammedov wrote:
> On Sat, 5 Oct 2019 18:00:09 -0400
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>
> > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> >
> > The virtio-fs virtio device provides shared file system access using
> > the FUSE protocol carried over virtio.
> > The actual file server is implemented in an external vhost-user-fs device
> > backend process.
> >
> > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> > Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
> > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > Message-Id: <20190930105135.27244-3-dgilbert@redhat.com>
> > Acked-by: Peter Maydell <peter.maydell@linaro.org>
> > Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>
> Michael,
>
> looks like your script for sending pull req is still broken,
>
> this patch in pull req has the same
> Message-ID: <20190930105135.27244-3-dgilbert@redhat.com>
> as the original email
> [PATCH v4 2/3] virtio: add vhost-user-fs base device
> even though body differs from original,
> which breaks threading on email client side.
>
> Could you fix it please?
Finally figured it out. It was picking up the last
Message-ID ignoring the mail header boundaries.
Fixed, thanks for the patience!
>
>
> > ---
> > configure | 13 ++
> > hw/virtio/Makefile.objs | 1 +
> > hw/virtio/vhost-user-fs.c | 299 ++++++++++++++++++++++++++++++
> > include/hw/virtio/vhost-user-fs.h | 45 +++++
> > 4 files changed, 358 insertions(+)
> > create mode 100644 hw/virtio/vhost-user-fs.c
> > create mode 100644 include/hw/virtio/vhost-user-fs.h
> >
> > diff --git a/configure b/configure
> > index 8f8446f52b..7bd01b201c 100755
> > --- a/configure
> > +++ b/configure
> > @@ -381,6 +381,7 @@ vhost_crypto=""
> > vhost_scsi=""
> > vhost_vsock=""
> > vhost_user=""
> > +vhost_user_fs=""
> > kvm="no"
> > hax="no"
> > hvf="no"
> > @@ -1293,6 +1294,10 @@ for opt do
> > ;;
> > --enable-vhost-vsock) vhost_vsock="yes"
> > ;;
> > + --disable-vhost-user-fs) vhost_user_fs="no"
> > + ;;
> > + --enable-vhost-user-fs) vhost_user_fs="yes"
> > + ;;
> > --disable-opengl) opengl="no"
> > ;;
> > --enable-opengl) opengl="yes"
> > @@ -2236,6 +2241,10 @@ test "$vhost_crypto" = "" && vhost_crypto=$vhost_user
> > if test "$vhost_crypto" = "yes" && test "$vhost_user" = "no"; then
> > error_exit "--enable-vhost-crypto requires --enable-vhost-user"
> > fi
> > +test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
> > +if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
> > + error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
> > +fi
> >
> > # OR the vhost-kernel and vhost-user values for simplicity
> > if test "$vhost_net" = ""; then
> > @@ -6377,6 +6386,7 @@ echo "vhost-crypto support $vhost_crypto"
> > echo "vhost-scsi support $vhost_scsi"
> > echo "vhost-vsock support $vhost_vsock"
> > echo "vhost-user support $vhost_user"
> > +echo "vhost-user-fs support $vhost_user_fs"
> > echo "Trace backends $trace_backends"
> > if have_backend "simple"; then
> > echo "Trace output file $trace_file-<pid>"
> > @@ -6873,6 +6883,9 @@ fi
> > if test "$vhost_user" = "yes" ; then
> > echo "CONFIG_VHOST_USER=y" >> $config_host_mak
> > fi
> > +if test "$vhost_user_fs" = "yes" ; then
> > + echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
> > +fi
> > if test "$blobs" = "yes" ; then
> > echo "INSTALL_BLOBS=yes" >> $config_host_mak
> > fi
> > diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> > index 964ce78607..47ffbf22c4 100644
> > --- a/hw/virtio/Makefile.objs
> > +++ b/hw/virtio/Makefile.objs
> > @@ -11,6 +11,7 @@ common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
> > common-obj-$(CONFIG_VIRTIO_MMIO) += virtio-mmio.o
> > obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
> > obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
> > +obj-$(CONFIG_VHOST_USER_FS) += vhost-user-fs.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
> > diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> > new file mode 100644
> > index 0000000000..f0df7f4746
> > --- /dev/null
> > +++ b/hw/virtio/vhost-user-fs.c
> > @@ -0,0 +1,299 @@
> > +/*
> > + * Vhost-user filesystem virtio device
> > + *
> > + * Copyright 2018-2019 Red Hat, Inc.
> > + *
> > + * Authors:
> > + * Stefan Hajnoczi <stefanha@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or
> > + * (at your option) any later version. See the COPYING file in the
> > + * top-level directory.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include <sys/ioctl.h>
> > +#include "standard-headers/linux/virtio_fs.h"
> > +#include "qapi/error.h"
> > +#include "hw/qdev-properties.h"
> > +#include "hw/virtio/virtio-bus.h"
> > +#include "hw/virtio/virtio-access.h"
> > +#include "qemu/error-report.h"
> > +#include "hw/virtio/vhost-user-fs.h"
> > +#include "monitor/monitor.h"
> > +
> > +static void vuf_get_config(VirtIODevice *vdev, uint8_t *config)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > + struct virtio_fs_config fscfg = {};
> > +
> > + memcpy((char *)fscfg.tag, fs->conf.tag,
> > + MIN(strlen(fs->conf.tag) + 1, sizeof(fscfg.tag)));
> > +
> > + virtio_stl_p(vdev, &fscfg.num_request_queues, fs->conf.num_request_queues);
> > +
> > + memcpy(config, &fscfg, sizeof(fscfg));
> > +}
> > +
> > +static void vuf_start(VirtIODevice *vdev)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> > + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> > + int ret;
> > + int i;
> > +
> > + if (!k->set_guest_notifiers) {
> > + error_report("binding does not support guest notifiers");
> > + return;
> > + }
> > +
> > + ret = vhost_dev_enable_notifiers(&fs->vhost_dev, vdev);
> > + if (ret < 0) {
> > + error_report("Error enabling host notifiers: %d", -ret);
> > + return;
> > + }
> > +
> > + ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, true);
> > + if (ret < 0) {
> > + error_report("Error binding guest notifier: %d", -ret);
> > + goto err_host_notifiers;
> > + }
> > +
> > + fs->vhost_dev.acked_features = vdev->guest_features;
> > + ret = vhost_dev_start(&fs->vhost_dev, vdev);
> > + if (ret < 0) {
> > + error_report("Error starting vhost: %d", -ret);
> > + goto err_guest_notifiers;
> > + }
> > +
> > + /*
> > + * guest_notifier_mask/pending not used yet, so just unmask
> > + * everything here. virtio-pci will do the right thing by
> > + * enabling/disabling irqfd.
> > + */
> > + for (i = 0; i < fs->vhost_dev.nvqs; i++) {
> > + vhost_virtqueue_mask(&fs->vhost_dev, vdev, i, false);
> > + }
> > +
> > + return;
> > +
> > +err_guest_notifiers:
> > + k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
> > +err_host_notifiers:
> > + vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
> > +}
> > +
> > +static void vuf_stop(VirtIODevice *vdev)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> > + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> > + int ret;
> > +
> > + if (!k->set_guest_notifiers) {
> > + return;
> > + }
> > +
> > + vhost_dev_stop(&fs->vhost_dev, vdev);
> > +
> > + ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
> > + if (ret < 0) {
> > + error_report("vhost guest notifier cleanup failed: %d", ret);
> > + return;
> > + }
> > +
> > + vhost_dev_disable_notifiers(&fs->vhost_dev, vdev);
> > +}
> > +
> > +static void vuf_set_status(VirtIODevice *vdev, uint8_t status)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > + bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
> > +
> > + if (!vdev->vm_running) {
> > + should_start = false;
> > + }
> > +
> > + if (fs->vhost_dev.started == should_start) {
> > + return;
> > + }
> > +
> > + if (should_start) {
> > + vuf_start(vdev);
> > + } else {
> > + vuf_stop(vdev);
> > + }
> > +}
> > +
> > +static uint64_t vuf_get_features(VirtIODevice *vdev,
> > + uint64_t requested_features,
> > + Error **errp)
> > +{
> > + /* No feature bits used yet */
> > + return requested_features;
> > +}
> > +
> > +static void vuf_handle_output(VirtIODevice *vdev, VirtQueue *vq)
> > +{
> > + /*
> > + * Not normally called; it's the daemon that handles the queue;
> > + * however virtio's cleanup path can call this.
> > + */
> > +}
> > +
> > +static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
> > + bool mask)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > +
> > + vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
> > +}
> > +
> > +static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
> > +{
> > + VHostUserFS *fs = VHOST_USER_FS(vdev);
> > +
> > + return vhost_virtqueue_pending(&fs->vhost_dev, idx);
> > +}
> > +
> > +static void vuf_device_realize(DeviceState *dev, Error **errp)
> > +{
> > + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> > + VHostUserFS *fs = VHOST_USER_FS(dev);
> > + unsigned int i;
> > + size_t len;
> > + int ret;
> > +
> > + if (!fs->conf.chardev.chr) {
> > + error_setg(errp, "missing chardev");
> > + return;
> > + }
> > +
> > + if (!fs->conf.tag) {
> > + error_setg(errp, "missing tag property");
> > + return;
> > + }
> > + len = strlen(fs->conf.tag);
> > + if (len == 0) {
> > + error_setg(errp, "tag property cannot be empty");
> > + return;
> > + }
> > + if (len > sizeof_field(struct virtio_fs_config, tag)) {
> > + error_setg(errp, "tag property must be %zu bytes or less",
> > + sizeof_field(struct virtio_fs_config, tag));
> > + return;
> > + }
> > +
> > + if (fs->conf.num_request_queues == 0) {
> > + error_setg(errp, "num-request-queues property must be larger than 0");
> > + return;
> > + }
> > +
> > + if (!is_power_of_2(fs->conf.queue_size)) {
> > + error_setg(errp, "queue-size property must be a power of 2");
> > + return;
> > + }
> > +
> > + if (fs->conf.queue_size > VIRTQUEUE_MAX_SIZE) {
> > + error_setg(errp, "queue-size property must be %u or smaller",
> > + VIRTQUEUE_MAX_SIZE);
> > + return;
> > + }
> > +
> > + if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev, errp)) {
> > + return;
> > + }
> > +
> > + virtio_init(vdev, "vhost-user-fs", VIRTIO_ID_FS,
> > + sizeof(struct virtio_fs_config));
> > +
> > + /* Hiprio queue */
> > + virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
> > +
> > + /* Request queues */
> > + for (i = 0; i < fs->conf.num_request_queues; i++) {
> > + virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output);
> > + }
> > +
> > + /* 1 high prio queue, plus the number configured */
> > + fs->vhost_dev.nvqs = 1 + fs->conf.num_request_queues;
> > + fs->vhost_dev.vqs = g_new0(struct vhost_virtqueue, fs->vhost_dev.nvqs);
> > + ret = vhost_dev_init(&fs->vhost_dev, &fs->vhost_user,
> > + VHOST_BACKEND_TYPE_USER, 0);
> > + if (ret < 0) {
> > + error_setg_errno(errp, -ret, "vhost_dev_init failed");
> > + goto err_virtio;
> > + }
> > +
> > + return;
> > +
> > +err_virtio:
> > + vhost_user_cleanup(&fs->vhost_user);
> > + virtio_cleanup(vdev);
> > + g_free(fs->vhost_dev.vqs);
> > + return;
> > +}
> > +
> > +static void vuf_device_unrealize(DeviceState *dev, Error **errp)
> > +{
> > + VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> > + VHostUserFS *fs = VHOST_USER_FS(dev);
> > +
> > + /* This will stop vhost backend if appropriate. */
> > + vuf_set_status(vdev, 0);
> > +
> > + vhost_dev_cleanup(&fs->vhost_dev);
> > +
> > + vhost_user_cleanup(&fs->vhost_user);
> > +
> > + virtio_cleanup(vdev);
> > + g_free(fs->vhost_dev.vqs);
> > + fs->vhost_dev.vqs = NULL;
> > +}
> > +
> > +static const VMStateDescription vuf_vmstate = {
> > + .name = "vhost-user-fs",
> > + .unmigratable = 1,
> > +};
> > +
> > +static Property vuf_properties[] = {
> > + DEFINE_PROP_CHR("chardev", VHostUserFS, conf.chardev),
> > + DEFINE_PROP_STRING("tag", VHostUserFS, conf.tag),
> > + DEFINE_PROP_UINT16("num-request-queues", VHostUserFS,
> > + conf.num_request_queues, 1),
> > + DEFINE_PROP_UINT16("queue-size", VHostUserFS, conf.queue_size, 128),
> > + DEFINE_PROP_STRING("vhostfd", VHostUserFS, conf.vhostfd),
> > + DEFINE_PROP_END_OF_LIST(),
> > +};
> > +
> > +static void vuf_class_init(ObjectClass *klass, void *data)
> > +{
> > + DeviceClass *dc = DEVICE_CLASS(klass);
> > + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
> > +
> > + dc->props = vuf_properties;
> > + dc->vmsd = &vuf_vmstate;
> > + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> > + vdc->realize = vuf_device_realize;
> > + vdc->unrealize = vuf_device_unrealize;
> > + vdc->get_features = vuf_get_features;
> > + vdc->get_config = vuf_get_config;
> > + vdc->set_status = vuf_set_status;
> > + vdc->guest_notifier_mask = vuf_guest_notifier_mask;
> > + vdc->guest_notifier_pending = vuf_guest_notifier_pending;
> > +}
> > +
> > +static const TypeInfo vuf_info = {
> > + .name = TYPE_VHOST_USER_FS,
> > + .parent = TYPE_VIRTIO_DEVICE,
> > + .instance_size = sizeof(VHostUserFS),
> > + .class_init = vuf_class_init,
> > +};
> > +
> > +static void vuf_register_types(void)
> > +{
> > + type_register_static(&vuf_info);
> > +}
> > +
> > +type_init(vuf_register_types)
> > diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h
> > new file mode 100644
> > index 0000000000..539885b458
> > --- /dev/null
> > +++ b/include/hw/virtio/vhost-user-fs.h
> > @@ -0,0 +1,45 @@
> > +/*
> > + * Vhost-user filesystem virtio device
> > + *
> > + * Copyright 2018-2019 Red Hat, Inc.
> > + *
> > + * Authors:
> > + * Stefan Hajnoczi <stefanha@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or
> > + * (at your option) any later version. See the COPYING file in the
> > + * top-level directory.
> > + */
> > +
> > +#ifndef _QEMU_VHOST_USER_FS_H
> > +#define _QEMU_VHOST_USER_FS_H
> > +
> > +#include "hw/virtio/virtio.h"
> > +#include "hw/virtio/vhost.h"
> > +#include "hw/virtio/vhost-user.h"
> > +#include "chardev/char-fe.h"
> > +
> > +#define TYPE_VHOST_USER_FS "vhost-user-fs-device"
> > +#define VHOST_USER_FS(obj) \
> > + OBJECT_CHECK(VHostUserFS, (obj), TYPE_VHOST_USER_FS)
> > +
> > +typedef struct {
> > + CharBackend chardev;
> > + char *tag;
> > + uint16_t num_request_queues;
> > + uint16_t queue_size;
> > + char *vhostfd;
> > +} VHostUserFSConf;
> > +
> > +typedef struct {
> > + /*< private >*/
> > + VirtIODevice parent;
> > + VHostUserFSConf conf;
> > + struct vhost_virtqueue *vhost_vqs;
> > + struct vhost_dev vhost_dev;
> > + VhostUserState vhost_user;
> > +
> > + /*< public >*/
> > +} VHostUserFS;
> > +
> > +#endif /* _QEMU_VHOST_USER_FS_H */
^ permalink raw reply [flat|nested] 60+ messages in thread
* [PATCH v4 3/3] virtio: add vhost-user-fs-pci device
2019-09-30 10:51 [PATCH v4 0/3] Add virtio-fs Dr. David Alan Gilbert (git)
2019-09-30 10:51 ` [PATCH v4 1/3] virtio: Add virtio_fs linux headers Dr. David Alan Gilbert (git)
2019-09-30 10:51 ` [PATCH v4 2/3] virtio: add vhost-user-fs base device Dr. David Alan Gilbert (git)
@ 2019-09-30 10:51 ` Dr. David Alan Gilbert (git)
2019-10-05 22:00 ` [PULL 19/19] " Michael S. Tsirkin
2 siblings, 1 reply; 60+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-09-30 10:51 UTC (permalink / raw)
To: qemu-devel, mst; +Cc: mszeredi, cohuck, vgoyal, stefanha
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Add the PCI version of vhost-user-fs.
Launch QEMU like this:
qemu -chardev socket,path=/tmp/vhost-fs.sock,id=chr0
-device vhost-user-fs-pci,tag=myfs,chardev=chr0
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
---
hw/virtio/Makefile.objs | 1 +
hw/virtio/vhost-user-fs-pci.c | 85 +++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+)
create mode 100644 hw/virtio/vhost-user-fs-pci.c
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 47ffbf22c4..e2f70fbb89 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -15,6 +15,7 @@ obj-$(CONFIG_VHOST_USER_FS) += vhost-user-fs.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-$(call land,$(CONFIG_VHOST_USER_FS),$(CONFIG_VIRTIO_PCI)) += vhost-user-fs-pci.o
obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
ifeq ($(CONFIG_VIRTIO_PCI),y)
diff --git a/hw/virtio/vhost-user-fs-pci.c b/hw/virtio/vhost-user-fs-pci.c
new file mode 100644
index 0000000000..933a3f265b
--- /dev/null
+++ b/hw/virtio/vhost-user-fs-pci.c
@@ -0,0 +1,85 @@
+/*
+ * Vhost-user filesystem virtio device PCI glue
+ *
+ * Copyright 2018-2019 Red Hat, Inc.
+ *
+ * Authors:
+ * Dr. David Alan Gilbert <dgilbert@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/vhost-user-fs.h"
+#include "virtio-pci.h"
+
+struct VHostUserFSPCI {
+ VirtIOPCIProxy parent_obj;
+ VHostUserFS vdev;
+};
+
+typedef struct VHostUserFSPCI VHostUserFSPCI;
+
+#define TYPE_VHOST_USER_FS_PCI "vhost-user-fs-pci-base"
+
+#define VHOST_USER_FS_PCI(obj) \
+ OBJECT_CHECK(VHostUserFSPCI, (obj), TYPE_VHOST_USER_FS_PCI)
+
+static Property vhost_user_fs_pci_properties[] = {
+ DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
+ DEV_NVECTORS_UNSPECIFIED),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_user_fs_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+ VHostUserFSPCI *dev = VHOST_USER_FS_PCI(vpci_dev);
+ DeviceState *vdev = DEVICE(&dev->vdev);
+
+ if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
+ vpci_dev->nvectors = dev->vdev.conf.num_request_queues + 1;
+ }
+
+ qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+ object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+}
+
+static void vhost_user_fs_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);
+ k->realize = vhost_user_fs_pci_realize;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ dc->props = vhost_user_fs_pci_properties;
+ pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+ pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
+ pcidev_k->revision = 0x00;
+ pcidev_k->class_id = PCI_CLASS_STORAGE_OTHER;
+}
+
+static void vhost_user_fs_pci_instance_init(Object *obj)
+{
+ VHostUserFSPCI *dev = VHOST_USER_FS_PCI(obj);
+
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+ TYPE_VHOST_USER_FS);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_fs_pci_info = {
+ .base_name = TYPE_VHOST_USER_FS_PCI,
+ .non_transitional_name = "vhost-user-fs-pci",
+ .instance_size = sizeof(VHostUserFSPCI),
+ .instance_init = vhost_user_fs_pci_instance_init,
+ .class_init = vhost_user_fs_pci_class_init,
+};
+
+static void vhost_user_fs_pci_register(void)
+{
+ virtio_pci_types_register(&vhost_user_fs_pci_info);
+}
+
+type_init(vhost_user_fs_pci_register);
--
2.21.0
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [PULL 19/19] virtio: add vhost-user-fs-pci device
2019-09-30 10:51 ` [PATCH v4 3/3] virtio: add vhost-user-fs-pci device Dr. David Alan Gilbert (git)
@ 2019-10-05 22:00 ` Michael S. Tsirkin
0 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 22:00 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Sebastien Boeuf, Dr. David Alan Gilbert,
Stefan Hajnoczi, Cornelia Huck
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Add the PCI version of vhost-user-fs.
Launch QEMU like this:
qemu -chardev socket,path=/tmp/vhost-fs.sock,id=chr0
-device vhost-user-fs-pci,tag=myfs,chardev=chr0
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20190930105135.27244-4-dgilbert@redhat.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/virtio/Makefile.objs | 1 +
hw/virtio/vhost-user-fs-pci.c | 85 +++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+)
create mode 100644 hw/virtio/vhost-user-fs-pci.c
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 47ffbf22c4..e2f70fbb89 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -15,6 +15,7 @@ obj-$(CONFIG_VHOST_USER_FS) += vhost-user-fs.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-$(call land,$(CONFIG_VHOST_USER_FS),$(CONFIG_VIRTIO_PCI)) += vhost-user-fs-pci.o
obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
ifeq ($(CONFIG_VIRTIO_PCI),y)
diff --git a/hw/virtio/vhost-user-fs-pci.c b/hw/virtio/vhost-user-fs-pci.c
new file mode 100644
index 0000000000..933a3f265b
--- /dev/null
+++ b/hw/virtio/vhost-user-fs-pci.c
@@ -0,0 +1,85 @@
+/*
+ * Vhost-user filesystem virtio device PCI glue
+ *
+ * Copyright 2018-2019 Red Hat, Inc.
+ *
+ * Authors:
+ * Dr. David Alan Gilbert <dgilbert@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/vhost-user-fs.h"
+#include "virtio-pci.h"
+
+struct VHostUserFSPCI {
+ VirtIOPCIProxy parent_obj;
+ VHostUserFS vdev;
+};
+
+typedef struct VHostUserFSPCI VHostUserFSPCI;
+
+#define TYPE_VHOST_USER_FS_PCI "vhost-user-fs-pci-base"
+
+#define VHOST_USER_FS_PCI(obj) \
+ OBJECT_CHECK(VHostUserFSPCI, (obj), TYPE_VHOST_USER_FS_PCI)
+
+static Property vhost_user_fs_pci_properties[] = {
+ DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
+ DEV_NVECTORS_UNSPECIFIED),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_user_fs_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+ VHostUserFSPCI *dev = VHOST_USER_FS_PCI(vpci_dev);
+ DeviceState *vdev = DEVICE(&dev->vdev);
+
+ if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
+ vpci_dev->nvectors = dev->vdev.conf.num_request_queues + 1;
+ }
+
+ qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+ object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+}
+
+static void vhost_user_fs_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);
+ k->realize = vhost_user_fs_pci_realize;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ dc->props = vhost_user_fs_pci_properties;
+ pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+ pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
+ pcidev_k->revision = 0x00;
+ pcidev_k->class_id = PCI_CLASS_STORAGE_OTHER;
+}
+
+static void vhost_user_fs_pci_instance_init(Object *obj)
+{
+ VHostUserFSPCI *dev = VHOST_USER_FS_PCI(obj);
+
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+ TYPE_VHOST_USER_FS);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_fs_pci_info = {
+ .base_name = TYPE_VHOST_USER_FS_PCI,
+ .non_transitional_name = "vhost-user-fs-pci",
+ .instance_size = sizeof(VHostUserFSPCI),
+ .instance_init = vhost_user_fs_pci_instance_init,
+ .class_init = vhost_user_fs_pci_class_init,
+};
+
+static void vhost_user_fs_pci_register(void)
+{
+ virtio_pci_types_register(&vhost_user_fs_pci_info);
+}
+
+type_init(vhost_user_fs_pci_register);
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 01/11] hw/acpi: Make ACPI IO address space configurable
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-10-05 21:58 ` [PULL 02/19] " Michael S. Tsirkin
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 02/11] hw/acpi: Do not create memory hotplug method when handler is not defined Shameer Kolothum
` (14 subsequent siblings)
15 siblings, 1 reply; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
This is in preparation for adding support for ARM64 platforms
where it doesn't use port mapped IO for ACPI IO space. We are
making changes so that MMIO region can be accommodated
and board can pass the base address into the aml build function.
Also move few MEMORY_* definitions to header so that other memory
hotplug event signalling mechanisms (eg. Generic Event Device on
HW-reduced acpi platforms) can use the same from their respective
event handler code.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
---
hw/acpi/memory_hotplug.c | 33 ++++++++++++++------------------
hw/i386/acpi-build.c | 7 ++++++-
hw/i386/pc.c | 3 +++
include/hw/acpi/memory_hotplug.h | 9 +++++++--
include/hw/i386/pc.h | 3 +++
5 files changed, 33 insertions(+), 22 deletions(-)
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 9483d66e86..9b0b150f4f 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -30,12 +30,7 @@
#define MEMORY_SLOT_PROXIMITY_METHOD "MPXM"
#define MEMORY_SLOT_EJECT_METHOD "MEJ0"
#define MEMORY_SLOT_NOTIFY_METHOD "MTFY"
-#define MEMORY_SLOT_SCAN_METHOD "MSCN"
#define MEMORY_HOTPLUG_DEVICE "MHPD"
-#define MEMORY_HOTPLUG_IO_LEN 24
-#define MEMORY_DEVICES_CONTAINER "\\_SB.MHPC"
-
-static uint16_t memhp_io_base;
static ACPIOSTInfo *acpi_memory_device_status(int slot, MemStatus *mdev)
{
@@ -210,7 +205,7 @@ static const MemoryRegionOps acpi_memory_hotplug_ops = {
};
void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
- MemHotplugState *state, uint16_t io_base)
+ MemHotplugState *state, hwaddr io_base)
{
MachineState *machine = MACHINE(qdev_get_machine());
@@ -219,12 +214,10 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
return;
}
- assert(!memhp_io_base);
- memhp_io_base = io_base;
state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
memory_region_init_io(&state->io, owner, &acpi_memory_hotplug_ops, state,
"acpi-mem-hotplug", MEMORY_HOTPLUG_IO_LEN);
- memory_region_add_subregion(as, memhp_io_base, &state->io);
+ memory_region_add_subregion(as, io_base, &state->io);
}
/**
@@ -343,7 +336,8 @@ const VMStateDescription vmstate_memory_hotplug = {
void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
const char *res_root,
- const char *event_handler_method)
+ const char *event_handler_method,
+ AmlRegionSpace rs, hwaddr memhp_io_base)
{
int i;
Aml *ifctx;
@@ -352,10 +346,6 @@ void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
Aml *mem_ctrl_dev;
char *mhp_res_path;
- if (!memhp_io_base) {
- return;
- }
-
mhp_res_path = g_strdup_printf("%s." MEMORY_HOTPLUG_DEVICE, res_root);
mem_ctrl_dev = aml_device("%s", mhp_res_path);
{
@@ -366,14 +356,19 @@ void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
aml_name_decl("_UID", aml_string("Memory hotplug resources")));
crs = aml_resource_template();
- aml_append(crs,
- aml_io(AML_DECODE16, memhp_io_base, memhp_io_base, 0,
- MEMORY_HOTPLUG_IO_LEN)
- );
+ if (rs == AML_SYSTEM_IO) {
+ aml_append(crs,
+ aml_io(AML_DECODE16, memhp_io_base, memhp_io_base, 0,
+ MEMORY_HOTPLUG_IO_LEN)
+ );
+ } else {
+ aml_append(crs, aml_memory32_fixed(memhp_io_base,
+ MEMORY_HOTPLUG_IO_LEN, AML_READ_WRITE));
+ }
aml_append(mem_ctrl_dev, aml_name_decl("_CRS", crs));
aml_append(mem_ctrl_dev, aml_operation_region(
- MEMORY_HOTPLUG_IO_REGION, AML_SYSTEM_IO,
+ MEMORY_HOTPLUG_IO_REGION, rs,
aml_int(memhp_io_base), MEMORY_HOTPLUG_IO_LEN)
);
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index e54e571a75..45be1474ea 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1873,7 +1873,12 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base,
"\\_SB.PCI0", "\\_GPE._E02");
}
- build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0", "\\_GPE._E03");
+
+ if (pcms->memhp_io_base && nr_mem) {
+ build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0",
+ "\\_GPE._E03", AML_SYSTEM_IO,
+ pcms->memhp_io_base);
+ }
scope = aml_scope("_GPE");
{
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index bad866fe44..1d26706255 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1954,6 +1954,9 @@ void pc_memory_init(PCMachineState *pcms,
/* Init default IOAPIC address space */
pcms->ioapic_as = &address_space_memory;
+
+ /* Init ACPI memory hotplug IO base address */
+ pcms->memhp_io_base = ACPI_MEMORY_HOTPLUG_BASE;
}
/*
diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h
index 77c65765d6..dfe9cf3fde 100644
--- a/include/hw/acpi/memory_hotplug.h
+++ b/include/hw/acpi/memory_hotplug.h
@@ -5,6 +5,10 @@
#include "hw/acpi/acpi.h"
#include "hw/acpi/aml-build.h"
+#define MEMORY_SLOT_SCAN_METHOD "MSCN"
+#define MEMORY_DEVICES_CONTAINER "\\_SB.MHPC"
+#define MEMORY_HOTPLUG_IO_LEN 24
+
/**
* MemStatus:
* @is_removing: the memory device in slot has been requested to be ejected.
@@ -29,7 +33,7 @@ typedef struct MemHotplugState {
} MemHotplugState;
void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
- MemHotplugState *state, uint16_t io_base);
+ MemHotplugState *state, hwaddr io_base);
void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
DeviceState *dev, Error **errp);
@@ -48,5 +52,6 @@ void acpi_memory_ospm_status(MemHotplugState *mem_st, ACPIOSTInfoList ***list);
void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
const char *res_root,
- const char *event_handler_method);
+ const char *event_handler_method,
+ AmlRegionSpace rs, hwaddr memhp_io_base);
#endif
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 19a837889d..ac09e42030 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -69,6 +69,9 @@ struct PCMachineState {
/* Address space used by IOAPIC device. All IOAPIC interrupts
* will be translated to MSI messages in the address space. */
AddressSpace *ioapic_as;
+
+ /* ACPI Memory hotplug IO base address */
+ hwaddr memhp_io_base;
};
#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [PULL 02/19] hw/acpi: Make ACPI IO address space configurable
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 01/11] hw/acpi: Make ACPI IO address space configurable Shameer Kolothum
@ 2019-10-05 21:58 ` Michael S. Tsirkin
0 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:58 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Eduardo Habkost, Shameer Kolothum, Eric Auger,
Paolo Bonzini, Igor Mammedov, Richard Henderson
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
This is in preparation for adding support for ARM64 platforms
where it doesn't use port mapped IO for ACPI IO space. We are
making changes so that MMIO region can be accommodated
and board can pass the base address into the aml build function.
Also move few MEMORY_* definitions to header so that other memory
hotplug event signalling mechanisms (eg. Generic Event Device on
HW-reduced acpi platforms) can use the same from their respective
event handler code.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20190918130633.4872-2-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/acpi/memory_hotplug.c | 33 ++++++++++++++------------------
hw/i386/acpi-build.c | 7 ++++++-
hw/i386/pc.c | 3 +++
include/hw/acpi/memory_hotplug.h | 9 +++++++--
include/hw/i386/pc.h | 3 +++
5 files changed, 33 insertions(+), 22 deletions(-)
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 9483d66e86..9b0b150f4f 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -30,12 +30,7 @@
#define MEMORY_SLOT_PROXIMITY_METHOD "MPXM"
#define MEMORY_SLOT_EJECT_METHOD "MEJ0"
#define MEMORY_SLOT_NOTIFY_METHOD "MTFY"
-#define MEMORY_SLOT_SCAN_METHOD "MSCN"
#define MEMORY_HOTPLUG_DEVICE "MHPD"
-#define MEMORY_HOTPLUG_IO_LEN 24
-#define MEMORY_DEVICES_CONTAINER "\\_SB.MHPC"
-
-static uint16_t memhp_io_base;
static ACPIOSTInfo *acpi_memory_device_status(int slot, MemStatus *mdev)
{
@@ -210,7 +205,7 @@ static const MemoryRegionOps acpi_memory_hotplug_ops = {
};
void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
- MemHotplugState *state, uint16_t io_base)
+ MemHotplugState *state, hwaddr io_base)
{
MachineState *machine = MACHINE(qdev_get_machine());
@@ -219,12 +214,10 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
return;
}
- assert(!memhp_io_base);
- memhp_io_base = io_base;
state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
memory_region_init_io(&state->io, owner, &acpi_memory_hotplug_ops, state,
"acpi-mem-hotplug", MEMORY_HOTPLUG_IO_LEN);
- memory_region_add_subregion(as, memhp_io_base, &state->io);
+ memory_region_add_subregion(as, io_base, &state->io);
}
/**
@@ -343,7 +336,8 @@ const VMStateDescription vmstate_memory_hotplug = {
void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
const char *res_root,
- const char *event_handler_method)
+ const char *event_handler_method,
+ AmlRegionSpace rs, hwaddr memhp_io_base)
{
int i;
Aml *ifctx;
@@ -352,10 +346,6 @@ void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
Aml *mem_ctrl_dev;
char *mhp_res_path;
- if (!memhp_io_base) {
- return;
- }
-
mhp_res_path = g_strdup_printf("%s." MEMORY_HOTPLUG_DEVICE, res_root);
mem_ctrl_dev = aml_device("%s", mhp_res_path);
{
@@ -366,14 +356,19 @@ void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
aml_name_decl("_UID", aml_string("Memory hotplug resources")));
crs = aml_resource_template();
- aml_append(crs,
- aml_io(AML_DECODE16, memhp_io_base, memhp_io_base, 0,
- MEMORY_HOTPLUG_IO_LEN)
- );
+ if (rs == AML_SYSTEM_IO) {
+ aml_append(crs,
+ aml_io(AML_DECODE16, memhp_io_base, memhp_io_base, 0,
+ MEMORY_HOTPLUG_IO_LEN)
+ );
+ } else {
+ aml_append(crs, aml_memory32_fixed(memhp_io_base,
+ MEMORY_HOTPLUG_IO_LEN, AML_READ_WRITE));
+ }
aml_append(mem_ctrl_dev, aml_name_decl("_CRS", crs));
aml_append(mem_ctrl_dev, aml_operation_region(
- MEMORY_HOTPLUG_IO_REGION, AML_SYSTEM_IO,
+ MEMORY_HOTPLUG_IO_REGION, rs,
aml_int(memhp_io_base), MEMORY_HOTPLUG_IO_LEN)
);
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4e0f9f425a..1d077a7cb7 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1888,7 +1888,12 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base,
"\\_SB.PCI0", "\\_GPE._E02");
}
- build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0", "\\_GPE._E03");
+
+ if (pcms->memhp_io_base && nr_mem) {
+ build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0",
+ "\\_GPE._E03", AML_SYSTEM_IO,
+ pcms->memhp_io_base);
+ }
scope = aml_scope("_GPE");
{
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index bcda50efcc..4b1904237e 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1766,6 +1766,9 @@ void pc_memory_init(PCMachineState *pcms,
/* Init default IOAPIC address space */
pcms->ioapic_as = &address_space_memory;
+
+ /* Init ACPI memory hotplug IO base address */
+ pcms->memhp_io_base = ACPI_MEMORY_HOTPLUG_BASE;
}
/*
diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h
index 77c65765d6..dfe9cf3fde 100644
--- a/include/hw/acpi/memory_hotplug.h
+++ b/include/hw/acpi/memory_hotplug.h
@@ -5,6 +5,10 @@
#include "hw/acpi/acpi.h"
#include "hw/acpi/aml-build.h"
+#define MEMORY_SLOT_SCAN_METHOD "MSCN"
+#define MEMORY_DEVICES_CONTAINER "\\_SB.MHPC"
+#define MEMORY_HOTPLUG_IO_LEN 24
+
/**
* MemStatus:
* @is_removing: the memory device in slot has been requested to be ejected.
@@ -29,7 +33,7 @@ typedef struct MemHotplugState {
} MemHotplugState;
void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
- MemHotplugState *state, uint16_t io_base);
+ MemHotplugState *state, hwaddr io_base);
void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
DeviceState *dev, Error **errp);
@@ -48,5 +52,6 @@ void acpi_memory_ospm_status(MemHotplugState *mem_st, ACPIOSTInfoList ***list);
void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
const char *res_root,
- const char *event_handler_method);
+ const char *event_handler_method,
+ AmlRegionSpace rs, hwaddr memhp_io_base);
#endif
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 6df4f4b6fb..37bfd95113 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -70,6 +70,9 @@ struct PCMachineState {
/* Address space used by IOAPIC device. All IOAPIC interrupts
* will be translated to MSI messages in the address space. */
AddressSpace *ioapic_as;
+
+ /* ACPI Memory hotplug IO base address */
+ hwaddr memhp_io_base;
};
#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 02/11] hw/acpi: Do not create memory hotplug method when handler is not defined
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 01/11] hw/acpi: Make ACPI IO address space configurable Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-10-05 21:58 ` [PULL 03/19] " Michael S. Tsirkin
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 03/11] hw/acpi: Add ACPI Generic Event Device Support Shameer Kolothum
` (13 subsequent siblings)
15 siblings, 1 reply; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
From: Samuel Ortiz <sameo@linux.intel.com>
With Hardware-reduced ACPI, the GED device will manage ACPI
hotplug entirely. As a consequence, make the memory specific
events AML generation optional. The code will only be added
when the method name is not NULL.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
---
hw/acpi/memory_hotplug.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 9b0b150f4f..8d2e82240f 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -712,10 +712,12 @@ void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
}
aml_append(table, dev_container);
- method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
- aml_append(method,
- aml_call0(MEMORY_DEVICES_CONTAINER "." MEMORY_SLOT_SCAN_METHOD));
- aml_append(table, method);
+ if (event_handler_method) {
+ method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
+ aml_append(method, aml_call0(MEMORY_DEVICES_CONTAINER "."
+ MEMORY_SLOT_SCAN_METHOD));
+ aml_append(table, method);
+ }
g_free(mhp_res_path);
}
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [PULL 03/19] hw/acpi: Do not create memory hotplug method when handler is not defined
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 02/11] hw/acpi: Do not create memory hotplug method when handler is not defined Shameer Kolothum
@ 2019-10-05 21:58 ` Michael S. Tsirkin
0 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:58 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Igor Mammedov, Samuel Ortiz, Shameer Kolothum, Eric Auger
From: Samuel Ortiz <sameo@linux.intel.com>
With Hardware-reduced ACPI, the GED device will manage ACPI
hotplug entirely. As a consequence, make the memory specific
events AML generation optional. The code will only be added
when the method name is not NULL.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20190918130633.4872-3-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/acpi/memory_hotplug.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 9b0b150f4f..8d2e82240f 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -712,10 +712,12 @@ void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
}
aml_append(table, dev_container);
- method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
- aml_append(method,
- aml_call0(MEMORY_DEVICES_CONTAINER "." MEMORY_SLOT_SCAN_METHOD));
- aml_append(table, method);
+ if (event_handler_method) {
+ method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
+ aml_append(method, aml_call0(MEMORY_DEVICES_CONTAINER "."
+ MEMORY_SLOT_SCAN_METHOD));
+ aml_append(table, method);
+ }
g_free(mhp_res_path);
}
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 03/11] hw/acpi: Add ACPI Generic Event Device Support
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 01/11] hw/acpi: Make ACPI IO address space configurable Shameer Kolothum
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 02/11] hw/acpi: Do not create memory hotplug method when handler is not defined Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-09-25 15:03 ` Igor Mammedov
2019-10-05 21:58 ` [PULL 04/19] " Michael S. Tsirkin
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 04/11] hw/arm/virt: Add memory hotplug framework Shameer Kolothum
` (12 subsequent siblings)
15 siblings, 2 replies; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
From: Samuel Ortiz <sameo@linux.intel.com>
The ACPI Generic Event Device (GED) is a hardware-reduced specific
device[ACPI v6.1 Section 5.6.9] that handles all platform events,
including the hotplug ones. This patch generates the AML code that
defines GEDs.
Platforms need to specify their own GED Event bitmap to describe
what kind of events they want to support through GED. Also this
uses a a single interrupt for the GED device, relying on IO
memory region to communicate the type of device affected by the
interrupt. This way, we can support up to 32 events with a unique
interrupt.
This supports only memory hotplug for now.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
---
Addressed comments from Igor.
- Removed memhp_state.is_enabled condition check and property.
- Used instance_init() instead of realize()
---
hw/acpi/Kconfig | 4 +
hw/acpi/Makefile.objs | 1 +
hw/acpi/generic_event_device.c | 303 +++++++++++++++++++++++++
include/hw/acpi/generic_event_device.h | 100 ++++++++
4 files changed, 408 insertions(+)
create mode 100644 hw/acpi/generic_event_device.c
create mode 100644 include/hw/acpi/generic_event_device.h
diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index 7c59cf900b..12e3f1e86e 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -31,3 +31,7 @@ config ACPI_VMGENID
bool
default y
depends on PC
+
+config ACPI_HW_REDUCED
+ bool
+ depends on ACPI
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 9bb2101e3b..655a9c1973 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -6,6 +6,7 @@ common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
+common-obj-$(CONFIG_ACPI_HW_REDUCED) += generic_event_device.o
common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
common-obj-y += acpi_interface.o
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
new file mode 100644
index 0000000000..b94500b08d
--- /dev/null
+++ b/hw/acpi/generic_event_device.c
@@ -0,0 +1,303 @@
+/*
+ *
+ * Copyright (c) 2018 Intel Corporation
+ * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd
+ * Written by Samuel Ortiz, Shameer Kolothum
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "exec/address-spaces.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/generic_event_device.h"
+#include "hw/irq.h"
+#include "hw/mem/pc-dimm.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qemu/error-report.h"
+
+static const uint32_t ged_supported_events[] = {
+ ACPI_GED_MEM_HOTPLUG_EVT,
+};
+
+/*
+ * The ACPI Generic Event Device (GED) is a hardware-reduced specific
+ * device[ACPI v6.1 Section 5.6.9] that handles all platform events,
+ * including the hotplug ones. Platforms need to specify their own
+ * GED Event bitmap to describe what kind of events they want to support
+ * through GED. This routine uses a single interrupt for the GED device,
+ * relying on IO memory region to communicate the type of device
+ * affected by the interrupt. This way, we can support up to 32 events
+ * with a unique interrupt.
+ */
+void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
+ uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base)
+{
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
+ Aml *crs = aml_resource_template();
+ Aml *evt, *field;
+ Aml *dev = aml_device("%s", name);
+ Aml *evt_sel = aml_local(0);
+ Aml *esel = aml_name(AML_GED_EVT_SEL);
+
+ /* _CRS interrupt */
+ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH,
+ AML_EXCLUSIVE, &ged_irq, 1));
+
+ aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0013")));
+ aml_append(dev, aml_name_decl("_UID", aml_string(GED_DEVICE)));
+ aml_append(dev, aml_name_decl("_CRS", crs));
+
+ /* Append IO region */
+ aml_append(dev, aml_operation_region(AML_GED_EVT_REG, rs,
+ aml_int(ged_base + ACPI_GED_EVT_SEL_OFFSET),
+ ACPI_GED_EVT_SEL_LEN));
+ field = aml_field(AML_GED_EVT_REG, AML_DWORD_ACC, AML_NOLOCK,
+ AML_WRITE_AS_ZEROS);
+ aml_append(field, aml_named_field(AML_GED_EVT_SEL,
+ ACPI_GED_EVT_SEL_LEN * BITS_PER_BYTE));
+ aml_append(dev, field);
+
+ /*
+ * For each GED event we:
+ * - Add a conditional block for each event, inside a loop.
+ * - Call a method for each supported GED event type.
+ *
+ * The resulting ASL code looks like:
+ *
+ * Local0 = ESEL
+ * If ((Local0 & One) == One)
+ * {
+ * MethodEvent0()
+ * }
+ *
+ * If ((Local0 & 0x2) == 0x2)
+ * {
+ * MethodEvent1()
+ * }
+ * ...
+ */
+ evt = aml_method("_EVT", 1, AML_SERIALIZED);
+ {
+ Aml *if_ctx;
+ uint32_t i;
+ uint32_t ged_events = ctpop32(s->ged_event_bitmap);
+
+ /* Local0 = ESEL */
+ aml_append(evt, aml_store(esel, evt_sel));
+
+ for (i = 0; i < ARRAY_SIZE(ged_supported_events) && ged_events; i++) {
+ uint32_t event = s->ged_event_bitmap & ged_supported_events[i];
+
+ if (!event) {
+ continue;
+ }
+
+ if_ctx = aml_if(aml_equal(aml_and(evt_sel, aml_int(event), NULL),
+ aml_int(event)));
+ switch (event) {
+ case ACPI_GED_MEM_HOTPLUG_EVT:
+ aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
+ MEMORY_SLOT_SCAN_METHOD));
+ break;
+ default:
+ /*
+ * Please make sure all the events in ged_supported_events[]
+ * are handled above.
+ */
+ g_assert_not_reached();
+ }
+
+ aml_append(evt, if_ctx);
+ ged_events--;
+ }
+
+ if (ged_events) {
+ error_report("Unsupported events specified");
+ abort();
+ }
+ }
+
+ /* Append _EVT method */
+ aml_append(dev, evt);
+
+ aml_append(table, dev);
+}
+
+/* Memory read by the GED _EVT AML dynamic method */
+static uint64_t ged_read(void *opaque, hwaddr addr, unsigned size)
+{
+ uint64_t val = 0;
+ GEDState *ged_st = opaque;
+
+ switch (addr) {
+ case ACPI_GED_EVT_SEL_OFFSET:
+ /* Read the selector value and reset it */
+ val = ged_st->sel;
+ ged_st->sel = 0;
+ break;
+ default:
+ break;
+ }
+
+ return val;
+}
+
+/* Nothing is expected to be written to the GED memory region */
+static void ged_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
+{
+}
+
+static const MemoryRegionOps ged_ops = {
+ .read = ged_read,
+ .write = ged_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
+
+static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
+
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
+ } else {
+ error_setg(errp, "virt: device plug request for unsupported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+ }
+}
+
+static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
+{
+ AcpiGedState *s = ACPI_GED(adev);
+ GEDState *ged_st = &s->ged_state;
+ uint32_t sel;
+
+ if (ev & ACPI_MEMORY_HOTPLUG_STATUS) {
+ sel = ACPI_GED_MEM_HOTPLUG_EVT;
+ } else {
+ /* Unknown event. Return without generating interrupt. */
+ warn_report("GED: Unsupported event %d. No irq injected", ev);
+ return;
+ }
+
+ /*
+ * Set the GED selector field to communicate the event type.
+ * This will be read by GED aml code to select the appropriate
+ * event method.
+ */
+ ged_st->sel |= sel;
+
+ /* Trigger the event by sending an interrupt to the guest. */
+ qemu_irq_pulse(s->irq);
+}
+
+static Property acpi_ged_properties[] = {
+ DEFINE_PROP_UINT32("ged-event", AcpiGedState, ged_event_bitmap, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vmstate_memhp_state = {
+ .name = "acpi-ged/memhp",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_MEMORY_HOTPLUG(memhp_state, AcpiGedState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_ged_state = {
+ .name = "acpi-ged-state",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(sel, GEDState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_acpi_ged = {
+ .name = "acpi-ged",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT(ged_state, AcpiGedState, 1, vmstate_ged_state, GEDState),
+ VMSTATE_END_OF_LIST(),
+ },
+ .subsections = (const VMStateDescription * []) {
+ &vmstate_memhp_state,
+ NULL
+ }
+};
+
+static void acpi_ged_initfn(Object *obj)
+{
+ DeviceState *dev = DEVICE(obj);
+ AcpiGedState *s = ACPI_GED(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ GEDState *ged_st = &s->ged_state;
+
+ memory_region_init_io(&ged_st->io, obj, &ged_ops, ged_st,
+ TYPE_ACPI_GED, ACPI_GED_EVT_SEL_LEN);
+ sysbus_init_mmio(sbd, &ged_st->io);
+
+ sysbus_init_irq(sbd, &s->irq);
+
+ s->memhp_state.is_enabled = true;
+ /*
+ * GED handles memory hotplug event and acpi-mem-hotplug
+ * memory region gets initialized here. Create an exclusive
+ * container for memory hotplug IO and expose it as GED sysbus
+ * MMIO so that boards can map it separately.
+ */
+ memory_region_init(&s->container_memhp, OBJECT(dev), "memhp container",
+ MEMORY_HOTPLUG_IO_LEN);
+ sysbus_init_mmio(sbd, &s->container_memhp);
+ acpi_memory_hotplug_init(&s->container_memhp, OBJECT(dev),
+ &s->memhp_state, 0);
+}
+
+static void acpi_ged_class_init(ObjectClass *class, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(class);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(class);
+ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(class);
+
+ dc->desc = "ACPI Generic Event Device";
+ dc->props = acpi_ged_properties;
+ dc->vmsd = &vmstate_acpi_ged;
+
+ hc->plug = acpi_ged_device_plug_cb;
+
+ adevc->send_event = acpi_ged_send_event;
+}
+
+static const TypeInfo acpi_ged_info = {
+ .name = TYPE_ACPI_GED,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(AcpiGedState),
+ .instance_init = acpi_ged_initfn,
+ .class_init = acpi_ged_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { TYPE_ACPI_DEVICE_IF },
+ { }
+ }
+};
+
+static void acpi_ged_register_types(void)
+{
+ type_register_static(&acpi_ged_info);
+}
+
+type_init(acpi_ged_register_types)
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
new file mode 100644
index 0000000000..2049e8d873
--- /dev/null
+++ b/include/hw/acpi/generic_event_device.h
@@ -0,0 +1,100 @@
+/*
+ *
+ * Copyright (c) 2018 Intel Corporation
+ * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd
+ * Written by Samuel Ortiz, Shameer Kolothum
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * The ACPI Generic Event Device (GED) is a hardware-reduced specific
+ * device[ACPI v6.1 Section 5.6.9] that handles all platform events,
+ * including the hotplug ones. Generic Event Device allows platforms
+ * to handle interrupts in ACPI ASL statements. It follows a very
+ * similar approach like the _EVT method from GPIO events. All
+ * interrupts are listed in _CRS and the handler is written in _EVT
+ * method. Here, we use a single interrupt for the GED device, relying
+ * on IO memory region to communicate the type of device affected by
+ * the interrupt. This way, we can support up to 32 events with a
+ * unique interrupt.
+ *
+ * Here is an example.
+ *
+ * Device (\_SB.GED)
+ * {
+ * Name (_HID, "ACPI0013")
+ * Name (_UID, Zero)
+ * Name (_CRS, ResourceTemplate ()
+ * {
+ * Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
+ * {
+ * 0x00000029,
+ * }
+ * })
+ * OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)
+ * Field (EREG, DWordAcc, NoLock, WriteAsZeros)
+ * {
+ * ESEL, 32
+ * }
+ *
+ * Method (_EVT, 1, Serialized) // _EVT: Event
+ * {
+ * Local0 = ESEL // ESEL = IO memory region which specifies the
+ * // device type.
+ * If (((Local0 & One) == One))
+ * {
+ * MethodEvent1()
+ * }
+ * If ((Local0 & 0x2) == 0x2)
+ * {
+ * MethodEvent2()
+ * }
+ * ...
+ * }
+ * }
+ *
+ */
+
+#ifndef HW_ACPI_GED_H
+#define HW_ACPI_GED_H
+
+#include "hw/sysbus.h"
+#include "hw/acpi/memory_hotplug.h"
+
+#define TYPE_ACPI_GED "acpi-ged"
+#define ACPI_GED(obj) \
+ OBJECT_CHECK(AcpiGedState, (obj), TYPE_ACPI_GED)
+
+#define ACPI_GED_EVT_SEL_OFFSET 0x0
+#define ACPI_GED_EVT_SEL_LEN 0x4
+
+#define GED_DEVICE "GED"
+#define AML_GED_EVT_REG "EREG"
+#define AML_GED_EVT_SEL "ESEL"
+
+/*
+ * Platforms need to specify the GED event bitmap
+ * to describe what kind of events they want to support
+ * through GED.
+ */
+#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
+
+typedef struct GEDState {
+ MemoryRegion io;
+ uint32_t sel;
+} GEDState;
+
+typedef struct AcpiGedState {
+ SysBusDevice parent_obj;
+ MemHotplugState memhp_state;
+ MemoryRegion container_memhp;
+ GEDState ged_state;
+ uint32_t ged_event_bitmap;
+ qemu_irq irq;
+} AcpiGedState;
+
+void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_dev,
+ uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base);
+
+#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [Qemu-devel] [PATCH-for-4.2 v11 03/11] hw/acpi: Add ACPI Generic Event Device Support
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 03/11] hw/acpi: Add ACPI Generic Event Device Support Shameer Kolothum
@ 2019-09-25 15:03 ` Igor Mammedov
2019-10-05 21:58 ` [PULL 04/19] " Michael S. Tsirkin
1 sibling, 0 replies; 60+ messages in thread
From: Igor Mammedov @ 2019-09-25 15:03 UTC (permalink / raw)
To: Shameer Kolothum
Cc: peter.maydell, sameo, ard.biesheuvel, shannon.zhaosl, mst,
qemu-devel, xuwei5, linuxarm, eric.auger, qemu-arm,
sebastien.boeuf, lersek
On Wed, 18 Sep 2019 14:06:25 +0100
Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> wrote:
> From: Samuel Ortiz <sameo@linux.intel.com>
>
> The ACPI Generic Event Device (GED) is a hardware-reduced specific
> device[ACPI v6.1 Section 5.6.9] that handles all platform events,
> including the hotplug ones. This patch generates the AML code that
> defines GEDs.
>
> Platforms need to specify their own GED Event bitmap to describe
> what kind of events they want to support through GED. Also this
> uses a a single interrupt for the GED device, relying on IO
> memory region to communicate the type of device affected by the
> interrupt. This way, we can support up to 32 events with a unique
> interrupt.
>
> This supports only memory hotplug for now.
>
> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
> Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> ---
> Addressed comments from Igor.
> - Removed memhp_state.is_enabled condition check and property.
> - Used instance_init() instead of realize()
> ---
> hw/acpi/Kconfig | 4 +
> hw/acpi/Makefile.objs | 1 +
> hw/acpi/generic_event_device.c | 303 +++++++++++++++++++++++++
> include/hw/acpi/generic_event_device.h | 100 ++++++++
> 4 files changed, 408 insertions(+)
> create mode 100644 hw/acpi/generic_event_device.c
> create mode 100644 include/hw/acpi/generic_event_device.h
>
> diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
> index 7c59cf900b..12e3f1e86e 100644
> --- a/hw/acpi/Kconfig
> +++ b/hw/acpi/Kconfig
> @@ -31,3 +31,7 @@ config ACPI_VMGENID
> bool
> default y
> depends on PC
> +
> +config ACPI_HW_REDUCED
> + bool
> + depends on ACPI
> diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
> index 9bb2101e3b..655a9c1973 100644
> --- a/hw/acpi/Makefile.objs
> +++ b/hw/acpi/Makefile.objs
> @@ -6,6 +6,7 @@ common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
> common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
> common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
> common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
> +common-obj-$(CONFIG_ACPI_HW_REDUCED) += generic_event_device.o
> common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
>
> common-obj-y += acpi_interface.o
> diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
> new file mode 100644
> index 0000000000..b94500b08d
> --- /dev/null
> +++ b/hw/acpi/generic_event_device.c
> @@ -0,0 +1,303 @@
> +/*
> + *
> + * Copyright (c) 2018 Intel Corporation
> + * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd
> + * Written by Samuel Ortiz, Shameer Kolothum
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "exec/address-spaces.h"
> +#include "hw/acpi/acpi.h"
> +#include "hw/acpi/generic_event_device.h"
> +#include "hw/irq.h"
> +#include "hw/mem/pc-dimm.h"
> +#include "hw/qdev-properties.h"
> +#include "migration/vmstate.h"
> +#include "qemu/error-report.h"
> +
> +static const uint32_t ged_supported_events[] = {
> + ACPI_GED_MEM_HOTPLUG_EVT,
> +};
> +
> +/*
> + * The ACPI Generic Event Device (GED) is a hardware-reduced specific
> + * device[ACPI v6.1 Section 5.6.9] that handles all platform events,
> + * including the hotplug ones. Platforms need to specify their own
> + * GED Event bitmap to describe what kind of events they want to support
> + * through GED. This routine uses a single interrupt for the GED device,
> + * relying on IO memory region to communicate the type of device
> + * affected by the interrupt. This way, we can support up to 32 events
> + * with a unique interrupt.
> + */
> +void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
> + uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base)
> +{
> + AcpiGedState *s = ACPI_GED(hotplug_dev);
> + Aml *crs = aml_resource_template();
> + Aml *evt, *field;
> + Aml *dev = aml_device("%s", name);
> + Aml *evt_sel = aml_local(0);
> + Aml *esel = aml_name(AML_GED_EVT_SEL);
> +
> + /* _CRS interrupt */
> + aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH,
> + AML_EXCLUSIVE, &ged_irq, 1));
> +
> + aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0013")));
> + aml_append(dev, aml_name_decl("_UID", aml_string(GED_DEVICE)));
> + aml_append(dev, aml_name_decl("_CRS", crs));
> +
> + /* Append IO region */
> + aml_append(dev, aml_operation_region(AML_GED_EVT_REG, rs,
> + aml_int(ged_base + ACPI_GED_EVT_SEL_OFFSET),
> + ACPI_GED_EVT_SEL_LEN));
> + field = aml_field(AML_GED_EVT_REG, AML_DWORD_ACC, AML_NOLOCK,
> + AML_WRITE_AS_ZEROS);
> + aml_append(field, aml_named_field(AML_GED_EVT_SEL,
> + ACPI_GED_EVT_SEL_LEN * BITS_PER_BYTE));
> + aml_append(dev, field);
> +
> + /*
> + * For each GED event we:
> + * - Add a conditional block for each event, inside a loop.
> + * - Call a method for each supported GED event type.
> + *
> + * The resulting ASL code looks like:
> + *
> + * Local0 = ESEL
> + * If ((Local0 & One) == One)
> + * {
> + * MethodEvent0()
> + * }
> + *
> + * If ((Local0 & 0x2) == 0x2)
> + * {
> + * MethodEvent1()
> + * }
> + * ...
> + */
> + evt = aml_method("_EVT", 1, AML_SERIALIZED);
> + {
> + Aml *if_ctx;
> + uint32_t i;
> + uint32_t ged_events = ctpop32(s->ged_event_bitmap);
> +
> + /* Local0 = ESEL */
> + aml_append(evt, aml_store(esel, evt_sel));
> +
> + for (i = 0; i < ARRAY_SIZE(ged_supported_events) && ged_events; i++) {
> + uint32_t event = s->ged_event_bitmap & ged_supported_events[i];
> +
> + if (!event) {
> + continue;
> + }
> +
> + if_ctx = aml_if(aml_equal(aml_and(evt_sel, aml_int(event), NULL),
> + aml_int(event)));
> + switch (event) {
> + case ACPI_GED_MEM_HOTPLUG_EVT:
> + aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
> + MEMORY_SLOT_SCAN_METHOD));
> + break;
> + default:
> + /*
> + * Please make sure all the events in ged_supported_events[]
> + * are handled above.
> + */
> + g_assert_not_reached();
> + }
> +
> + aml_append(evt, if_ctx);
> + ged_events--;
> + }
> +
> + if (ged_events) {
> + error_report("Unsupported events specified");
> + abort();
> + }
> + }
> +
> + /* Append _EVT method */
> + aml_append(dev, evt);
> +
> + aml_append(table, dev);
> +}
> +
> +/* Memory read by the GED _EVT AML dynamic method */
> +static uint64_t ged_read(void *opaque, hwaddr addr, unsigned size)
> +{
> + uint64_t val = 0;
> + GEDState *ged_st = opaque;
> +
> + switch (addr) {
> + case ACPI_GED_EVT_SEL_OFFSET:
> + /* Read the selector value and reset it */
> + val = ged_st->sel;
> + ged_st->sel = 0;
> + break;
> + default:
> + break;
> + }
> +
> + return val;
> +}
> +
> +/* Nothing is expected to be written to the GED memory region */
> +static void ged_write(void *opaque, hwaddr addr, uint64_t data,
> + unsigned int size)
> +{
> +}
> +
> +static const MemoryRegionOps ged_ops = {
> + .read = ged_read,
> + .write = ged_write,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> + .valid = {
> + .min_access_size = 4,
> + .max_access_size = 4,
> + },
> +};
> +
> +static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
> + DeviceState *dev, Error **errp)
> +{
> + AcpiGedState *s = ACPI_GED(hotplug_dev);
> +
> + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> + acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
> + } else {
> + error_setg(errp, "virt: device plug request for unsupported device"
> + " type: %s", object_get_typename(OBJECT(dev)));
> + }
> +}
> +
> +static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
> +{
> + AcpiGedState *s = ACPI_GED(adev);
> + GEDState *ged_st = &s->ged_state;
> + uint32_t sel;
> +
> + if (ev & ACPI_MEMORY_HOTPLUG_STATUS) {
> + sel = ACPI_GED_MEM_HOTPLUG_EVT;
> + } else {
> + /* Unknown event. Return without generating interrupt. */
> + warn_report("GED: Unsupported event %d. No irq injected", ev);
> + return;
> + }
> +
> + /*
> + * Set the GED selector field to communicate the event type.
> + * This will be read by GED aml code to select the appropriate
> + * event method.
> + */
> + ged_st->sel |= sel;
> +
> + /* Trigger the event by sending an interrupt to the guest. */
> + qemu_irq_pulse(s->irq);
> +}
> +
> +static Property acpi_ged_properties[] = {
> + DEFINE_PROP_UINT32("ged-event", AcpiGedState, ged_event_bitmap, 0),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static const VMStateDescription vmstate_memhp_state = {
> + .name = "acpi-ged/memhp",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .fields = (VMStateField[]) {
> + VMSTATE_MEMORY_HOTPLUG(memhp_state, AcpiGedState),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> +static const VMStateDescription vmstate_ged_state = {
> + .name = "acpi-ged-state",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .fields = (VMStateField[]) {
> + VMSTATE_UINT32(sel, GEDState),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> +static const VMStateDescription vmstate_acpi_ged = {
> + .name = "acpi-ged",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .fields = (VMStateField[]) {
> + VMSTATE_STRUCT(ged_state, AcpiGedState, 1, vmstate_ged_state, GEDState),
> + VMSTATE_END_OF_LIST(),
> + },
> + .subsections = (const VMStateDescription * []) {
> + &vmstate_memhp_state,
> + NULL
> + }
> +};
> +
> +static void acpi_ged_initfn(Object *obj)
> +{
> + DeviceState *dev = DEVICE(obj);
> + AcpiGedState *s = ACPI_GED(dev);
> + SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
> + GEDState *ged_st = &s->ged_state;
> +
> + memory_region_init_io(&ged_st->io, obj, &ged_ops, ged_st,
> + TYPE_ACPI_GED, ACPI_GED_EVT_SEL_LEN);
> + sysbus_init_mmio(sbd, &ged_st->io);
> +
> + sysbus_init_irq(sbd, &s->irq);
> +
> + s->memhp_state.is_enabled = true;
> + /*
> + * GED handles memory hotplug event and acpi-mem-hotplug
> + * memory region gets initialized here. Create an exclusive
> + * container for memory hotplug IO and expose it as GED sysbus
> + * MMIO so that boards can map it separately.
> + */
> + memory_region_init(&s->container_memhp, OBJECT(dev), "memhp container",
> + MEMORY_HOTPLUG_IO_LEN);
> + sysbus_init_mmio(sbd, &s->container_memhp);
> + acpi_memory_hotplug_init(&s->container_memhp, OBJECT(dev),
> + &s->memhp_state, 0);
> +}
> +
> +static void acpi_ged_class_init(ObjectClass *class, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(class);
> + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(class);
> + AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(class);
> +
> + dc->desc = "ACPI Generic Event Device";
> + dc->props = acpi_ged_properties;
> + dc->vmsd = &vmstate_acpi_ged;
> +
> + hc->plug = acpi_ged_device_plug_cb;
> +
> + adevc->send_event = acpi_ged_send_event;
> +}
> +
> +static const TypeInfo acpi_ged_info = {
> + .name = TYPE_ACPI_GED,
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(AcpiGedState),
> + .instance_init = acpi_ged_initfn,
> + .class_init = acpi_ged_class_init,
> + .interfaces = (InterfaceInfo[]) {
> + { TYPE_HOTPLUG_HANDLER },
> + { TYPE_ACPI_DEVICE_IF },
> + { }
> + }
> +};
> +
> +static void acpi_ged_register_types(void)
> +{
> + type_register_static(&acpi_ged_info);
> +}
> +
> +type_init(acpi_ged_register_types)
> diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
> new file mode 100644
> index 0000000000..2049e8d873
> --- /dev/null
> +++ b/include/hw/acpi/generic_event_device.h
> @@ -0,0 +1,100 @@
> +/*
> + *
> + * Copyright (c) 2018 Intel Corporation
> + * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd
> + * Written by Samuel Ortiz, Shameer Kolothum
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * The ACPI Generic Event Device (GED) is a hardware-reduced specific
> + * device[ACPI v6.1 Section 5.6.9] that handles all platform events,
> + * including the hotplug ones. Generic Event Device allows platforms
> + * to handle interrupts in ACPI ASL statements. It follows a very
> + * similar approach like the _EVT method from GPIO events. All
> + * interrupts are listed in _CRS and the handler is written in _EVT
> + * method. Here, we use a single interrupt for the GED device, relying
> + * on IO memory region to communicate the type of device affected by
> + * the interrupt. This way, we can support up to 32 events with a
> + * unique interrupt.
> + *
> + * Here is an example.
> + *
> + * Device (\_SB.GED)
> + * {
> + * Name (_HID, "ACPI0013")
> + * Name (_UID, Zero)
> + * Name (_CRS, ResourceTemplate ()
> + * {
> + * Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
> + * {
> + * 0x00000029,
> + * }
> + * })
> + * OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)
> + * Field (EREG, DWordAcc, NoLock, WriteAsZeros)
> + * {
> + * ESEL, 32
> + * }
> + *
> + * Method (_EVT, 1, Serialized) // _EVT: Event
> + * {
> + * Local0 = ESEL // ESEL = IO memory region which specifies the
> + * // device type.
> + * If (((Local0 & One) == One))
> + * {
> + * MethodEvent1()
> + * }
> + * If ((Local0 & 0x2) == 0x2)
> + * {
> + * MethodEvent2()
> + * }
> + * ...
> + * }
> + * }
> + *
> + */
> +
> +#ifndef HW_ACPI_GED_H
> +#define HW_ACPI_GED_H
> +
> +#include "hw/sysbus.h"
> +#include "hw/acpi/memory_hotplug.h"
> +
> +#define TYPE_ACPI_GED "acpi-ged"
> +#define ACPI_GED(obj) \
> + OBJECT_CHECK(AcpiGedState, (obj), TYPE_ACPI_GED)
> +
> +#define ACPI_GED_EVT_SEL_OFFSET 0x0
> +#define ACPI_GED_EVT_SEL_LEN 0x4
> +
> +#define GED_DEVICE "GED"
> +#define AML_GED_EVT_REG "EREG"
> +#define AML_GED_EVT_SEL "ESEL"
> +
> +/*
> + * Platforms need to specify the GED event bitmap
> + * to describe what kind of events they want to support
> + * through GED.
> + */
> +#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
> +
> +typedef struct GEDState {
> + MemoryRegion io;
> + uint32_t sel;
> +} GEDState;
> +
> +typedef struct AcpiGedState {
> + SysBusDevice parent_obj;
> + MemHotplugState memhp_state;
> + MemoryRegion container_memhp;
> + GEDState ged_state;
> + uint32_t ged_event_bitmap;
> + qemu_irq irq;
> +} AcpiGedState;
> +
> +void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_dev,
> + uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base);
> +
> +#endif
^ permalink raw reply [flat|nested] 60+ messages in thread
* [PULL 04/19] hw/acpi: Add ACPI Generic Event Device Support
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 03/11] hw/acpi: Add ACPI Generic Event Device Support Shameer Kolothum
2019-09-25 15:03 ` Igor Mammedov
@ 2019-10-05 21:58 ` Michael S. Tsirkin
1 sibling, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:58 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Samuel Ortiz, Shameer Kolothum, Eric Auger,
Sebastien Boeuf, Igor Mammedov
From: Samuel Ortiz <sameo@linux.intel.com>
The ACPI Generic Event Device (GED) is a hardware-reduced specific
device[ACPI v6.1 Section 5.6.9] that handles all platform events,
including the hotplug ones. This patch generates the AML code that
defines GEDs.
Platforms need to specify their own GED Event bitmap to describe
what kind of events they want to support through GED. Also this
uses a a single interrupt for the GED device, relying on IO
memory region to communicate the type of device affected by the
interrupt. This way, we can support up to 32 events with a unique
interrupt.
This supports only memory hotplug for now.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-Id: <20190918130633.4872-4-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
---
hw/acpi/Kconfig | 4 +
hw/acpi/Makefile.objs | 1 +
hw/acpi/generic_event_device.c | 303 +++++++++++++++++++++++++
include/hw/acpi/generic_event_device.h | 100 ++++++++
4 files changed, 408 insertions(+)
create mode 100644 hw/acpi/generic_event_device.c
create mode 100644 include/hw/acpi/generic_event_device.h
diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index 7c59cf900b..12e3f1e86e 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -31,3 +31,7 @@ config ACPI_VMGENID
bool
default y
depends on PC
+
+config ACPI_HW_REDUCED
+ bool
+ depends on ACPI
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 9bb2101e3b..655a9c1973 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -6,6 +6,7 @@ common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
+common-obj-$(CONFIG_ACPI_HW_REDUCED) += generic_event_device.o
common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
common-obj-y += acpi_interface.o
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
new file mode 100644
index 0000000000..b94500b08d
--- /dev/null
+++ b/hw/acpi/generic_event_device.c
@@ -0,0 +1,303 @@
+/*
+ *
+ * Copyright (c) 2018 Intel Corporation
+ * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd
+ * Written by Samuel Ortiz, Shameer Kolothum
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "exec/address-spaces.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/generic_event_device.h"
+#include "hw/irq.h"
+#include "hw/mem/pc-dimm.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qemu/error-report.h"
+
+static const uint32_t ged_supported_events[] = {
+ ACPI_GED_MEM_HOTPLUG_EVT,
+};
+
+/*
+ * The ACPI Generic Event Device (GED) is a hardware-reduced specific
+ * device[ACPI v6.1 Section 5.6.9] that handles all platform events,
+ * including the hotplug ones. Platforms need to specify their own
+ * GED Event bitmap to describe what kind of events they want to support
+ * through GED. This routine uses a single interrupt for the GED device,
+ * relying on IO memory region to communicate the type of device
+ * affected by the interrupt. This way, we can support up to 32 events
+ * with a unique interrupt.
+ */
+void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
+ uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base)
+{
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
+ Aml *crs = aml_resource_template();
+ Aml *evt, *field;
+ Aml *dev = aml_device("%s", name);
+ Aml *evt_sel = aml_local(0);
+ Aml *esel = aml_name(AML_GED_EVT_SEL);
+
+ /* _CRS interrupt */
+ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH,
+ AML_EXCLUSIVE, &ged_irq, 1));
+
+ aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0013")));
+ aml_append(dev, aml_name_decl("_UID", aml_string(GED_DEVICE)));
+ aml_append(dev, aml_name_decl("_CRS", crs));
+
+ /* Append IO region */
+ aml_append(dev, aml_operation_region(AML_GED_EVT_REG, rs,
+ aml_int(ged_base + ACPI_GED_EVT_SEL_OFFSET),
+ ACPI_GED_EVT_SEL_LEN));
+ field = aml_field(AML_GED_EVT_REG, AML_DWORD_ACC, AML_NOLOCK,
+ AML_WRITE_AS_ZEROS);
+ aml_append(field, aml_named_field(AML_GED_EVT_SEL,
+ ACPI_GED_EVT_SEL_LEN * BITS_PER_BYTE));
+ aml_append(dev, field);
+
+ /*
+ * For each GED event we:
+ * - Add a conditional block for each event, inside a loop.
+ * - Call a method for each supported GED event type.
+ *
+ * The resulting ASL code looks like:
+ *
+ * Local0 = ESEL
+ * If ((Local0 & One) == One)
+ * {
+ * MethodEvent0()
+ * }
+ *
+ * If ((Local0 & 0x2) == 0x2)
+ * {
+ * MethodEvent1()
+ * }
+ * ...
+ */
+ evt = aml_method("_EVT", 1, AML_SERIALIZED);
+ {
+ Aml *if_ctx;
+ uint32_t i;
+ uint32_t ged_events = ctpop32(s->ged_event_bitmap);
+
+ /* Local0 = ESEL */
+ aml_append(evt, aml_store(esel, evt_sel));
+
+ for (i = 0; i < ARRAY_SIZE(ged_supported_events) && ged_events; i++) {
+ uint32_t event = s->ged_event_bitmap & ged_supported_events[i];
+
+ if (!event) {
+ continue;
+ }
+
+ if_ctx = aml_if(aml_equal(aml_and(evt_sel, aml_int(event), NULL),
+ aml_int(event)));
+ switch (event) {
+ case ACPI_GED_MEM_HOTPLUG_EVT:
+ aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
+ MEMORY_SLOT_SCAN_METHOD));
+ break;
+ default:
+ /*
+ * Please make sure all the events in ged_supported_events[]
+ * are handled above.
+ */
+ g_assert_not_reached();
+ }
+
+ aml_append(evt, if_ctx);
+ ged_events--;
+ }
+
+ if (ged_events) {
+ error_report("Unsupported events specified");
+ abort();
+ }
+ }
+
+ /* Append _EVT method */
+ aml_append(dev, evt);
+
+ aml_append(table, dev);
+}
+
+/* Memory read by the GED _EVT AML dynamic method */
+static uint64_t ged_read(void *opaque, hwaddr addr, unsigned size)
+{
+ uint64_t val = 0;
+ GEDState *ged_st = opaque;
+
+ switch (addr) {
+ case ACPI_GED_EVT_SEL_OFFSET:
+ /* Read the selector value and reset it */
+ val = ged_st->sel;
+ ged_st->sel = 0;
+ break;
+ default:
+ break;
+ }
+
+ return val;
+}
+
+/* Nothing is expected to be written to the GED memory region */
+static void ged_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
+{
+}
+
+static const MemoryRegionOps ged_ops = {
+ .read = ged_read,
+ .write = ged_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
+
+static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
+
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
+ } else {
+ error_setg(errp, "virt: device plug request for unsupported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+ }
+}
+
+static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
+{
+ AcpiGedState *s = ACPI_GED(adev);
+ GEDState *ged_st = &s->ged_state;
+ uint32_t sel;
+
+ if (ev & ACPI_MEMORY_HOTPLUG_STATUS) {
+ sel = ACPI_GED_MEM_HOTPLUG_EVT;
+ } else {
+ /* Unknown event. Return without generating interrupt. */
+ warn_report("GED: Unsupported event %d. No irq injected", ev);
+ return;
+ }
+
+ /*
+ * Set the GED selector field to communicate the event type.
+ * This will be read by GED aml code to select the appropriate
+ * event method.
+ */
+ ged_st->sel |= sel;
+
+ /* Trigger the event by sending an interrupt to the guest. */
+ qemu_irq_pulse(s->irq);
+}
+
+static Property acpi_ged_properties[] = {
+ DEFINE_PROP_UINT32("ged-event", AcpiGedState, ged_event_bitmap, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vmstate_memhp_state = {
+ .name = "acpi-ged/memhp",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_MEMORY_HOTPLUG(memhp_state, AcpiGedState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_ged_state = {
+ .name = "acpi-ged-state",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(sel, GEDState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_acpi_ged = {
+ .name = "acpi-ged",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT(ged_state, AcpiGedState, 1, vmstate_ged_state, GEDState),
+ VMSTATE_END_OF_LIST(),
+ },
+ .subsections = (const VMStateDescription * []) {
+ &vmstate_memhp_state,
+ NULL
+ }
+};
+
+static void acpi_ged_initfn(Object *obj)
+{
+ DeviceState *dev = DEVICE(obj);
+ AcpiGedState *s = ACPI_GED(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ GEDState *ged_st = &s->ged_state;
+
+ memory_region_init_io(&ged_st->io, obj, &ged_ops, ged_st,
+ TYPE_ACPI_GED, ACPI_GED_EVT_SEL_LEN);
+ sysbus_init_mmio(sbd, &ged_st->io);
+
+ sysbus_init_irq(sbd, &s->irq);
+
+ s->memhp_state.is_enabled = true;
+ /*
+ * GED handles memory hotplug event and acpi-mem-hotplug
+ * memory region gets initialized here. Create an exclusive
+ * container for memory hotplug IO and expose it as GED sysbus
+ * MMIO so that boards can map it separately.
+ */
+ memory_region_init(&s->container_memhp, OBJECT(dev), "memhp container",
+ MEMORY_HOTPLUG_IO_LEN);
+ sysbus_init_mmio(sbd, &s->container_memhp);
+ acpi_memory_hotplug_init(&s->container_memhp, OBJECT(dev),
+ &s->memhp_state, 0);
+}
+
+static void acpi_ged_class_init(ObjectClass *class, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(class);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(class);
+ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(class);
+
+ dc->desc = "ACPI Generic Event Device";
+ dc->props = acpi_ged_properties;
+ dc->vmsd = &vmstate_acpi_ged;
+
+ hc->plug = acpi_ged_device_plug_cb;
+
+ adevc->send_event = acpi_ged_send_event;
+}
+
+static const TypeInfo acpi_ged_info = {
+ .name = TYPE_ACPI_GED,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(AcpiGedState),
+ .instance_init = acpi_ged_initfn,
+ .class_init = acpi_ged_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { TYPE_ACPI_DEVICE_IF },
+ { }
+ }
+};
+
+static void acpi_ged_register_types(void)
+{
+ type_register_static(&acpi_ged_info);
+}
+
+type_init(acpi_ged_register_types)
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
new file mode 100644
index 0000000000..2049e8d873
--- /dev/null
+++ b/include/hw/acpi/generic_event_device.h
@@ -0,0 +1,100 @@
+/*
+ *
+ * Copyright (c) 2018 Intel Corporation
+ * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd
+ * Written by Samuel Ortiz, Shameer Kolothum
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * The ACPI Generic Event Device (GED) is a hardware-reduced specific
+ * device[ACPI v6.1 Section 5.6.9] that handles all platform events,
+ * including the hotplug ones. Generic Event Device allows platforms
+ * to handle interrupts in ACPI ASL statements. It follows a very
+ * similar approach like the _EVT method from GPIO events. All
+ * interrupts are listed in _CRS and the handler is written in _EVT
+ * method. Here, we use a single interrupt for the GED device, relying
+ * on IO memory region to communicate the type of device affected by
+ * the interrupt. This way, we can support up to 32 events with a
+ * unique interrupt.
+ *
+ * Here is an example.
+ *
+ * Device (\_SB.GED)
+ * {
+ * Name (_HID, "ACPI0013")
+ * Name (_UID, Zero)
+ * Name (_CRS, ResourceTemplate ()
+ * {
+ * Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
+ * {
+ * 0x00000029,
+ * }
+ * })
+ * OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)
+ * Field (EREG, DWordAcc, NoLock, WriteAsZeros)
+ * {
+ * ESEL, 32
+ * }
+ *
+ * Method (_EVT, 1, Serialized) // _EVT: Event
+ * {
+ * Local0 = ESEL // ESEL = IO memory region which specifies the
+ * // device type.
+ * If (((Local0 & One) == One))
+ * {
+ * MethodEvent1()
+ * }
+ * If ((Local0 & 0x2) == 0x2)
+ * {
+ * MethodEvent2()
+ * }
+ * ...
+ * }
+ * }
+ *
+ */
+
+#ifndef HW_ACPI_GED_H
+#define HW_ACPI_GED_H
+
+#include "hw/sysbus.h"
+#include "hw/acpi/memory_hotplug.h"
+
+#define TYPE_ACPI_GED "acpi-ged"
+#define ACPI_GED(obj) \
+ OBJECT_CHECK(AcpiGedState, (obj), TYPE_ACPI_GED)
+
+#define ACPI_GED_EVT_SEL_OFFSET 0x0
+#define ACPI_GED_EVT_SEL_LEN 0x4
+
+#define GED_DEVICE "GED"
+#define AML_GED_EVT_REG "EREG"
+#define AML_GED_EVT_SEL "ESEL"
+
+/*
+ * Platforms need to specify the GED event bitmap
+ * to describe what kind of events they want to support
+ * through GED.
+ */
+#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
+
+typedef struct GEDState {
+ MemoryRegion io;
+ uint32_t sel;
+} GEDState;
+
+typedef struct AcpiGedState {
+ SysBusDevice parent_obj;
+ MemHotplugState memhp_state;
+ MemoryRegion container_memhp;
+ GEDState ged_state;
+ uint32_t ged_event_bitmap;
+ qemu_irq irq;
+} AcpiGedState;
+
+void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_dev,
+ uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base);
+
+#endif
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 04/11] hw/arm/virt: Add memory hotplug framework
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (2 preceding siblings ...)
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 03/11] hw/acpi: Add ACPI Generic Event Device Support Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-10-05 21:58 ` [PULL 05/19] " Michael S. Tsirkin
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 05/11] hw/arm/virt: Enable device memory cold/hot plug with ACPI boot Shameer Kolothum
` (11 subsequent siblings)
15 siblings, 1 reply; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
From: Eric Auger <eric.auger@redhat.com>
This patch adds the memory hot-plug/hot-unplug infrastructure
in machvirt. The device memory is not yet exposed to the Guest
either through DT or ACPI and hence both cold/hot plug of memory
is explicitly disabled for now.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Kwangwoo Lee <kwangwoo.lee@sk.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
---
hw/arm/Kconfig | 2 ++
hw/arm/virt.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 76a2a6bcbf..39d285ad3d 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -20,6 +20,8 @@ config ARM_VIRT
select SMBIOS
select VIRTIO_MMIO
select ACPI_PCI
+ select MEM_DEVICE
+ select DIMM
config CHEETAH
bool
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d74538b021..1c967e3fee 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -68,6 +68,8 @@
#include "hw/arm/smmuv3.h"
#include "hw/acpi/acpi.h"
#include "target/arm/internals.h"
+#include "hw/mem/pc-dimm.h"
+#include "hw/mem/nvdimm.h"
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -1876,6 +1878,42 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
return ms->possible_cpus;
}
+static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
+{
+
+ /*
+ * The device memory is not yet exposed to the Guest either through
+ * DT or ACPI and hence both cold/hot plug of memory is explicitly
+ * disabled for now.
+ */
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ error_setg(errp, "memory cold/hot plug is not yet supported");
+ return;
+ }
+
+ pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp);
+}
+
+static void virt_memory_plug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+ Error *local_err = NULL;
+
+ pc_dimm_plug(PC_DIMM(dev), MACHINE(vms), &local_err);
+
+ error_propagate(errp, local_err);
+}
+
+static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ virt_memory_pre_plug(hotplug_dev, dev, errp);
+ }
+}
+
static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
@@ -1887,12 +1925,23 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
SYS_BUS_DEVICE(dev));
}
}
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ virt_memory_plug(hotplug_dev, dev, errp);
+ }
+}
+
+static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ error_setg(errp, "device unplug request for unsupported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
}
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
DeviceState *dev)
{
- if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) {
+ if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE) ||
+ (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
return HOTPLUG_HANDLER(machine);
}
@@ -1956,7 +2005,9 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->kvm_type = virt_kvm_type;
assert(!mc->get_hotplug_handler);
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
+ hc->pre_plug = virt_machine_device_pre_plug_cb;
hc->plug = virt_machine_device_plug_cb;
+ hc->unplug_request = virt_machine_device_unplug_request_cb;
mc->numa_mem_supported = true;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [PULL 05/19] hw/arm/virt: Add memory hotplug framework
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 04/11] hw/arm/virt: Add memory hotplug framework Shameer Kolothum
@ 2019-10-05 21:58 ` Michael S. Tsirkin
0 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:58 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Shameer Kolothum, Eric Auger, qemu-arm,
Igor Mammedov, Kwangwoo Lee
From: Eric Auger <eric.auger@redhat.com>
This patch adds the memory hot-plug/hot-unplug infrastructure
in machvirt. The device memory is not yet exposed to the Guest
either through DT or ACPI and hence both cold/hot plug of memory
is explicitly disabled for now.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Kwangwoo Lee <kwangwoo.lee@sk.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20190918130633.4872-5-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/arm/Kconfig | 2 ++
hw/arm/virt.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 76a2a6bcbf..39d285ad3d 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -20,6 +20,8 @@ config ARM_VIRT
select SMBIOS
select VIRTIO_MMIO
select ACPI_PCI
+ select MEM_DEVICE
+ select DIMM
config CHEETAH
bool
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d74538b021..1c967e3fee 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -68,6 +68,8 @@
#include "hw/arm/smmuv3.h"
#include "hw/acpi/acpi.h"
#include "target/arm/internals.h"
+#include "hw/mem/pc-dimm.h"
+#include "hw/mem/nvdimm.h"
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -1876,6 +1878,42 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
return ms->possible_cpus;
}
+static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
+{
+
+ /*
+ * The device memory is not yet exposed to the Guest either through
+ * DT or ACPI and hence both cold/hot plug of memory is explicitly
+ * disabled for now.
+ */
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ error_setg(errp, "memory cold/hot plug is not yet supported");
+ return;
+ }
+
+ pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp);
+}
+
+static void virt_memory_plug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+ Error *local_err = NULL;
+
+ pc_dimm_plug(PC_DIMM(dev), MACHINE(vms), &local_err);
+
+ error_propagate(errp, local_err);
+}
+
+static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ virt_memory_pre_plug(hotplug_dev, dev, errp);
+ }
+}
+
static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
@@ -1887,12 +1925,23 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
SYS_BUS_DEVICE(dev));
}
}
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ virt_memory_plug(hotplug_dev, dev, errp);
+ }
+}
+
+static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ error_setg(errp, "device unplug request for unsupported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
}
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
DeviceState *dev)
{
- if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) {
+ if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE) ||
+ (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
return HOTPLUG_HANDLER(machine);
}
@@ -1956,7 +2005,9 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->kvm_type = virt_kvm_type;
assert(!mc->get_hotplug_handler);
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
+ hc->pre_plug = virt_machine_device_pre_plug_cb;
hc->plug = virt_machine_device_plug_cb;
+ hc->unplug_request = virt_machine_device_unplug_request_cb;
mc->numa_mem_supported = true;
}
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 05/11] hw/arm/virt: Enable device memory cold/hot plug with ACPI boot
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (3 preceding siblings ...)
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 04/11] hw/arm/virt: Add memory hotplug framework Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-09-25 15:06 ` Igor Mammedov
2019-10-05 21:59 ` [PULL 06/19] " Michael S. Tsirkin
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 06/11] hw/arm/virt-acpi-build: Add PC-DIMM in SRAT Shameer Kolothum
` (10 subsequent siblings)
15 siblings, 2 replies; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
This initializes the GED device with base memory and irq, configures
ged memory hotplug event and builds the corresponding aml code. With
this, both hot and cold plug of device memory is enabled now for Guest
with ACPI boot. Memory cold plug support with Guest DT boot is not yet
supported.
As DSDT table gets changed by this, update bios-tables-test-allowed-diff.h
to avoid "make check" failure.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
v10--> v11
Update based on Igor's comments,
- Invoke build_memory_hotplug_aml() based on ged-event property.
---
hw/arm/Kconfig | 2 +
hw/arm/virt-acpi-build.c | 21 ++++++++++
hw/arm/virt.c | 59 +++++++++++++++++++++++----
include/hw/arm/virt.h | 4 ++
tests/bios-tables-test-allowed-diff.h | 1 +
5 files changed, 80 insertions(+), 7 deletions(-)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 39d285ad3d..c6e7782580 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -22,6 +22,8 @@ config ARM_VIRT
select ACPI_PCI
select MEM_DEVICE
select DIMM
+ select ACPI_MEMORY_HOTPLUG
+ select ACPI_HW_REDUCED
config CHEETAH
bool
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 6cdf156cf5..cadeea0f41 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -39,6 +39,8 @@
#include "hw/acpi/aml-build.h"
#include "hw/acpi/utils.h"
#include "hw/acpi/pci.h"
+#include "hw/acpi/memory_hotplug.h"
+#include "hw/acpi/generic_event_device.h"
#include "hw/pci/pcie_host.h"
#include "hw/pci/pci.h"
#include "hw/arm/virt.h"
@@ -708,6 +710,7 @@ static void
build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
{
Aml *scope, *dsdt;
+ MachineState *ms = MACHINE(vms);
const MemMapEntry *memmap = vms->memmap;
const int *irqmap = vms->irqmap;
@@ -732,6 +735,24 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
vms->highmem, vms->highmem_ecam);
acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
(irqmap[VIRT_GPIO] + ARM_SPI_BASE));
+ if (vms->acpi_dev) {
+ build_ged_aml(scope, "\\_SB."GED_DEVICE,
+ HOTPLUG_HANDLER(vms->acpi_dev),
+ irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
+ memmap[VIRT_ACPI_GED].base);
+ }
+
+ if (vms->acpi_dev) {
+ uint32_t event = object_property_get_uint(OBJECT(vms->acpi_dev),
+ "ged-event", &error_abort);
+
+ if (event & ACPI_GED_MEM_HOTPLUG_EVT) {
+ build_memory_hotplug_aml(scope, ms->ram_slots, "\\_SB", NULL,
+ AML_SYSTEM_MEMORY,
+ memmap[VIRT_PCDIMM_ACPI].base);
+ }
+ }
+
acpi_dsdt_add_power_button(scope);
aml_append(dsdt, scope);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1c967e3fee..f926477ba5 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -70,6 +70,7 @@
#include "target/arm/internals.h"
#include "hw/mem/pc-dimm.h"
#include "hw/mem/nvdimm.h"
+#include "hw/acpi/generic_event_device.h"
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -140,6 +141,8 @@ static const MemMapEntry base_memmap[] = {
[VIRT_GPIO] = { 0x09030000, 0x00001000 },
[VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
[VIRT_SMMU] = { 0x09050000, 0x00020000 },
+ [VIRT_PCDIMM_ACPI] = { 0x09070000, MEMORY_HOTPLUG_IO_LEN },
+ [VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
@@ -175,6 +178,7 @@ static const int a15irqmap[] = {
[VIRT_PCIE] = 3, /* ... to 6 */
[VIRT_GPIO] = 7,
[VIRT_SECURE_UART] = 8,
+ [VIRT_ACPI_GED] = 9,
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
[VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
[VIRT_SMMU] = 74, /* ...to 74 + NUM_SMMU_IRQS - 1 */
@@ -527,6 +531,29 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
}
}
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
+{
+ DeviceState *dev;
+ MachineState *ms = MACHINE(vms);
+ int irq = vms->irqmap[VIRT_ACPI_GED];
+ uint32_t event = 0;
+
+ if (ms->ram_slots) {
+ event = ACPI_GED_MEM_HOTPLUG_EVT;
+ }
+
+ dev = qdev_create(NULL, TYPE_ACPI_GED);
+ qdev_prop_set_uint32(dev, "ged-event", event);
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
+
+ qdev_init_nofail(dev);
+
+ return dev;
+}
+
static void create_its(VirtMachineState *vms, DeviceState *gicdev)
{
const char *itsclass = its_class_name();
@@ -1491,6 +1518,7 @@ static void machvirt_init(MachineState *machine)
MemoryRegion *ram = g_new(MemoryRegion, 1);
bool firmware_loaded;
bool aarch64 = true;
+ bool has_ged = !vmc->no_ged;
unsigned int smp_cpus = machine->smp.cpus;
unsigned int max_cpus = machine->smp.max_cpus;
@@ -1705,6 +1733,10 @@ static void machvirt_init(MachineState *machine)
create_gpio(vms, pic);
+ if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
+ vms->acpi_dev = create_acpi_ged(vms, pic);
+ }
+
/* Create mmio transports, so the user can create virtio backends
* (which will be automatically plugged in to the transports). If
* no backend is created the transport will just sit harmlessly idle.
@@ -1881,14 +1913,17 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+ const bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
- /*
- * The device memory is not yet exposed to the Guest either through
- * DT or ACPI and hence both cold/hot plug of memory is explicitly
- * disabled for now.
- */
- if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- error_setg(errp, "memory cold/hot plug is not yet supported");
+ if (is_nvdimm) {
+ error_setg(errp, "nvdimm is not yet supported");
+ return;
+ }
+
+ if (!vms->acpi_dev) {
+ error_setg(errp,
+ "memory hotplug is not enabled: missing acpi-ged device");
return;
}
@@ -1898,11 +1933,18 @@ static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
static void virt_memory_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
+ HotplugHandlerClass *hhc;
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
Error *local_err = NULL;
pc_dimm_plug(PC_DIMM(dev), MACHINE(vms), &local_err);
+ if (local_err) {
+ goto out;
+ }
+ hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
+ hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort);
+out:
error_propagate(errp, local_err);
}
@@ -2109,8 +2151,11 @@ DEFINE_VIRT_MACHINE_AS_LATEST(4, 2)
static void virt_machine_4_1_options(MachineClass *mc)
{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
virt_machine_4_2_options(mc);
compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
+ vmc->no_ged = true;
}
DEFINE_VIRT_MACHINE(4, 1)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index a72094204e..577ee49b4b 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -77,6 +77,8 @@ enum {
VIRT_GPIO,
VIRT_SECURE_UART,
VIRT_SECURE_MEM,
+ VIRT_PCDIMM_ACPI,
+ VIRT_ACPI_GED,
VIRT_LOWMEMMAP_LAST,
};
@@ -106,6 +108,7 @@ typedef struct {
bool claim_edge_triggered_timers;
bool smbios_old_sys_ver;
bool no_highmem_ecam;
+ bool no_ged; /* Machines < 4.2 has no support for ACPI GED device */
} VirtMachineClass;
typedef struct {
@@ -133,6 +136,7 @@ typedef struct {
uint32_t iommu_phandle;
int psci_conduit;
hwaddr highest_gpa;
+ DeviceState *acpi_dev;
} VirtMachineState;
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
diff --git a/tests/bios-tables-test-allowed-diff.h b/tests/bios-tables-test-allowed-diff.h
index dfb8523c8b..7b4adbc822 100644
--- a/tests/bios-tables-test-allowed-diff.h
+++ b/tests/bios-tables-test-allowed-diff.h
@@ -1 +1,2 @@
/* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/virt/DSDT",
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [PATCH-for-4.2 v11 05/11] hw/arm/virt: Enable device memory cold/hot plug with ACPI boot
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 05/11] hw/arm/virt: Enable device memory cold/hot plug with ACPI boot Shameer Kolothum
@ 2019-09-25 15:06 ` Igor Mammedov
2019-10-05 21:59 ` [PULL 06/19] " Michael S. Tsirkin
1 sibling, 0 replies; 60+ messages in thread
From: Igor Mammedov @ 2019-09-25 15:06 UTC (permalink / raw)
To: Shameer Kolothum
Cc: peter.maydell, sameo, shannon.zhaosl, ard.biesheuvel, qemu-devel,
xuwei5, linuxarm, eric.auger, qemu-arm, mst, sebastien.boeuf,
lersek
On Wed, 18 Sep 2019 14:06:27 +0100
Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> wrote:
> This initializes the GED device with base memory and irq, configures
> ged memory hotplug event and builds the corresponding aml code. With
> this, both hot and cold plug of device memory is enabled now for Guest
> with ACPI boot. Memory cold plug support with Guest DT boot is not yet
> supported.
>
> As DSDT table gets changed by this, update bios-tables-test-allowed-diff.h
> to avoid "make check" failure.
>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> ---
> v10--> v11
>
> Update based on Igor's comments,
> - Invoke build_memory_hotplug_aml() based on ged-event property.
> ---
> hw/arm/Kconfig | 2 +
> hw/arm/virt-acpi-build.c | 21 ++++++++++
> hw/arm/virt.c | 59 +++++++++++++++++++++++----
> include/hw/arm/virt.h | 4 ++
> tests/bios-tables-test-allowed-diff.h | 1 +
> 5 files changed, 80 insertions(+), 7 deletions(-)
>
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 39d285ad3d..c6e7782580 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -22,6 +22,8 @@ config ARM_VIRT
> select ACPI_PCI
> select MEM_DEVICE
> select DIMM
> + select ACPI_MEMORY_HOTPLUG
> + select ACPI_HW_REDUCED
>
> config CHEETAH
> bool
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 6cdf156cf5..cadeea0f41 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -39,6 +39,8 @@
> #include "hw/acpi/aml-build.h"
> #include "hw/acpi/utils.h"
> #include "hw/acpi/pci.h"
> +#include "hw/acpi/memory_hotplug.h"
> +#include "hw/acpi/generic_event_device.h"
> #include "hw/pci/pcie_host.h"
> #include "hw/pci/pci.h"
> #include "hw/arm/virt.h"
> @@ -708,6 +710,7 @@ static void
> build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> {
> Aml *scope, *dsdt;
> + MachineState *ms = MACHINE(vms);
> const MemMapEntry *memmap = vms->memmap;
> const int *irqmap = vms->irqmap;
>
> @@ -732,6 +735,24 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> vms->highmem, vms->highmem_ecam);
> acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
> (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
> + if (vms->acpi_dev) {
> + build_ged_aml(scope, "\\_SB."GED_DEVICE,
> + HOTPLUG_HANDLER(vms->acpi_dev),
> + irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
> + memmap[VIRT_ACPI_GED].base);
> + }
> +
> + if (vms->acpi_dev) {
> + uint32_t event = object_property_get_uint(OBJECT(vms->acpi_dev),
> + "ged-event", &error_abort);
> +
> + if (event & ACPI_GED_MEM_HOTPLUG_EVT) {
> + build_memory_hotplug_aml(scope, ms->ram_slots, "\\_SB", NULL,
> + AML_SYSTEM_MEMORY,
> + memmap[VIRT_PCDIMM_ACPI].base);
> + }
> + }
> +
> acpi_dsdt_add_power_button(scope);
>
> aml_append(dsdt, scope);
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 1c967e3fee..f926477ba5 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -70,6 +70,7 @@
> #include "target/arm/internals.h"
> #include "hw/mem/pc-dimm.h"
> #include "hw/mem/nvdimm.h"
> +#include "hw/acpi/generic_event_device.h"
>
> #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
> static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
> @@ -140,6 +141,8 @@ static const MemMapEntry base_memmap[] = {
> [VIRT_GPIO] = { 0x09030000, 0x00001000 },
> [VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
> [VIRT_SMMU] = { 0x09050000, 0x00020000 },
> + [VIRT_PCDIMM_ACPI] = { 0x09070000, MEMORY_HOTPLUG_IO_LEN },
> + [VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
> [VIRT_MMIO] = { 0x0a000000, 0x00000200 },
> /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
> [VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
> @@ -175,6 +178,7 @@ static const int a15irqmap[] = {
> [VIRT_PCIE] = 3, /* ... to 6 */
> [VIRT_GPIO] = 7,
> [VIRT_SECURE_UART] = 8,
> + [VIRT_ACPI_GED] = 9,
> [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
> [VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
> [VIRT_SMMU] = 74, /* ...to 74 + NUM_SMMU_IRQS - 1 */
> @@ -527,6 +531,29 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
> }
> }
>
> +static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
> +{
> + DeviceState *dev;
> + MachineState *ms = MACHINE(vms);
> + int irq = vms->irqmap[VIRT_ACPI_GED];
> + uint32_t event = 0;
> +
> + if (ms->ram_slots) {
> + event = ACPI_GED_MEM_HOTPLUG_EVT;
> + }
> +
> + dev = qdev_create(NULL, TYPE_ACPI_GED);
> + qdev_prop_set_uint32(dev, "ged-event", event);
> +
> + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
> + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
> + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
> +
> + qdev_init_nofail(dev);
> +
> + return dev;
> +}
> +
> static void create_its(VirtMachineState *vms, DeviceState *gicdev)
> {
> const char *itsclass = its_class_name();
> @@ -1491,6 +1518,7 @@ static void machvirt_init(MachineState *machine)
> MemoryRegion *ram = g_new(MemoryRegion, 1);
> bool firmware_loaded;
> bool aarch64 = true;
> + bool has_ged = !vmc->no_ged;
> unsigned int smp_cpus = machine->smp.cpus;
> unsigned int max_cpus = machine->smp.max_cpus;
>
> @@ -1705,6 +1733,10 @@ static void machvirt_init(MachineState *machine)
>
> create_gpio(vms, pic);
>
> + if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
> + vms->acpi_dev = create_acpi_ged(vms, pic);
> + }
> +
> /* Create mmio transports, so the user can create virtio backends
> * (which will be automatically plugged in to the transports). If
> * no backend is created the transport will just sit harmlessly idle.
> @@ -1881,14 +1913,17 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
> static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
> Error **errp)
> {
> + VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
> + const bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
>
> - /*
> - * The device memory is not yet exposed to the Guest either through
> - * DT or ACPI and hence both cold/hot plug of memory is explicitly
> - * disabled for now.
> - */
> - if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> - error_setg(errp, "memory cold/hot plug is not yet supported");
> + if (is_nvdimm) {
> + error_setg(errp, "nvdimm is not yet supported");
> + return;
> + }
> +
> + if (!vms->acpi_dev) {
> + error_setg(errp,
> + "memory hotplug is not enabled: missing acpi-ged device");
> return;
> }
>
> @@ -1898,11 +1933,18 @@ static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
> static void virt_memory_plug(HotplugHandler *hotplug_dev,
> DeviceState *dev, Error **errp)
> {
> + HotplugHandlerClass *hhc;
> VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
> Error *local_err = NULL;
>
> pc_dimm_plug(PC_DIMM(dev), MACHINE(vms), &local_err);
> + if (local_err) {
> + goto out;
> + }
>
> + hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
> + hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort);
> +out:
> error_propagate(errp, local_err);
> }
>
> @@ -2109,8 +2151,11 @@ DEFINE_VIRT_MACHINE_AS_LATEST(4, 2)
>
> static void virt_machine_4_1_options(MachineClass *mc)
> {
> + VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
> +
> virt_machine_4_2_options(mc);
> compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
> + vmc->no_ged = true;
> }
> DEFINE_VIRT_MACHINE(4, 1)
>
> diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
> index a72094204e..577ee49b4b 100644
> --- a/include/hw/arm/virt.h
> +++ b/include/hw/arm/virt.h
> @@ -77,6 +77,8 @@ enum {
> VIRT_GPIO,
> VIRT_SECURE_UART,
> VIRT_SECURE_MEM,
> + VIRT_PCDIMM_ACPI,
> + VIRT_ACPI_GED,
> VIRT_LOWMEMMAP_LAST,
> };
>
> @@ -106,6 +108,7 @@ typedef struct {
> bool claim_edge_triggered_timers;
> bool smbios_old_sys_ver;
> bool no_highmem_ecam;
> + bool no_ged; /* Machines < 4.2 has no support for ACPI GED device */
> } VirtMachineClass;
>
> typedef struct {
> @@ -133,6 +136,7 @@ typedef struct {
> uint32_t iommu_phandle;
> int psci_conduit;
> hwaddr highest_gpa;
> + DeviceState *acpi_dev;
> } VirtMachineState;
>
> #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
> diff --git a/tests/bios-tables-test-allowed-diff.h b/tests/bios-tables-test-allowed-diff.h
> index dfb8523c8b..7b4adbc822 100644
> --- a/tests/bios-tables-test-allowed-diff.h
> +++ b/tests/bios-tables-test-allowed-diff.h
> @@ -1 +1,2 @@
> /* List of comma-separated changed AML files to ignore */
> +"tests/data/acpi/virt/DSDT",
^ permalink raw reply [flat|nested] 60+ messages in thread
* [PULL 06/19] hw/arm/virt: Enable device memory cold/hot plug with ACPI boot
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 05/11] hw/arm/virt: Enable device memory cold/hot plug with ACPI boot Shameer Kolothum
2019-09-25 15:06 ` Igor Mammedov
@ 2019-10-05 21:59 ` Michael S. Tsirkin
1 sibling, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:59 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Shannon Zhao, qemu-arm, Shameer Kolothum, Igor Mammedov
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
This initializes the GED device with base memory and irq, configures
ged memory hotplug event and builds the corresponding aml code. With
this, both hot and cold plug of device memory is enabled now for Guest
with ACPI boot. Memory cold plug support with Guest DT boot is not yet
supported.
As DSDT table gets changed by this, update bios-tables-test-allowed-diff.h
to avoid "make check" failure.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Message-Id: <20190918130633.4872-6-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
---
hw/arm/Kconfig | 2 +
hw/arm/virt-acpi-build.c | 21 ++++++++++
hw/arm/virt.c | 59 +++++++++++++++++++++++----
include/hw/arm/virt.h | 4 ++
tests/bios-tables-test-allowed-diff.h | 1 +
5 files changed, 80 insertions(+), 7 deletions(-)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 39d285ad3d..c6e7782580 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -22,6 +22,8 @@ config ARM_VIRT
select ACPI_PCI
select MEM_DEVICE
select DIMM
+ select ACPI_MEMORY_HOTPLUG
+ select ACPI_HW_REDUCED
config CHEETAH
bool
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 6cdf156cf5..cadeea0f41 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -39,6 +39,8 @@
#include "hw/acpi/aml-build.h"
#include "hw/acpi/utils.h"
#include "hw/acpi/pci.h"
+#include "hw/acpi/memory_hotplug.h"
+#include "hw/acpi/generic_event_device.h"
#include "hw/pci/pcie_host.h"
#include "hw/pci/pci.h"
#include "hw/arm/virt.h"
@@ -708,6 +710,7 @@ static void
build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
{
Aml *scope, *dsdt;
+ MachineState *ms = MACHINE(vms);
const MemMapEntry *memmap = vms->memmap;
const int *irqmap = vms->irqmap;
@@ -732,6 +735,24 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
vms->highmem, vms->highmem_ecam);
acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
(irqmap[VIRT_GPIO] + ARM_SPI_BASE));
+ if (vms->acpi_dev) {
+ build_ged_aml(scope, "\\_SB."GED_DEVICE,
+ HOTPLUG_HANDLER(vms->acpi_dev),
+ irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
+ memmap[VIRT_ACPI_GED].base);
+ }
+
+ if (vms->acpi_dev) {
+ uint32_t event = object_property_get_uint(OBJECT(vms->acpi_dev),
+ "ged-event", &error_abort);
+
+ if (event & ACPI_GED_MEM_HOTPLUG_EVT) {
+ build_memory_hotplug_aml(scope, ms->ram_slots, "\\_SB", NULL,
+ AML_SYSTEM_MEMORY,
+ memmap[VIRT_PCDIMM_ACPI].base);
+ }
+ }
+
acpi_dsdt_add_power_button(scope);
aml_append(dsdt, scope);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1c967e3fee..f926477ba5 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -70,6 +70,7 @@
#include "target/arm/internals.h"
#include "hw/mem/pc-dimm.h"
#include "hw/mem/nvdimm.h"
+#include "hw/acpi/generic_event_device.h"
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -140,6 +141,8 @@ static const MemMapEntry base_memmap[] = {
[VIRT_GPIO] = { 0x09030000, 0x00001000 },
[VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
[VIRT_SMMU] = { 0x09050000, 0x00020000 },
+ [VIRT_PCDIMM_ACPI] = { 0x09070000, MEMORY_HOTPLUG_IO_LEN },
+ [VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
@@ -175,6 +178,7 @@ static const int a15irqmap[] = {
[VIRT_PCIE] = 3, /* ... to 6 */
[VIRT_GPIO] = 7,
[VIRT_SECURE_UART] = 8,
+ [VIRT_ACPI_GED] = 9,
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
[VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
[VIRT_SMMU] = 74, /* ...to 74 + NUM_SMMU_IRQS - 1 */
@@ -527,6 +531,29 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
}
}
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
+{
+ DeviceState *dev;
+ MachineState *ms = MACHINE(vms);
+ int irq = vms->irqmap[VIRT_ACPI_GED];
+ uint32_t event = 0;
+
+ if (ms->ram_slots) {
+ event = ACPI_GED_MEM_HOTPLUG_EVT;
+ }
+
+ dev = qdev_create(NULL, TYPE_ACPI_GED);
+ qdev_prop_set_uint32(dev, "ged-event", event);
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
+
+ qdev_init_nofail(dev);
+
+ return dev;
+}
+
static void create_its(VirtMachineState *vms, DeviceState *gicdev)
{
const char *itsclass = its_class_name();
@@ -1491,6 +1518,7 @@ static void machvirt_init(MachineState *machine)
MemoryRegion *ram = g_new(MemoryRegion, 1);
bool firmware_loaded;
bool aarch64 = true;
+ bool has_ged = !vmc->no_ged;
unsigned int smp_cpus = machine->smp.cpus;
unsigned int max_cpus = machine->smp.max_cpus;
@@ -1705,6 +1733,10 @@ static void machvirt_init(MachineState *machine)
create_gpio(vms, pic);
+ if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
+ vms->acpi_dev = create_acpi_ged(vms, pic);
+ }
+
/* Create mmio transports, so the user can create virtio backends
* (which will be automatically plugged in to the transports). If
* no backend is created the transport will just sit harmlessly idle.
@@ -1881,14 +1913,17 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+ const bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
- /*
- * The device memory is not yet exposed to the Guest either through
- * DT or ACPI and hence both cold/hot plug of memory is explicitly
- * disabled for now.
- */
- if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- error_setg(errp, "memory cold/hot plug is not yet supported");
+ if (is_nvdimm) {
+ error_setg(errp, "nvdimm is not yet supported");
+ return;
+ }
+
+ if (!vms->acpi_dev) {
+ error_setg(errp,
+ "memory hotplug is not enabled: missing acpi-ged device");
return;
}
@@ -1898,11 +1933,18 @@ static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
static void virt_memory_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
+ HotplugHandlerClass *hhc;
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
Error *local_err = NULL;
pc_dimm_plug(PC_DIMM(dev), MACHINE(vms), &local_err);
+ if (local_err) {
+ goto out;
+ }
+ hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
+ hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort);
+out:
error_propagate(errp, local_err);
}
@@ -2109,8 +2151,11 @@ DEFINE_VIRT_MACHINE_AS_LATEST(4, 2)
static void virt_machine_4_1_options(MachineClass *mc)
{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
virt_machine_4_2_options(mc);
compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
+ vmc->no_ged = true;
}
DEFINE_VIRT_MACHINE(4, 1)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index a72094204e..577ee49b4b 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -77,6 +77,8 @@ enum {
VIRT_GPIO,
VIRT_SECURE_UART,
VIRT_SECURE_MEM,
+ VIRT_PCDIMM_ACPI,
+ VIRT_ACPI_GED,
VIRT_LOWMEMMAP_LAST,
};
@@ -106,6 +108,7 @@ typedef struct {
bool claim_edge_triggered_timers;
bool smbios_old_sys_ver;
bool no_highmem_ecam;
+ bool no_ged; /* Machines < 4.2 has no support for ACPI GED device */
} VirtMachineClass;
typedef struct {
@@ -133,6 +136,7 @@ typedef struct {
uint32_t iommu_phandle;
int psci_conduit;
hwaddr highest_gpa;
+ DeviceState *acpi_dev;
} VirtMachineState;
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
diff --git a/tests/bios-tables-test-allowed-diff.h b/tests/bios-tables-test-allowed-diff.h
index dfb8523c8b..7b4adbc822 100644
--- a/tests/bios-tables-test-allowed-diff.h
+++ b/tests/bios-tables-test-allowed-diff.h
@@ -1 +1,2 @@
/* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/virt/DSDT",
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 06/11] hw/arm/virt-acpi-build: Add PC-DIMM in SRAT
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (4 preceding siblings ...)
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 05/11] hw/arm/virt: Enable device memory cold/hot plug with ACPI boot Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-10-05 21:59 ` [PULL 07/19] " Michael S. Tsirkin
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 07/11] hw/arm: Factor out powerdown notifier from GPIO Shameer Kolothum
` (9 subsequent siblings)
15 siblings, 1 reply; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
Generate Memory Affinity Structures for PC-DIMM ranges.
Also, Linux and Windows need ACPI SRAT table to make memory hotplug
work properly, however currently QEMU doesn't create SRAT table if
numa options aren't present on CLI. Hence add support(>=4.2) to
create numa node automatically (auto_enable_numa_with_memhp) when
QEMU is started with memory hotplug enabled but without '-numa'
options on CLI.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
---
hw/arm/virt-acpi-build.c | 8 ++++++++
hw/arm/virt.c | 2 ++
2 files changed, 10 insertions(+)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index cadeea0f41..c97661ad68 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -546,6 +546,14 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
}
}
+ if (ms->device_memory) {
+ numamem = acpi_data_push(table_data, sizeof *numamem);
+ build_srat_memory(numamem, ms->device_memory->base,
+ memory_region_size(&ms->device_memory->mr),
+ ms->numa_state->num_nodes - 1,
+ MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
+ }
+
build_header(linker, table_data, (void *)(table_data->data + srat_start),
"SRAT", table_data->len - srat_start, 3, NULL, NULL);
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f926477ba5..d221841c42 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2051,6 +2051,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
hc->plug = virt_machine_device_plug_cb;
hc->unplug_request = virt_machine_device_unplug_request_cb;
mc->numa_mem_supported = true;
+ mc->auto_enable_numa_with_memhp = true;
}
static void virt_instance_init(Object *obj)
@@ -2156,6 +2157,7 @@ static void virt_machine_4_1_options(MachineClass *mc)
virt_machine_4_2_options(mc);
compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
vmc->no_ged = true;
+ mc->auto_enable_numa_with_memhp = false;
}
DEFINE_VIRT_MACHINE(4, 1)
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [PULL 07/19] hw/arm/virt-acpi-build: Add PC-DIMM in SRAT
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 06/11] hw/arm/virt-acpi-build: Add PC-DIMM in SRAT Shameer Kolothum
@ 2019-10-05 21:59 ` Michael S. Tsirkin
0 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:59 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Eric Auger, Shameer Kolothum, Shannon Zhao,
qemu-arm, Igor Mammedov
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Generate Memory Affinity Structures for PC-DIMM ranges.
Also, Linux and Windows need ACPI SRAT table to make memory hotplug
work properly, however currently QEMU doesn't create SRAT table if
numa options aren't present on CLI. Hence add support(>=4.2) to
create numa node automatically (auto_enable_numa_with_memhp) when
QEMU is started with memory hotplug enabled but without '-numa'
options on CLI.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20190918130633.4872-7-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/arm/virt-acpi-build.c | 8 ++++++++
hw/arm/virt.c | 2 ++
2 files changed, 10 insertions(+)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index cadeea0f41..c97661ad68 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -546,6 +546,14 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
}
}
+ if (ms->device_memory) {
+ numamem = acpi_data_push(table_data, sizeof *numamem);
+ build_srat_memory(numamem, ms->device_memory->base,
+ memory_region_size(&ms->device_memory->mr),
+ ms->numa_state->num_nodes - 1,
+ MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
+ }
+
build_header(linker, table_data, (void *)(table_data->data + srat_start),
"SRAT", table_data->len - srat_start, 3, NULL, NULL);
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f926477ba5..d221841c42 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2051,6 +2051,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
hc->plug = virt_machine_device_plug_cb;
hc->unplug_request = virt_machine_device_unplug_request_cb;
mc->numa_mem_supported = true;
+ mc->auto_enable_numa_with_memhp = true;
}
static void virt_instance_init(Object *obj)
@@ -2156,6 +2157,7 @@ static void virt_machine_4_1_options(MachineClass *mc)
virt_machine_4_2_options(mc);
compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
vmc->no_ged = true;
+ mc->auto_enable_numa_with_memhp = false;
}
DEFINE_VIRT_MACHINE(4, 1)
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 07/11] hw/arm: Factor out powerdown notifier from GPIO
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (5 preceding siblings ...)
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 06/11] hw/arm/virt-acpi-build: Add PC-DIMM in SRAT Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-10-05 21:59 ` [PULL 08/19] " Michael S. Tsirkin
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 08/11] hw/arm: Use GED for system_powerdown event Shameer Kolothum
` (8 subsequent siblings)
15 siblings, 1 reply; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
This is in preparation of using GED device for
system_powerdown event. Make the powerdown notifier
registration independent of create_gpio() fn.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
---
hw/arm/virt.c | 12 ++++--------
include/hw/arm/virt.h | 1 +
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d221841c42..dbd8c18f36 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -797,10 +797,6 @@ static void virt_powerdown_req(Notifier *n, void *opaque)
qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
}
-static Notifier virt_system_powerdown_notifier = {
- .notify = virt_powerdown_req
-};
-
static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
{
char *nodename;
@@ -841,10 +837,6 @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
KEY_POWER);
qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
"gpios", phandle, 3, 0);
-
- /* connect powerdown request */
- qemu_register_powerdown_notifier(&virt_system_powerdown_notifier);
-
g_free(nodename);
}
@@ -1737,6 +1729,10 @@ static void machvirt_init(MachineState *machine)
vms->acpi_dev = create_acpi_ged(vms, pic);
}
+ /* connect powerdown request */
+ vms->powerdown_notifier.notify = virt_powerdown_req;
+ qemu_register_powerdown_notifier(&vms->powerdown_notifier);
+
/* Create mmio transports, so the user can create virtio backends
* (which will be automatically plugged in to the transports). If
* no backend is created the transport will just sit harmlessly idle.
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 577ee49b4b..0b41083e9d 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -137,6 +137,7 @@ typedef struct {
int psci_conduit;
hwaddr highest_gpa;
DeviceState *acpi_dev;
+ Notifier powerdown_notifier;
} VirtMachineState;
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [PULL 08/19] hw/arm: Factor out powerdown notifier from GPIO
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 07/11] hw/arm: Factor out powerdown notifier from GPIO Shameer Kolothum
@ 2019-10-05 21:59 ` Michael S. Tsirkin
0 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:59 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Igor Mammedov, qemu-arm, Shameer Kolothum, Eric Auger
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
This is in preparation of using GED device for
system_powerdown event. Make the powerdown notifier
registration independent of create_gpio() fn.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20190918130633.4872-8-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/arm/virt.c | 12 ++++--------
include/hw/arm/virt.h | 1 +
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d221841c42..dbd8c18f36 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -797,10 +797,6 @@ static void virt_powerdown_req(Notifier *n, void *opaque)
qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
}
-static Notifier virt_system_powerdown_notifier = {
- .notify = virt_powerdown_req
-};
-
static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
{
char *nodename;
@@ -841,10 +837,6 @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
KEY_POWER);
qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
"gpios", phandle, 3, 0);
-
- /* connect powerdown request */
- qemu_register_powerdown_notifier(&virt_system_powerdown_notifier);
-
g_free(nodename);
}
@@ -1737,6 +1729,10 @@ static void machvirt_init(MachineState *machine)
vms->acpi_dev = create_acpi_ged(vms, pic);
}
+ /* connect powerdown request */
+ vms->powerdown_notifier.notify = virt_powerdown_req;
+ qemu_register_powerdown_notifier(&vms->powerdown_notifier);
+
/* Create mmio transports, so the user can create virtio backends
* (which will be automatically plugged in to the transports). If
* no backend is created the transport will just sit harmlessly idle.
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 577ee49b4b..0b41083e9d 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -137,6 +137,7 @@ typedef struct {
int psci_conduit;
hwaddr highest_gpa;
DeviceState *acpi_dev;
+ Notifier powerdown_notifier;
} VirtMachineState;
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 08/11] hw/arm: Use GED for system_powerdown event
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (6 preceding siblings ...)
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 07/11] hw/arm: Factor out powerdown notifier from GPIO Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-10-05 21:59 ` [PULL 09/19] " Michael S. Tsirkin
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 09/11] docs/specs: Add ACPI GED documentation Shameer Kolothum
` (7 subsequent siblings)
15 siblings, 1 reply; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
For machines 4.2 or higher with ACPI boot use GED for system_powerdown
event instead of GPIO. Guest boot with DT still uses GPIO.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
---
hw/acpi/generic_event_device.c | 8 ++++++++
hw/arm/virt-acpi-build.c | 6 +++---
hw/arm/virt.c | 18 ++++++++++++------
include/hw/acpi/acpi_dev_interface.h | 1 +
include/hw/acpi/generic_event_device.h | 3 +++
5 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index b94500b08d..9cee90cc70 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -22,6 +22,7 @@
static const uint32_t ged_supported_events[] = {
ACPI_GED_MEM_HOTPLUG_EVT,
+ ACPI_GED_PWR_DOWN_EVT,
};
/*
@@ -104,6 +105,11 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
MEMORY_SLOT_SCAN_METHOD));
break;
+ case ACPI_GED_PWR_DOWN_EVT:
+ aml_append(if_ctx,
+ aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
+ aml_int(0x80)));
+ break;
default:
/*
* Please make sure all the events in ged_supported_events[]
@@ -184,6 +190,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
if (ev & ACPI_MEMORY_HOTPLUG_STATUS) {
sel = ACPI_GED_MEM_HOTPLUG_EVT;
+ } else if (ev & ACPI_POWER_DOWN_STATUS) {
+ sel = ACPI_GED_PWR_DOWN_EVT;
} else {
/* Unknown event. Return without generating interrupt. */
warn_report("GED: Unsupported event %d. No irq injected", ev);
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index c97661ad68..4cd50175e0 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -50,7 +50,6 @@
#include "migration/vmstate.h"
#define ARM_SPI_BASE 32
-#define ACPI_POWER_BUTTON_DEVICE "PWRB"
static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
{
@@ -741,13 +740,14 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
(irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
vms->highmem, vms->highmem_ecam);
- acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
- (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
if (vms->acpi_dev) {
build_ged_aml(scope, "\\_SB."GED_DEVICE,
HOTPLUG_HANDLER(vms->acpi_dev),
irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
memmap[VIRT_ACPI_GED].base);
+ } else {
+ acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
+ (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
}
if (vms->acpi_dev) {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index dbd8c18f36..d4bedc2607 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -536,10 +536,10 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
DeviceState *dev;
MachineState *ms = MACHINE(vms);
int irq = vms->irqmap[VIRT_ACPI_GED];
- uint32_t event = 0;
+ uint32_t event = ACPI_GED_PWR_DOWN_EVT;
if (ms->ram_slots) {
- event = ACPI_GED_MEM_HOTPLUG_EVT;
+ event |= ACPI_GED_MEM_HOTPLUG_EVT;
}
dev = qdev_create(NULL, TYPE_ACPI_GED);
@@ -793,8 +793,14 @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
static DeviceState *gpio_key_dev;
static void virt_powerdown_req(Notifier *n, void *opaque)
{
- /* use gpio Pin 3 for power button event */
- qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
+ VirtMachineState *s = container_of(n, VirtMachineState, powerdown_notifier);
+
+ if (s->acpi_dev) {
+ acpi_send_event(s->acpi_dev, ACPI_POWER_DOWN_STATUS);
+ } else {
+ /* use gpio Pin 3 for power button event */
+ qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
+ }
}
static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
@@ -1723,10 +1729,10 @@ static void machvirt_init(MachineState *machine)
create_pcie(vms, pic);
- create_gpio(vms, pic);
-
if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
vms->acpi_dev = create_acpi_ged(vms, pic);
+ } else {
+ create_gpio(vms, pic);
}
/* connect powerdown request */
diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h
index 0ba90effd2..a2a12af9b9 100644
--- a/include/hw/acpi/acpi_dev_interface.h
+++ b/include/hw/acpi/acpi_dev_interface.h
@@ -13,6 +13,7 @@ typedef enum {
ACPI_MEMORY_HOTPLUG_STATUS = 8,
ACPI_NVDIMM_HOTPLUG_STATUS = 16,
ACPI_VMGENID_CHANGE_STATUS = 32,
+ ACPI_POWER_DOWN_STATUS = 64,
} AcpiEventStatusBits;
#define TYPE_ACPI_DEVICE_IF "acpi-device-interface"
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
index 2049e8d873..d157eac088 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -62,6 +62,8 @@
#include "hw/sysbus.h"
#include "hw/acpi/memory_hotplug.h"
+#define ACPI_POWER_BUTTON_DEVICE "PWRB"
+
#define TYPE_ACPI_GED "acpi-ged"
#define ACPI_GED(obj) \
OBJECT_CHECK(AcpiGedState, (obj), TYPE_ACPI_GED)
@@ -79,6 +81,7 @@
* through GED.
*/
#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
+#define ACPI_GED_PWR_DOWN_EVT 0x2
typedef struct GEDState {
MemoryRegion io;
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [PULL 09/19] hw/arm: Use GED for system_powerdown event
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 08/11] hw/arm: Use GED for system_powerdown event Shameer Kolothum
@ 2019-10-05 21:59 ` Michael S. Tsirkin
0 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:59 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Eric Auger, Shameer Kolothum, Shannon Zhao,
qemu-arm, Igor Mammedov
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
For machines 4.2 or higher with ACPI boot use GED for system_powerdown
event instead of GPIO. Guest boot with DT still uses GPIO.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20190918130633.4872-9-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/acpi/generic_event_device.c | 8 ++++++++
hw/arm/virt-acpi-build.c | 6 +++---
hw/arm/virt.c | 18 ++++++++++++------
include/hw/acpi/acpi_dev_interface.h | 1 +
include/hw/acpi/generic_event_device.h | 3 +++
5 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index b94500b08d..9cee90cc70 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -22,6 +22,7 @@
static const uint32_t ged_supported_events[] = {
ACPI_GED_MEM_HOTPLUG_EVT,
+ ACPI_GED_PWR_DOWN_EVT,
};
/*
@@ -104,6 +105,11 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
MEMORY_SLOT_SCAN_METHOD));
break;
+ case ACPI_GED_PWR_DOWN_EVT:
+ aml_append(if_ctx,
+ aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
+ aml_int(0x80)));
+ break;
default:
/*
* Please make sure all the events in ged_supported_events[]
@@ -184,6 +190,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
if (ev & ACPI_MEMORY_HOTPLUG_STATUS) {
sel = ACPI_GED_MEM_HOTPLUG_EVT;
+ } else if (ev & ACPI_POWER_DOWN_STATUS) {
+ sel = ACPI_GED_PWR_DOWN_EVT;
} else {
/* Unknown event. Return without generating interrupt. */
warn_report("GED: Unsupported event %d. No irq injected", ev);
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index c97661ad68..4cd50175e0 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -50,7 +50,6 @@
#include "migration/vmstate.h"
#define ARM_SPI_BASE 32
-#define ACPI_POWER_BUTTON_DEVICE "PWRB"
static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
{
@@ -741,13 +740,14 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
(irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
vms->highmem, vms->highmem_ecam);
- acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
- (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
if (vms->acpi_dev) {
build_ged_aml(scope, "\\_SB."GED_DEVICE,
HOTPLUG_HANDLER(vms->acpi_dev),
irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
memmap[VIRT_ACPI_GED].base);
+ } else {
+ acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
+ (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
}
if (vms->acpi_dev) {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index dbd8c18f36..d4bedc2607 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -536,10 +536,10 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
DeviceState *dev;
MachineState *ms = MACHINE(vms);
int irq = vms->irqmap[VIRT_ACPI_GED];
- uint32_t event = 0;
+ uint32_t event = ACPI_GED_PWR_DOWN_EVT;
if (ms->ram_slots) {
- event = ACPI_GED_MEM_HOTPLUG_EVT;
+ event |= ACPI_GED_MEM_HOTPLUG_EVT;
}
dev = qdev_create(NULL, TYPE_ACPI_GED);
@@ -793,8 +793,14 @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
static DeviceState *gpio_key_dev;
static void virt_powerdown_req(Notifier *n, void *opaque)
{
- /* use gpio Pin 3 for power button event */
- qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
+ VirtMachineState *s = container_of(n, VirtMachineState, powerdown_notifier);
+
+ if (s->acpi_dev) {
+ acpi_send_event(s->acpi_dev, ACPI_POWER_DOWN_STATUS);
+ } else {
+ /* use gpio Pin 3 for power button event */
+ qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
+ }
}
static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
@@ -1723,10 +1729,10 @@ static void machvirt_init(MachineState *machine)
create_pcie(vms, pic);
- create_gpio(vms, pic);
-
if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
vms->acpi_dev = create_acpi_ged(vms, pic);
+ } else {
+ create_gpio(vms, pic);
}
/* connect powerdown request */
diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h
index 0ba90effd2..a2a12af9b9 100644
--- a/include/hw/acpi/acpi_dev_interface.h
+++ b/include/hw/acpi/acpi_dev_interface.h
@@ -13,6 +13,7 @@ typedef enum {
ACPI_MEMORY_HOTPLUG_STATUS = 8,
ACPI_NVDIMM_HOTPLUG_STATUS = 16,
ACPI_VMGENID_CHANGE_STATUS = 32,
+ ACPI_POWER_DOWN_STATUS = 64,
} AcpiEventStatusBits;
#define TYPE_ACPI_DEVICE_IF "acpi-device-interface"
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
index 2049e8d873..d157eac088 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -62,6 +62,8 @@
#include "hw/sysbus.h"
#include "hw/acpi/memory_hotplug.h"
+#define ACPI_POWER_BUTTON_DEVICE "PWRB"
+
#define TYPE_ACPI_GED "acpi-ged"
#define ACPI_GED(obj) \
OBJECT_CHECK(AcpiGedState, (obj), TYPE_ACPI_GED)
@@ -79,6 +81,7 @@
* through GED.
*/
#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
+#define ACPI_GED_PWR_DOWN_EVT 0x2
typedef struct GEDState {
MemoryRegion io;
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 09/11] docs/specs: Add ACPI GED documentation
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (7 preceding siblings ...)
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 08/11] hw/arm: Use GED for system_powerdown event Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-09-25 15:09 ` Igor Mammedov
2019-10-05 21:59 ` [PULL 10/19] " Michael S. Tsirkin
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 10/11] tests: Update ACPI tables list for upcoming arm/virt tests Shameer Kolothum
` (6 subsequent siblings)
15 siblings, 2 replies; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
Documents basic concepts of ACPI Generic Event device(GED)
and interface between QEMU and the ACPI BIOS.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
---
Addressed Peter's comments,
-changed to rst format.
-typo/grammer corrections.
---
docs/specs/acpi_hw_reduced_hotplug.rst | 70 ++++++++++++++++++++++++++
docs/specs/index.rst | 1 +
2 files changed, 71 insertions(+)
create mode 100644 docs/specs/acpi_hw_reduced_hotplug.rst
diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst b/docs/specs/acpi_hw_reduced_hotplug.rst
new file mode 100644
index 0000000000..911a98255b
--- /dev/null
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -0,0 +1,70 @@
+==================================================
+QEMU and ACPI BIOS Generic Event Device interface
+==================================================
+
+The ACPI *Generic Event Device* (GED) is a HW reduced platform
+specific device introduced in ACPI v6.1 that handles all platform
+events, including the hotplug ones. GED is modelled as a device
+in the namespace with a _HID defined to be ACPI0013. This document
+describes the interface between QEMU and the ACPI BIOS.
+
+GED allows HW reduced platforms to handle interrupts in ACPI ASL
+statements. It follows a very similar approach to the _EVT method
+from GPIO events. All interrupts are listed in _CRS and the handler
+is written in _EVT method. However, the QEMU implementation uses a
+single interrupt for the GED device, relying on an IO memory region
+to communicate the type of device affected by the interrupt. This way,
+we can support up to 32 events with a unique interrupt.
+
+**Here is an example,**
+
+::
+
+ Device (\_SB.GED)
+ {
+ Name (_HID, "ACPI0013")
+ Name (_UID, Zero)
+ Name (_CRS, ResourceTemplate ()
+ {
+ Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
+ {
+ 0x00000029,
+ }
+ })
+ OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)
+ Field (EREG, DWordAcc, NoLock, WriteAsZeros)
+ {
+ ESEL, 32
+ }
+ Method (_EVT, 1, Serialized)
+ {
+ Local0 = ESEL // ESEL = IO memory region which specifies the
+ // device type.
+ If (((Local0 & One) == One))
+ {
+ MethodEvent1()
+ }
+ If ((Local0 & 0x2) == 0x2)
+ {
+ MethodEvent2()
+ }
+ ...
+ }
+ }
+
+GED IO interface (4 byte access)
+--------------------------------
+**read access:**
+
+::
+
+ [0x0-0x3] Event selector bit field (32 bit) set by QEMU.
+
+ bits:
+ 0: Memory hotplug event
+ 1: System power down event
+ 2-31: Reserved
+
+**write_access:**
+
+Nothing is expected to be written into GED IO memory
diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index 40adb97c5e..984ba44029 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -12,3 +12,4 @@ Contents:
ppc-xive
ppc-spapr-xive
+ acpi_hw_reduced_hotplug
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [Qemu-devel] [PATCH-for-4.2 v11 09/11] docs/specs: Add ACPI GED documentation
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 09/11] docs/specs: Add ACPI GED documentation Shameer Kolothum
@ 2019-09-25 15:09 ` Igor Mammedov
2019-10-05 21:59 ` [PULL 10/19] " Michael S. Tsirkin
1 sibling, 0 replies; 60+ messages in thread
From: Igor Mammedov @ 2019-09-25 15:09 UTC (permalink / raw)
To: Shameer Kolothum
Cc: peter.maydell, sameo, ard.biesheuvel, shannon.zhaosl, mst,
qemu-devel, xuwei5, linuxarm, eric.auger, qemu-arm,
sebastien.boeuf, lersek
On Wed, 18 Sep 2019 14:06:31 +0100
Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> wrote:
> Documents basic concepts of ACPI Generic Event device(GED)
> and interface between QEMU and the ACPI BIOS.
>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> ---
> Addressed Peter's comments,
> -changed to rst format.
> -typo/grammer corrections.
> ---
> docs/specs/acpi_hw_reduced_hotplug.rst | 70 ++++++++++++++++++++++++++
> docs/specs/index.rst | 1 +
> 2 files changed, 71 insertions(+)
> create mode 100644 docs/specs/acpi_hw_reduced_hotplug.rst
>
> diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst b/docs/specs/acpi_hw_reduced_hotplug.rst
> new file mode 100644
> index 0000000000..911a98255b
> --- /dev/null
> +++ b/docs/specs/acpi_hw_reduced_hotplug.rst
> @@ -0,0 +1,70 @@
> +==================================================
> +QEMU and ACPI BIOS Generic Event Device interface
> +==================================================
> +
> +The ACPI *Generic Event Device* (GED) is a HW reduced platform
> +specific device introduced in ACPI v6.1 that handles all platform
> +events, including the hotplug ones. GED is modelled as a device
> +in the namespace with a _HID defined to be ACPI0013. This document
> +describes the interface between QEMU and the ACPI BIOS.
> +
> +GED allows HW reduced platforms to handle interrupts in ACPI ASL
> +statements. It follows a very similar approach to the _EVT method
> +from GPIO events. All interrupts are listed in _CRS and the handler
> +is written in _EVT method. However, the QEMU implementation uses a
> +single interrupt for the GED device, relying on an IO memory region
> +to communicate the type of device affected by the interrupt. This way,
> +we can support up to 32 events with a unique interrupt.
> +
> +**Here is an example,**
> +
> +::
> +
> + Device (\_SB.GED)
> + {
> + Name (_HID, "ACPI0013")
> + Name (_UID, Zero)
> + Name (_CRS, ResourceTemplate ()
> + {
> + Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
> + {
> + 0x00000029,
> + }
> + })
> + OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)
> + Field (EREG, DWordAcc, NoLock, WriteAsZeros)
> + {
> + ESEL, 32
> + }
> + Method (_EVT, 1, Serialized)
> + {
> + Local0 = ESEL // ESEL = IO memory region which specifies the
> + // device type.
> + If (((Local0 & One) == One))
> + {
> + MethodEvent1()
> + }
> + If ((Local0 & 0x2) == 0x2)
> + {
> + MethodEvent2()
> + }
> + ...
> + }
> + }
> +
> +GED IO interface (4 byte access)
> +--------------------------------
> +**read access:**
> +
> +::
> +
> + [0x0-0x3] Event selector bit field (32 bit) set by QEMU.
> +
> + bits:
> + 0: Memory hotplug event
> + 1: System power down event
> + 2-31: Reserved
> +
> +**write_access:**
> +
> +Nothing is expected to be written into GED IO memory
> diff --git a/docs/specs/index.rst b/docs/specs/index.rst
> index 40adb97c5e..984ba44029 100644
> --- a/docs/specs/index.rst
> +++ b/docs/specs/index.rst
> @@ -12,3 +12,4 @@ Contents:
>
> ppc-xive
> ppc-spapr-xive
> + acpi_hw_reduced_hotplug
^ permalink raw reply [flat|nested] 60+ messages in thread
* [PULL 10/19] docs/specs: Add ACPI GED documentation
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 09/11] docs/specs: Add ACPI GED documentation Shameer Kolothum
2019-09-25 15:09 ` Igor Mammedov
@ 2019-10-05 21:59 ` Michael S. Tsirkin
1 sibling, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:59 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Shameer Kolothum, Eric Auger,
Cédric Le Goater, Aleksandar Markovic, David Gibson
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Documents basic concepts of ACPI Generic Event device(GED)
and interface between QEMU and the ACPI BIOS.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-Id: <20190918130633.4872-10-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
docs/specs/acpi_hw_reduced_hotplug.rst | 70 ++++++++++++++++++++++++++
docs/specs/index.rst | 1 +
2 files changed, 71 insertions(+)
create mode 100644 docs/specs/acpi_hw_reduced_hotplug.rst
diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst b/docs/specs/acpi_hw_reduced_hotplug.rst
new file mode 100644
index 0000000000..911a98255b
--- /dev/null
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -0,0 +1,70 @@
+==================================================
+QEMU and ACPI BIOS Generic Event Device interface
+==================================================
+
+The ACPI *Generic Event Device* (GED) is a HW reduced platform
+specific device introduced in ACPI v6.1 that handles all platform
+events, including the hotplug ones. GED is modelled as a device
+in the namespace with a _HID defined to be ACPI0013. This document
+describes the interface between QEMU and the ACPI BIOS.
+
+GED allows HW reduced platforms to handle interrupts in ACPI ASL
+statements. It follows a very similar approach to the _EVT method
+from GPIO events. All interrupts are listed in _CRS and the handler
+is written in _EVT method. However, the QEMU implementation uses a
+single interrupt for the GED device, relying on an IO memory region
+to communicate the type of device affected by the interrupt. This way,
+we can support up to 32 events with a unique interrupt.
+
+**Here is an example,**
+
+::
+
+ Device (\_SB.GED)
+ {
+ Name (_HID, "ACPI0013")
+ Name (_UID, Zero)
+ Name (_CRS, ResourceTemplate ()
+ {
+ Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
+ {
+ 0x00000029,
+ }
+ })
+ OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)
+ Field (EREG, DWordAcc, NoLock, WriteAsZeros)
+ {
+ ESEL, 32
+ }
+ Method (_EVT, 1, Serialized)
+ {
+ Local0 = ESEL // ESEL = IO memory region which specifies the
+ // device type.
+ If (((Local0 & One) == One))
+ {
+ MethodEvent1()
+ }
+ If ((Local0 & 0x2) == 0x2)
+ {
+ MethodEvent2()
+ }
+ ...
+ }
+ }
+
+GED IO interface (4 byte access)
+--------------------------------
+**read access:**
+
+::
+
+ [0x0-0x3] Event selector bit field (32 bit) set by QEMU.
+
+ bits:
+ 0: Memory hotplug event
+ 1: System power down event
+ 2-31: Reserved
+
+**write_access:**
+
+Nothing is expected to be written into GED IO memory
diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index 40adb97c5e..984ba44029 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -12,3 +12,4 @@ Contents:
ppc-xive
ppc-spapr-xive
+ acpi_hw_reduced_hotplug
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 10/11] tests: Update ACPI tables list for upcoming arm/virt tests
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (8 preceding siblings ...)
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 09/11] docs/specs: Add ACPI GED documentation Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-09-25 15:11 ` Igor Mammedov
2019-10-05 21:59 ` [PULL 11/19] " Michael S. Tsirkin
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 11/11] tests: Add bios tests to arm/virt Shameer Kolothum
` (5 subsequent siblings)
15 siblings, 2 replies; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
This is in preparation to add numamem and memhp tests to
arm/virt platform. The bios-tables-test-allowed-diff.h
is updated with a list of expected ACPI tables that needs to be
present in tests/data/acpi/virt folder.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
v10 --> v11
As per Michael's suggestion updated bios-tables-test-allowed-diff.h
instead of adding expected files directly.
---
tests/bios-tables-test-allowed-diff.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/tests/bios-tables-test-allowed-diff.h b/tests/bios-tables-test-allowed-diff.h
index 7b4adbc822..3776dd2f3d 100644
--- a/tests/bios-tables-test-allowed-diff.h
+++ b/tests/bios-tables-test-allowed-diff.h
@@ -1,2 +1,17 @@
/* List of comma-separated changed AML files to ignore */
"tests/data/acpi/virt/DSDT",
+"tests/data/acpi/virt/APIC.memhp",
+"tests/data/acpi/virt/APIC.numamem",
+"tests/data/acpi/virt/DSDT.memhp",
+"tests/data/acpi/virt/DSDT.numamem",
+"tests/data/acpi/virt/FACP.memhp",
+"tests/data/acpi/virt/FACP.numamem",
+"tests/data/acpi/virt/GTDT.memhp",
+"tests/data/acpi/virt/GTDT.numamem",
+"tests/data/acpi/virt/MCFG.memhp",
+"tests/data/acpi/virt/MCFG.numamem",
+"tests/data/acpi/virt/SLIT.memhp",
+"tests/data/acpi/virt/SPCR.memhp",
+"tests/data/acpi/virt/SPCR.numamem",
+"tests/data/acpi/virt/SRAT.memhp",
+"tests/data/acpi/virt/SRAT.numamem",
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [PATCH-for-4.2 v11 10/11] tests: Update ACPI tables list for upcoming arm/virt tests
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 10/11] tests: Update ACPI tables list for upcoming arm/virt tests Shameer Kolothum
@ 2019-09-25 15:11 ` Igor Mammedov
2019-10-05 21:59 ` [PULL 11/19] " Michael S. Tsirkin
1 sibling, 0 replies; 60+ messages in thread
From: Igor Mammedov @ 2019-09-25 15:11 UTC (permalink / raw)
To: Shameer Kolothum
Cc: peter.maydell, sameo, shannon.zhaosl, ard.biesheuvel, qemu-devel,
xuwei5, linuxarm, eric.auger, qemu-arm, mst, sebastien.boeuf,
lersek
On Wed, 18 Sep 2019 14:06:32 +0100
Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> wrote:
> This is in preparation to add numamem and memhp tests to
> arm/virt platform. The bios-tables-test-allowed-diff.h
> is updated with a list of expected ACPI tables that needs to be
> present in tests/data/acpi/virt folder.
>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> ---
> v10 --> v11
>
> As per Michael's suggestion updated bios-tables-test-allowed-diff.h
> instead of adding expected files directly.
> ---
> tests/bios-tables-test-allowed-diff.h | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/tests/bios-tables-test-allowed-diff.h b/tests/bios-tables-test-allowed-diff.h
> index 7b4adbc822..3776dd2f3d 100644
> --- a/tests/bios-tables-test-allowed-diff.h
> +++ b/tests/bios-tables-test-allowed-diff.h
> @@ -1,2 +1,17 @@
> /* List of comma-separated changed AML files to ignore */
> "tests/data/acpi/virt/DSDT",
> +"tests/data/acpi/virt/APIC.memhp",
> +"tests/data/acpi/virt/APIC.numamem",
> +"tests/data/acpi/virt/DSDT.memhp",
> +"tests/data/acpi/virt/DSDT.numamem",
> +"tests/data/acpi/virt/FACP.memhp",
> +"tests/data/acpi/virt/FACP.numamem",
> +"tests/data/acpi/virt/GTDT.memhp",
> +"tests/data/acpi/virt/GTDT.numamem",
> +"tests/data/acpi/virt/MCFG.memhp",
> +"tests/data/acpi/virt/MCFG.numamem",
> +"tests/data/acpi/virt/SLIT.memhp",
> +"tests/data/acpi/virt/SPCR.memhp",
> +"tests/data/acpi/virt/SPCR.numamem",
> +"tests/data/acpi/virt/SRAT.memhp",
> +"tests/data/acpi/virt/SRAT.numamem",
^ permalink raw reply [flat|nested] 60+ messages in thread
* [PULL 11/19] tests: Update ACPI tables list for upcoming arm/virt tests
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 10/11] tests: Update ACPI tables list for upcoming arm/virt tests Shameer Kolothum
2019-09-25 15:11 ` Igor Mammedov
@ 2019-10-05 21:59 ` Michael S. Tsirkin
1 sibling, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:59 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Gerd Hoffmann, Shameer Kolothum, Igor Mammedov
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
This is in preparation to add numamem and memhp tests to
arm/virt platform. The bios-tables-test-allowed-diff.h
is updated with a list of expected ACPI tables that needs to be
present in tests/data/acpi/virt folder.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Message-Id: <20190918130633.4872-11-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
---
tests/bios-tables-test-allowed-diff.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/tests/bios-tables-test-allowed-diff.h b/tests/bios-tables-test-allowed-diff.h
index 7b4adbc822..3776dd2f3d 100644
--- a/tests/bios-tables-test-allowed-diff.h
+++ b/tests/bios-tables-test-allowed-diff.h
@@ -1,2 +1,17 @@
/* List of comma-separated changed AML files to ignore */
"tests/data/acpi/virt/DSDT",
+"tests/data/acpi/virt/APIC.memhp",
+"tests/data/acpi/virt/APIC.numamem",
+"tests/data/acpi/virt/DSDT.memhp",
+"tests/data/acpi/virt/DSDT.numamem",
+"tests/data/acpi/virt/FACP.memhp",
+"tests/data/acpi/virt/FACP.numamem",
+"tests/data/acpi/virt/GTDT.memhp",
+"tests/data/acpi/virt/GTDT.numamem",
+"tests/data/acpi/virt/MCFG.memhp",
+"tests/data/acpi/virt/MCFG.numamem",
+"tests/data/acpi/virt/SLIT.memhp",
+"tests/data/acpi/virt/SPCR.memhp",
+"tests/data/acpi/virt/SPCR.numamem",
+"tests/data/acpi/virt/SRAT.memhp",
+"tests/data/acpi/virt/SRAT.numamem",
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* [Qemu-devel] [PATCH-for-4.2 v11 11/11] tests: Add bios tests to arm/virt
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (9 preceding siblings ...)
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 10/11] tests: Update ACPI tables list for upcoming arm/virt tests Shameer Kolothum
@ 2019-09-18 13:06 ` Shameer Kolothum
2019-09-25 15:26 ` Michael S. Tsirkin
2019-10-05 21:59 ` [PULL 14/19] " Michael S. Tsirkin
2019-09-19 4:53 ` [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support no-reply
` (4 subsequent siblings)
15 siblings, 2 replies; 60+ messages in thread
From: Shameer Kolothum @ 2019-09-18 13:06 UTC (permalink / raw)
To: qemu-devel, qemu-arm, eric.auger, imammedo
Cc: peter.maydell, sameo, ard.biesheuvel, mst, linuxarm, xuwei5,
shannon.zhaosl, sebastien.boeuf, lersek
This adds numamem and memhp tests for arm/virt platform.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
---
v10-->v11
Added Igor's R-by.
In order to avoid "make check" failure, the files listed in patch #10
has to be added to tests/data/acpi/virt folder before this patch.
---
tests/bios-tables-test.c | 49 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
index 9b3d8b0d1b..6d9e2e41b0 100644
--- a/tests/bios-tables-test.c
+++ b/tests/bios-tables-test.c
@@ -870,6 +870,53 @@ static void test_acpi_piix4_tcg_dimm_pxm(void)
test_acpi_tcg_dimm_pxm(MACHINE_PC);
}
+static void test_acpi_virt_tcg_memhp(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .accel = "tcg",
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 256ULL * 1024 * 1024,
+ };
+
+ data.variant = ".memhp";
+ test_acpi_one(" -cpu cortex-a57"
+ " -m 256M,slots=3,maxmem=1G"
+ " -object memory-backend-ram,id=ram0,size=128M"
+ " -object memory-backend-ram,id=ram1,size=128M"
+ " -numa node,memdev=ram0 -numa node,memdev=ram1"
+ " -numa dist,src=0,dst=1,val=21",
+ &data);
+
+ free_test_data(&data);
+
+}
+
+static void test_acpi_virt_tcg_numamem(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .accel = "tcg",
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 128ULL * 1024 * 1024,
+ };
+
+ data.variant = ".numamem";
+ test_acpi_one(" -cpu cortex-a57"
+ " -object memory-backend-ram,id=ram0,size=128M"
+ " -numa node,memdev=ram0",
+ &data);
+
+ free_test_data(&data);
+
+}
+
static void test_acpi_virt_tcg(void)
{
test_data data = {
@@ -916,6 +963,8 @@ int main(int argc, char *argv[])
qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm);
} else if (strcmp(arch, "aarch64") == 0) {
qtest_add_func("acpi/virt", test_acpi_virt_tcg);
+ qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem);
+ qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
}
ret = g_test_run();
boot_sector_cleanup(disk);
--
2.17.1
^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [PATCH-for-4.2 v11 11/11] tests: Add bios tests to arm/virt
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 11/11] tests: Add bios tests to arm/virt Shameer Kolothum
@ 2019-09-25 15:26 ` Michael S. Tsirkin
2019-09-25 17:36 ` Igor Mammedov
2019-10-05 21:59 ` [PULL 14/19] " Michael S. Tsirkin
1 sibling, 1 reply; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-09-25 15:26 UTC (permalink / raw)
To: Shameer Kolothum
Cc: peter.maydell, sameo, shannon.zhaosl, ard.biesheuvel, qemu-devel,
xuwei5, linuxarm, eric.auger, qemu-arm, imammedo,
sebastien.boeuf, lersek
On Wed, Sep 18, 2019 at 02:06:33PM +0100, Shameer Kolothum wrote:
> This adds numamem and memhp tests for arm/virt platform.
>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> ---
> v10-->v11
>
> Added Igor's R-by.
>
> In order to avoid "make check" failure, the files listed in patch #10
> has to be added to tests/data/acpi/virt folder before this patch.
So you can just add empty stubs.
> ---
> tests/bios-tables-test.c | 49 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 49 insertions(+)
>
> diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
> index 9b3d8b0d1b..6d9e2e41b0 100644
> --- a/tests/bios-tables-test.c
> +++ b/tests/bios-tables-test.c
> @@ -870,6 +870,53 @@ static void test_acpi_piix4_tcg_dimm_pxm(void)
> test_acpi_tcg_dimm_pxm(MACHINE_PC);
> }
>
> +static void test_acpi_virt_tcg_memhp(void)
> +{
> + test_data data = {
> + .machine = "virt",
> + .accel = "tcg",
> + .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
> + .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
> + .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
> + .ram_start = 0x40000000ULL,
> + .scan_len = 256ULL * 1024 * 1024,
> + };
> +
> + data.variant = ".memhp";
> + test_acpi_one(" -cpu cortex-a57"
> + " -m 256M,slots=3,maxmem=1G"
> + " -object memory-backend-ram,id=ram0,size=128M"
> + " -object memory-backend-ram,id=ram1,size=128M"
> + " -numa node,memdev=ram0 -numa node,memdev=ram1"
> + " -numa dist,src=0,dst=1,val=21",
> + &data);
> +
> + free_test_data(&data);
> +
> +}
> +
> +static void test_acpi_virt_tcg_numamem(void)
> +{
> + test_data data = {
> + .machine = "virt",
> + .accel = "tcg",
> + .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
> + .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
> + .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
> + .ram_start = 0x40000000ULL,
> + .scan_len = 128ULL * 1024 * 1024,
> + };
> +
> + data.variant = ".numamem";
> + test_acpi_one(" -cpu cortex-a57"
> + " -object memory-backend-ram,id=ram0,size=128M"
> + " -numa node,memdev=ram0",
> + &data);
> +
> + free_test_data(&data);
> +
> +}
> +
> static void test_acpi_virt_tcg(void)
> {
> test_data data = {
> @@ -916,6 +963,8 @@ int main(int argc, char *argv[])
> qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm);
> } else if (strcmp(arch, "aarch64") == 0) {
> qtest_add_func("acpi/virt", test_acpi_virt_tcg);
> + qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem);
> + qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
> }
> ret = g_test_run();
> boot_sector_cleanup(disk);
> --
> 2.17.1
>
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH-for-4.2 v11 11/11] tests: Add bios tests to arm/virt
2019-09-25 15:26 ` Michael S. Tsirkin
@ 2019-09-25 17:36 ` Igor Mammedov
0 siblings, 0 replies; 60+ messages in thread
From: Igor Mammedov @ 2019-09-25 17:36 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: peter.maydell, sameo, ard.biesheuvel, qemu-devel,
Shameer Kolothum, linuxarm, shannon.zhaosl, qemu-arm, xuwei5,
eric.auger, sebastien.boeuf, lersek
On Wed, 25 Sep 2019 11:26:04 -0400
"Michael S. Tsirkin" <mst@redhat.com> wrote:
> On Wed, Sep 18, 2019 at 02:06:33PM +0100, Shameer Kolothum wrote:
> > This adds numamem and memhp tests for arm/virt platform.
> >
> > Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> > Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> > v10-->v11
> >
> > Added Igor's R-by.
> >
> > In order to avoid "make check" failure, the files listed in patch #10
> > has to be added to tests/data/acpi/virt folder before this patch.
>
> So you can just add empty stubs.
Wouldn't IASL choke on such files?
>
> > ---
> > tests/bios-tables-test.c | 49 ++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 49 insertions(+)
> >
> > diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
> > index 9b3d8b0d1b..6d9e2e41b0 100644
> > --- a/tests/bios-tables-test.c
> > +++ b/tests/bios-tables-test.c
> > @@ -870,6 +870,53 @@ static void test_acpi_piix4_tcg_dimm_pxm(void)
> > test_acpi_tcg_dimm_pxm(MACHINE_PC);
> > }
> >
> > +static void test_acpi_virt_tcg_memhp(void)
> > +{
> > + test_data data = {
> > + .machine = "virt",
> > + .accel = "tcg",
> > + .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
> > + .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
> > + .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
> > + .ram_start = 0x40000000ULL,
> > + .scan_len = 256ULL * 1024 * 1024,
> > + };
> > +
> > + data.variant = ".memhp";
> > + test_acpi_one(" -cpu cortex-a57"
> > + " -m 256M,slots=3,maxmem=1G"
> > + " -object memory-backend-ram,id=ram0,size=128M"
> > + " -object memory-backend-ram,id=ram1,size=128M"
> > + " -numa node,memdev=ram0 -numa node,memdev=ram1"
> > + " -numa dist,src=0,dst=1,val=21",
> > + &data);
> > +
> > + free_test_data(&data);
> > +
> > +}
> > +
> > +static void test_acpi_virt_tcg_numamem(void)
> > +{
> > + test_data data = {
> > + .machine = "virt",
> > + .accel = "tcg",
> > + .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
> > + .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
> > + .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
> > + .ram_start = 0x40000000ULL,
> > + .scan_len = 128ULL * 1024 * 1024,
> > + };
> > +
> > + data.variant = ".numamem";
> > + test_acpi_one(" -cpu cortex-a57"
> > + " -object memory-backend-ram,id=ram0,size=128M"
> > + " -numa node,memdev=ram0",
> > + &data);
> > +
> > + free_test_data(&data);
> > +
> > +}
> > +
> > static void test_acpi_virt_tcg(void)
> > {
> > test_data data = {
> > @@ -916,6 +963,8 @@ int main(int argc, char *argv[])
> > qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm);
> > } else if (strcmp(arch, "aarch64") == 0) {
> > qtest_add_func("acpi/virt", test_acpi_virt_tcg);
> > + qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem);
> > + qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
> > }
> > ret = g_test_run();
> > boot_sector_cleanup(disk);
> > --
> > 2.17.1
> >
>
^ permalink raw reply [flat|nested] 60+ messages in thread
* [PULL 14/19] tests: Add bios tests to arm/virt
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 11/11] tests: Add bios tests to arm/virt Shameer Kolothum
2019-09-25 15:26 ` Michael S. Tsirkin
@ 2019-10-05 21:59 ` Michael S. Tsirkin
1 sibling, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-10-05 21:59 UTC (permalink / raw)
To: qemu-devel
Cc: Laurent Vivier, Peter Maydell, Thomas Huth, Shameer Kolothum,
Igor Mammedov, Paolo Bonzini
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
This adds numamem and memhp tests for arm/virt platform.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20190918130633.4872-12-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
tests/bios-tables-test.c | 49 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
index 8b066cc8f9..652a78773f 100644
--- a/tests/bios-tables-test.c
+++ b/tests/bios-tables-test.c
@@ -873,6 +873,53 @@ static void test_acpi_piix4_tcg_dimm_pxm(void)
test_acpi_tcg_dimm_pxm(MACHINE_PC);
}
+static void test_acpi_virt_tcg_memhp(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .accel = "tcg",
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 256ULL * 1024 * 1024,
+ };
+
+ data.variant = ".memhp";
+ test_acpi_one(" -cpu cortex-a57"
+ " -m 256M,slots=3,maxmem=1G"
+ " -object memory-backend-ram,id=ram0,size=128M"
+ " -object memory-backend-ram,id=ram1,size=128M"
+ " -numa node,memdev=ram0 -numa node,memdev=ram1"
+ " -numa dist,src=0,dst=1,val=21",
+ &data);
+
+ free_test_data(&data);
+
+}
+
+static void test_acpi_virt_tcg_numamem(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .accel = "tcg",
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 128ULL * 1024 * 1024,
+ };
+
+ data.variant = ".numamem";
+ test_acpi_one(" -cpu cortex-a57"
+ " -object memory-backend-ram,id=ram0,size=128M"
+ " -numa node,memdev=ram0",
+ &data);
+
+ free_test_data(&data);
+
+}
+
static void test_acpi_virt_tcg(void)
{
test_data data = {
@@ -919,6 +966,8 @@ int main(int argc, char *argv[])
qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm);
} else if (strcmp(arch, "aarch64") == 0) {
qtest_add_func("acpi/virt", test_acpi_virt_tcg);
+ qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem);
+ qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
}
ret = g_test_run();
boot_sector_cleanup(disk);
--
MST
^ permalink raw reply related [flat|nested] 60+ messages in thread
* Re: [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (10 preceding siblings ...)
2019-09-18 13:06 ` [Qemu-devel] [PATCH-for-4.2 v11 11/11] tests: Add bios tests to arm/virt Shameer Kolothum
@ 2019-09-19 4:53 ` no-reply
2019-09-19 20:36 ` no-reply
` (3 subsequent siblings)
15 siblings, 0 replies; 60+ messages in thread
From: no-reply @ 2019-09-19 4:53 UTC (permalink / raw)
To: shameerali.kolothum.thodi
Cc: peter.maydell, sameo, ard.biesheuvel, shannon.zhaosl, mst,
qemu-devel, xuwei5, linuxarm, eric.auger, qemu-arm, imammedo,
sebastien.boeuf, lersek
Patchew URL: https://patchew.org/QEMU/20190918130633.4872-1-shameerali.kolothum.thodi@huawei.com/
Hi,
This series failed the docker-quick@centos7 build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.
=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===
libudev no
default devices yes
warning: Python 2 support is deprecated
warning: Python 3 will be required for building future versions of QEMU
cross containers no
NOTE: guest cross-compilers enabled: cc
---
Looking for expected file 'tests/data/acpi/virt/SRAT.numamem'
Looking for expected file 'tests/data/acpi/virt/SRAT'
**
ERROR:/tmp/qemu-test/src/tests/bios-tables-test.c:327:load_expected_aml: assertion failed: (exp_sdt.aml_file)
ERROR - Bail out! ERROR:/tmp/qemu-test/src/tests/bios-tables-test.c:327:load_expected_aml: assertion failed: (exp_sdt.aml_file)
make: *** [check-qtest-aarch64] Error 1
Traceback (most recent call last):
File "./tests/docker/docker.py", line 664, in <module>
The full log is available at
http://patchew.org/logs/20190918130633.4872-1-shameerali.kolothum.thodi@huawei.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (11 preceding siblings ...)
2019-09-19 4:53 ` [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support no-reply
@ 2019-09-19 20:36 ` no-reply
2019-09-20 15:49 ` no-reply
` (2 subsequent siblings)
15 siblings, 0 replies; 60+ messages in thread
From: no-reply @ 2019-09-19 20:36 UTC (permalink / raw)
To: shameerali.kolothum.thodi
Cc: peter.maydell, sameo, ard.biesheuvel, shannon.zhaosl, mst,
qemu-devel, xuwei5, linuxarm, eric.auger, qemu-arm, imammedo,
sebastien.boeuf, lersek
Patchew URL: https://patchew.org/QEMU/20190918130633.4872-1-shameerali.kolothum.thodi@huawei.com/
Hi,
This series failed the docker-quick@centos7 build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.
=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===
libudev no
default devices yes
warning: Python 2 support is deprecated
warning: Python 3 will be required for building future versions of QEMU
cross containers no
NOTE: guest cross-compilers enabled: cc
---
Looking for expected file 'tests/data/acpi/virt/SRAT.numamem'
Looking for expected file 'tests/data/acpi/virt/SRAT'
**
ERROR:/tmp/qemu-test/src/tests/bios-tables-test.c:327:load_expected_aml: assertion failed: (exp_sdt.aml_file)
ERROR - Bail out! ERROR:/tmp/qemu-test/src/tests/bios-tables-test.c:327:load_expected_aml: assertion failed: (exp_sdt.aml_file)
make: *** [check-qtest-aarch64] Error 1
make: *** Waiting for unfinished jobs....
Could not access KVM kernel module: No such file or directory
The full log is available at
http://patchew.org/logs/20190918130633.4872-1-shameerali.kolothum.thodi@huawei.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (12 preceding siblings ...)
2019-09-19 20:36 ` no-reply
@ 2019-09-20 15:49 ` no-reply
2019-09-25 15:28 ` Michael S. Tsirkin
2019-09-25 15:30 ` Michael S. Tsirkin
15 siblings, 0 replies; 60+ messages in thread
From: no-reply @ 2019-09-20 15:49 UTC (permalink / raw)
To: shameerali.kolothum.thodi
Cc: peter.maydell, sameo, ard.biesheuvel, shannon.zhaosl, mst,
qemu-devel, xuwei5, linuxarm, eric.auger, qemu-arm, imammedo,
sebastien.boeuf, lersek
Patchew URL: https://patchew.org/QEMU/20190918130633.4872-1-shameerali.kolothum.thodi@huawei.com/
Hi,
This series failed the docker-quick@centos7 build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.
=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===
libudev no
default devices yes
warning: Python 2 support is deprecated
warning: Python 3 will be required for building future versions of QEMU
cross containers no
NOTE: guest cross-compilers enabled: cc
---
Looking for expected file 'tests/data/acpi/virt/SRAT.numamem'
Looking for expected file 'tests/data/acpi/virt/SRAT'
**
ERROR:/tmp/qemu-test/src/tests/bios-tables-test.c:327:load_expected_aml: assertion failed: (exp_sdt.aml_file)
ERROR - Bail out! ERROR:/tmp/qemu-test/src/tests/bios-tables-test.c:327:load_expected_aml: assertion failed: (exp_sdt.aml_file)
make: *** [check-qtest-aarch64] Error 1
make: *** Waiting for unfinished jobs....
TEST check-qtest-x86_64: tests/vmgenid-test
The full log is available at
http://patchew.org/logs/20190918130633.4872-1-shameerali.kolothum.thodi@huawei.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (13 preceding siblings ...)
2019-09-20 15:49 ` no-reply
@ 2019-09-25 15:28 ` Michael S. Tsirkin
2019-09-25 15:37 ` Igor Mammedov
2019-09-25 15:30 ` Michael S. Tsirkin
15 siblings, 1 reply; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-09-25 15:28 UTC (permalink / raw)
To: Shameer Kolothum
Cc: peter.maydell, sameo, shannon.zhaosl, ard.biesheuvel, qemu-devel,
xuwei5, linuxarm, eric.auger, qemu-arm, imammedo,
sebastien.boeuf, lersek
On Wed, Sep 18, 2019 at 02:06:22PM +0100, Shameer Kolothum wrote:
> This series is an attempt to provide device memory hotplug support
> on ARM virt platform. This is based on Eric's recent works here[1]
> and carries some of the pc-dimm related patches dropped from his
> series.
>
> The kernel support for arm64 memory hot add was added recently by
> Robin and hence the guest kernel should be => 5.0-rc1.
>
> NVDIM support is not included currently as we still have an unresolved
> issue while hot adding NVDIMM[2]. However NVDIMM cold plug patches
> can be included, but not done for now, for keeping it simple.
>
> This makes use of GED device to sent hotplug ACPI events to the
> Guest. GED code is based on Nemu. Thanks to the efforts of Samuel and
> Sebastien to add the hardware-reduced support to Nemu using GED
> device[3]. (Please shout if I got the author/signed-off wrong for
> those patches or missed any names).
>
> This is sanity tested on a HiSilicon ARM64 platform and appreciate
> any further testing.
>
> Note:
> Attempted adding dimm_pxm test case to bios-tables-test for arm/virt.
> But noticed the issue decribed here[5]. This is under investigation
> now.
>
> Thanks,
> Shameer
Which tree is this going through? Mine or ARM?
> [1] https://patchwork.kernel.org/cover/10837565/
> [2] https://patchwork.kernel.org/cover/10783589/
> [3] https://github.com/intel/nemu/blob/topic/virt-x86/hw/acpi/ged.c
> [4] http://lists.infradead.org/pipermail/linux-arm-kernel/2019-May/651763.html
> [5] https://www.mail-archive.com/qemu-devel@nongnu.org/msg632651.html
>
> v10 --> v11
> -Changed patch #10 to update bios-tables-test-allowed-diff.h with a
> list of expected ACPI tables.
> -GED document changed to rst format (patch #9)
> -Addressed comments from Igor (patch #3 & #5)
> -Igor's R-by to #7, #8 & #11.
>
> v9 --> v10
> -Fix for "make check" failure on x86_64(Patch #1).
> -Minor updates based on Eric's comments.
> -Dropped patch "hw/arm/virt: Add 4.2 machine type" as this is already
> in master now.
> -Added R-by tags by Eric.
>
> v8 --> v9
> -Changes related to GED being a TYPE_SYS_BUS_DEVICE now.
> -Re-arranged patches 8 and 9.
> -Added GED ABI documentation(patch #10).
> -Added numamem and memhp tests to arm/virt(#11 and #12)
> -Dropped few R-by tags as code has changed a bit.
> -Please see Individual patch history for details.
>
> v7 --> v8
> -Addressed comments from Igor.Please see individual patches.
> -Updated bios-tables-test-allowed-diff.h to avoid "make check"
> failure (patch #6) and dropped patch #10
> -Added Igor's R-by to patches 4 & 5.
> -Dropped Erics's R-by from patch #9 for now.
>
> v6 --> v7
> - Added 4.2 machine support and restricted GED creation for < 4.2
> This is to address the migration test fail reported by Eric.
> - Included "tests: Update DSDT ACPI table.." patch(#10) from Eric
> to fix the "make check" bios-tables-test failure.
>
> v5 --> v6
>
> -Addressed comments from Eric.
> -Added R-by from Eric and Igor.
>
> v4 --> v5
> -Removed gsi/ged-irq routing in virt.
> -Added Migration support.
> -Dropped support for DT coldplug case based on the discussions
> here[4]
> -Added system_powerdown support through GED.
>
> v3 --> v4
> Addressed comments from Igor and Eric,
> -Renamed "virt-acpi" to "acpi-ged".
> -Changed ged device parent to TYPE_DEVICE.
> -Introduced DT memory node property "hotpluggable" to resolve device
> memory being treated as early boot memory issue(patch #7).
> -Combined patches #3 and #9 from v3 into #3.
>
> v2 --> v3
>
> Addressed comments from Igor and Eric,
> -Made virt acpi device platform independent and moved
> to hw/acpi/generic_event_device.c
> -Moved ged specific code into hw/acpi/generic_event_device.c
> -Introduced an opt-in feature "fdt" to resolve device-memory being
> treated as early boot memory.
> -Dropped patch #1 from v2.
>
> RFC --> v2
>
> -Use GED device instead of GPIO for ACPI hotplug events.
> -Removed NVDIMM support for now.
> -Includes dropped patches from Eric's v9 series.
>
> Eric Auger (1):
> hw/arm/virt: Add memory hotplug framework
>
> Samuel Ortiz (2):
> hw/acpi: Do not create memory hotplug method when handler is not
> defined
> hw/acpi: Add ACPI Generic Event Device Support
>
> Shameer Kolothum (8):
> hw/acpi: Make ACPI IO address space configurable
> hw/arm/virt: Enable device memory cold/hot plug with ACPI boot
> hw/arm/virt-acpi-build: Add PC-DIMM in SRAT
> hw/arm: Factor out powerdown notifier from GPIO
> hw/arm: Use GED for system_powerdown event
> docs/specs: Add ACPI GED documentation
> tests: Update ACPI tables list for upcoming arm/virt tests
> tests: Add bios tests to arm/virt
>
> docs/specs/acpi_hw_reduced_hotplug.rst | 70 ++++++
> docs/specs/index.rst | 1 +
> hw/acpi/Kconfig | 4 +
> hw/acpi/Makefile.objs | 1 +
> hw/acpi/generic_event_device.c | 311 +++++++++++++++++++++++++
> hw/acpi/memory_hotplug.c | 43 ++--
> hw/arm/Kconfig | 4 +
> hw/arm/virt-acpi-build.c | 35 ++-
> hw/arm/virt.c | 124 +++++++++-
> hw/i386/acpi-build.c | 7 +-
> hw/i386/pc.c | 3 +
> include/hw/acpi/acpi_dev_interface.h | 1 +
> include/hw/acpi/generic_event_device.h | 103 ++++++++
> include/hw/acpi/memory_hotplug.h | 9 +-
> include/hw/arm/virt.h | 5 +
> include/hw/i386/pc.h | 3 +
> tests/bios-tables-test-allowed-diff.h | 16 ++
> tests/bios-tables-test.c | 49 ++++
> 18 files changed, 748 insertions(+), 41 deletions(-)
> create mode 100644 docs/specs/acpi_hw_reduced_hotplug.rst
> create mode 100644 hw/acpi/generic_event_device.c
> create mode 100644 include/hw/acpi/generic_event_device.h
>
> --
> 2.17.1
>
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support
2019-09-25 15:28 ` Michael S. Tsirkin
@ 2019-09-25 15:37 ` Igor Mammedov
2019-09-25 16:20 ` Michael S. Tsirkin
0 siblings, 1 reply; 60+ messages in thread
From: Igor Mammedov @ 2019-09-25 15:37 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: peter.maydell, sameo, shannon.zhaosl, ard.biesheuvel, qemu-devel,
Shameer Kolothum, linuxarm, eric.auger, qemu-arm, xuwei5,
sebastien.boeuf, lersek
On Wed, 25 Sep 2019 11:28:42 -0400
"Michael S. Tsirkin" <mst@redhat.com> wrote:
> On Wed, Sep 18, 2019 at 02:06:22PM +0100, Shameer Kolothum wrote:
> > This series is an attempt to provide device memory hotplug support
> > on ARM virt platform. This is based on Eric's recent works here[1]
> > and carries some of the pc-dimm related patches dropped from his
> > series.
> >
> > The kernel support for arm64 memory hot add was added recently by
> > Robin and hence the guest kernel should be => 5.0-rc1.
> >
> > NVDIM support is not included currently as we still have an unresolved
> > issue while hot adding NVDIMM[2]. However NVDIMM cold plug patches
> > can be included, but not done for now, for keeping it simple.
> >
> > This makes use of GED device to sent hotplug ACPI events to the
> > Guest. GED code is based on Nemu. Thanks to the efforts of Samuel and
> > Sebastien to add the hardware-reduced support to Nemu using GED
> > device[3]. (Please shout if I got the author/signed-off wrong for
> > those patches or missed any names).
> >
> > This is sanity tested on a HiSilicon ARM64 platform and appreciate
> > any further testing.
> >
> > Note:
> > Attempted adding dimm_pxm test case to bios-tables-test for arm/virt.
> > But noticed the issue decribed here[5]. This is under investigation
> > now.
> >
> > Thanks,
> > Shameer
>
>
> Which tree is this going through? Mine or ARM?
I'd assume your tree???
(You are the wizard who knows how to handle bios-tables-test-allowed-diff.h on merge)
>
>
> > [1] https://patchwork.kernel.org/cover/10837565/
> > [2] https://patchwork.kernel.org/cover/10783589/
> > [3] https://github.com/intel/nemu/blob/topic/virt-x86/hw/acpi/ged.c
> > [4] http://lists.infradead.org/pipermail/linux-arm-kernel/2019-May/651763.html
> > [5] https://www.mail-archive.com/qemu-devel@nongnu.org/msg632651.html
> >
> > v10 --> v11
> > -Changed patch #10 to update bios-tables-test-allowed-diff.h with a
> > list of expected ACPI tables.
> > -GED document changed to rst format (patch #9)
> > -Addressed comments from Igor (patch #3 & #5)
> > -Igor's R-by to #7, #8 & #11.
> >
> > v9 --> v10
> > -Fix for "make check" failure on x86_64(Patch #1).
> > -Minor updates based on Eric's comments.
> > -Dropped patch "hw/arm/virt: Add 4.2 machine type" as this is already
> > in master now.
> > -Added R-by tags by Eric.
> >
> > v8 --> v9
> > -Changes related to GED being a TYPE_SYS_BUS_DEVICE now.
> > -Re-arranged patches 8 and 9.
> > -Added GED ABI documentation(patch #10).
> > -Added numamem and memhp tests to arm/virt(#11 and #12)
> > -Dropped few R-by tags as code has changed a bit.
> > -Please see Individual patch history for details.
> >
> > v7 --> v8
> > -Addressed comments from Igor.Please see individual patches.
> > -Updated bios-tables-test-allowed-diff.h to avoid "make check"
> > failure (patch #6) and dropped patch #10
> > -Added Igor's R-by to patches 4 & 5.
> > -Dropped Erics's R-by from patch #9 for now.
> >
> > v6 --> v7
> > - Added 4.2 machine support and restricted GED creation for < 4.2
> > This is to address the migration test fail reported by Eric.
> > - Included "tests: Update DSDT ACPI table.." patch(#10) from Eric
> > to fix the "make check" bios-tables-test failure.
> >
> > v5 --> v6
> >
> > -Addressed comments from Eric.
> > -Added R-by from Eric and Igor.
> >
> > v4 --> v5
> > -Removed gsi/ged-irq routing in virt.
> > -Added Migration support.
> > -Dropped support for DT coldplug case based on the discussions
> > here[4]
> > -Added system_powerdown support through GED.
> >
> > v3 --> v4
> > Addressed comments from Igor and Eric,
> > -Renamed "virt-acpi" to "acpi-ged".
> > -Changed ged device parent to TYPE_DEVICE.
> > -Introduced DT memory node property "hotpluggable" to resolve device
> > memory being treated as early boot memory issue(patch #7).
> > -Combined patches #3 and #9 from v3 into #3.
> >
> > v2 --> v3
> >
> > Addressed comments from Igor and Eric,
> > -Made virt acpi device platform independent and moved
> > to hw/acpi/generic_event_device.c
> > -Moved ged specific code into hw/acpi/generic_event_device.c
> > -Introduced an opt-in feature "fdt" to resolve device-memory being
> > treated as early boot memory.
> > -Dropped patch #1 from v2.
> >
> > RFC --> v2
> >
> > -Use GED device instead of GPIO for ACPI hotplug events.
> > -Removed NVDIMM support for now.
> > -Includes dropped patches from Eric's v9 series.
> >
> > Eric Auger (1):
> > hw/arm/virt: Add memory hotplug framework
> >
> > Samuel Ortiz (2):
> > hw/acpi: Do not create memory hotplug method when handler is not
> > defined
> > hw/acpi: Add ACPI Generic Event Device Support
> >
> > Shameer Kolothum (8):
> > hw/acpi: Make ACPI IO address space configurable
> > hw/arm/virt: Enable device memory cold/hot plug with ACPI boot
> > hw/arm/virt-acpi-build: Add PC-DIMM in SRAT
> > hw/arm: Factor out powerdown notifier from GPIO
> > hw/arm: Use GED for system_powerdown event
> > docs/specs: Add ACPI GED documentation
> > tests: Update ACPI tables list for upcoming arm/virt tests
> > tests: Add bios tests to arm/virt
> >
> > docs/specs/acpi_hw_reduced_hotplug.rst | 70 ++++++
> > docs/specs/index.rst | 1 +
> > hw/acpi/Kconfig | 4 +
> > hw/acpi/Makefile.objs | 1 +
> > hw/acpi/generic_event_device.c | 311 +++++++++++++++++++++++++
> > hw/acpi/memory_hotplug.c | 43 ++--
> > hw/arm/Kconfig | 4 +
> > hw/arm/virt-acpi-build.c | 35 ++-
> > hw/arm/virt.c | 124 +++++++++-
> > hw/i386/acpi-build.c | 7 +-
> > hw/i386/pc.c | 3 +
> > include/hw/acpi/acpi_dev_interface.h | 1 +
> > include/hw/acpi/generic_event_device.h | 103 ++++++++
> > include/hw/acpi/memory_hotplug.h | 9 +-
> > include/hw/arm/virt.h | 5 +
> > include/hw/i386/pc.h | 3 +
> > tests/bios-tables-test-allowed-diff.h | 16 ++
> > tests/bios-tables-test.c | 49 ++++
> > 18 files changed, 748 insertions(+), 41 deletions(-)
> > create mode 100644 docs/specs/acpi_hw_reduced_hotplug.rst
> > create mode 100644 hw/acpi/generic_event_device.c
> > create mode 100644 include/hw/acpi/generic_event_device.h
> >
> > --
> > 2.17.1
> >
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support
2019-09-25 15:37 ` Igor Mammedov
@ 2019-09-25 16:20 ` Michael S. Tsirkin
2019-09-27 10:37 ` Peter Maydell
0 siblings, 1 reply; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-09-25 16:20 UTC (permalink / raw)
To: Igor Mammedov
Cc: peter.maydell, sameo, shannon.zhaosl, ard.biesheuvel, qemu-devel,
Shameer Kolothum, linuxarm, eric.auger, qemu-arm, xuwei5,
sebastien.boeuf, lersek
On Wed, Sep 25, 2019 at 05:37:53PM +0200, Igor Mammedov wrote:
> On Wed, 25 Sep 2019 11:28:42 -0400
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>
> > On Wed, Sep 18, 2019 at 02:06:22PM +0100, Shameer Kolothum wrote:
> > > This series is an attempt to provide device memory hotplug support
> > > on ARM virt platform. This is based on Eric's recent works here[1]
> > > and carries some of the pc-dimm related patches dropped from his
> > > series.
> > >
> > > The kernel support for arm64 memory hot add was added recently by
> > > Robin and hence the guest kernel should be => 5.0-rc1.
> > >
> > > NVDIM support is not included currently as we still have an unresolved
> > > issue while hot adding NVDIMM[2]. However NVDIMM cold plug patches
> > > can be included, but not done for now, for keeping it simple.
> > >
> > > This makes use of GED device to sent hotplug ACPI events to the
> > > Guest. GED code is based on Nemu. Thanks to the efforts of Samuel and
> > > Sebastien to add the hardware-reduced support to Nemu using GED
> > > device[3]. (Please shout if I got the author/signed-off wrong for
> > > those patches or missed any names).
> > >
> > > This is sanity tested on a HiSilicon ARM64 platform and appreciate
> > > any further testing.
> > >
> > > Note:
> > > Attempted adding dimm_pxm test case to bios-tables-test for arm/virt.
> > > But noticed the issue decribed here[5]. This is under investigation
> > > now.
> > >
> > > Thanks,
> > > Shameer
> >
> >
> > Which tree is this going through? Mine or ARM?
>
> I'd assume your tree???
> (You are the wizard who knows how to handle bios-tables-test-allowed-diff.h on merge)
Sure. Peter if you agree, could you send your ack for that please?
> >
> >
> > > [1] https://patchwork.kernel.org/cover/10837565/
> > > [2] https://patchwork.kernel.org/cover/10783589/
> > > [3] https://github.com/intel/nemu/blob/topic/virt-x86/hw/acpi/ged.c
> > > [4] http://lists.infradead.org/pipermail/linux-arm-kernel/2019-May/651763.html
> > > [5] https://www.mail-archive.com/qemu-devel@nongnu.org/msg632651.html
> > >
> > > v10 --> v11
> > > -Changed patch #10 to update bios-tables-test-allowed-diff.h with a
> > > list of expected ACPI tables.
> > > -GED document changed to rst format (patch #9)
> > > -Addressed comments from Igor (patch #3 & #5)
> > > -Igor's R-by to #7, #8 & #11.
> > >
> > > v9 --> v10
> > > -Fix for "make check" failure on x86_64(Patch #1).
> > > -Minor updates based on Eric's comments.
> > > -Dropped patch "hw/arm/virt: Add 4.2 machine type" as this is already
> > > in master now.
> > > -Added R-by tags by Eric.
> > >
> > > v8 --> v9
> > > -Changes related to GED being a TYPE_SYS_BUS_DEVICE now.
> > > -Re-arranged patches 8 and 9.
> > > -Added GED ABI documentation(patch #10).
> > > -Added numamem and memhp tests to arm/virt(#11 and #12)
> > > -Dropped few R-by tags as code has changed a bit.
> > > -Please see Individual patch history for details.
> > >
> > > v7 --> v8
> > > -Addressed comments from Igor.Please see individual patches.
> > > -Updated bios-tables-test-allowed-diff.h to avoid "make check"
> > > failure (patch #6) and dropped patch #10
> > > -Added Igor's R-by to patches 4 & 5.
> > > -Dropped Erics's R-by from patch #9 for now.
> > >
> > > v6 --> v7
> > > - Added 4.2 machine support and restricted GED creation for < 4.2
> > > This is to address the migration test fail reported by Eric.
> > > - Included "tests: Update DSDT ACPI table.." patch(#10) from Eric
> > > to fix the "make check" bios-tables-test failure.
> > >
> > > v5 --> v6
> > >
> > > -Addressed comments from Eric.
> > > -Added R-by from Eric and Igor.
> > >
> > > v4 --> v5
> > > -Removed gsi/ged-irq routing in virt.
> > > -Added Migration support.
> > > -Dropped support for DT coldplug case based on the discussions
> > > here[4]
> > > -Added system_powerdown support through GED.
> > >
> > > v3 --> v4
> > > Addressed comments from Igor and Eric,
> > > -Renamed "virt-acpi" to "acpi-ged".
> > > -Changed ged device parent to TYPE_DEVICE.
> > > -Introduced DT memory node property "hotpluggable" to resolve device
> > > memory being treated as early boot memory issue(patch #7).
> > > -Combined patches #3 and #9 from v3 into #3.
> > >
> > > v2 --> v3
> > >
> > > Addressed comments from Igor and Eric,
> > > -Made virt acpi device platform independent and moved
> > > to hw/acpi/generic_event_device.c
> > > -Moved ged specific code into hw/acpi/generic_event_device.c
> > > -Introduced an opt-in feature "fdt" to resolve device-memory being
> > > treated as early boot memory.
> > > -Dropped patch #1 from v2.
> > >
> > > RFC --> v2
> > >
> > > -Use GED device instead of GPIO for ACPI hotplug events.
> > > -Removed NVDIMM support for now.
> > > -Includes dropped patches from Eric's v9 series.
> > >
> > > Eric Auger (1):
> > > hw/arm/virt: Add memory hotplug framework
> > >
> > > Samuel Ortiz (2):
> > > hw/acpi: Do not create memory hotplug method when handler is not
> > > defined
> > > hw/acpi: Add ACPI Generic Event Device Support
> > >
> > > Shameer Kolothum (8):
> > > hw/acpi: Make ACPI IO address space configurable
> > > hw/arm/virt: Enable device memory cold/hot plug with ACPI boot
> > > hw/arm/virt-acpi-build: Add PC-DIMM in SRAT
> > > hw/arm: Factor out powerdown notifier from GPIO
> > > hw/arm: Use GED for system_powerdown event
> > > docs/specs: Add ACPI GED documentation
> > > tests: Update ACPI tables list for upcoming arm/virt tests
> > > tests: Add bios tests to arm/virt
> > >
> > > docs/specs/acpi_hw_reduced_hotplug.rst | 70 ++++++
> > > docs/specs/index.rst | 1 +
> > > hw/acpi/Kconfig | 4 +
> > > hw/acpi/Makefile.objs | 1 +
> > > hw/acpi/generic_event_device.c | 311 +++++++++++++++++++++++++
> > > hw/acpi/memory_hotplug.c | 43 ++--
> > > hw/arm/Kconfig | 4 +
> > > hw/arm/virt-acpi-build.c | 35 ++-
> > > hw/arm/virt.c | 124 +++++++++-
> > > hw/i386/acpi-build.c | 7 +-
> > > hw/i386/pc.c | 3 +
> > > include/hw/acpi/acpi_dev_interface.h | 1 +
> > > include/hw/acpi/generic_event_device.h | 103 ++++++++
> > > include/hw/acpi/memory_hotplug.h | 9 +-
> > > include/hw/arm/virt.h | 5 +
> > > include/hw/i386/pc.h | 3 +
> > > tests/bios-tables-test-allowed-diff.h | 16 ++
> > > tests/bios-tables-test.c | 49 ++++
> > > 18 files changed, 748 insertions(+), 41 deletions(-)
> > > create mode 100644 docs/specs/acpi_hw_reduced_hotplug.rst
> > > create mode 100644 hw/acpi/generic_event_device.c
> > > create mode 100644 include/hw/acpi/generic_event_device.h
> > >
> > > --
> > > 2.17.1
> > >
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support
2019-09-25 16:20 ` Michael S. Tsirkin
@ 2019-09-27 10:37 ` Peter Maydell
0 siblings, 0 replies; 60+ messages in thread
From: Peter Maydell @ 2019-09-27 10:37 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Samuel Ortiz, Eric Auger, Ard Biesheuvel, QEMU Developers,
Shameer Kolothum, Linuxarm, Shannon Zhao, qemu-arm, Xu Wei,
Igor Mammedov, sebastien.boeuf, Laszlo Ersek
On Wed, 25 Sep 2019 at 17:20, Michael S. Tsirkin <mst@redhat.com> wrote:
>
> On Wed, Sep 25, 2019 at 05:37:53PM +0200, Igor Mammedov wrote:
> > On Wed, 25 Sep 2019 11:28:42 -0400
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> >
> > > On Wed, Sep 18, 2019 at 02:06:22PM +0100, Shameer Kolothum wrote:
> > > > This series is an attempt to provide device memory hotplug support
> > > > on ARM virt platform. This is based on Eric's recent works here[1]
> > > > and carries some of the pc-dimm related patches dropped from his
> > > > series.
> > > >
> > > > The kernel support for arm64 memory hot add was added recently by
> > > > Robin and hence the guest kernel should be => 5.0-rc1.
> > > >
> > > > NVDIM support is not included currently as we still have an unresolved
> > > > issue while hot adding NVDIMM[2]. However NVDIMM cold plug patches
> > > > can be included, but not done for now, for keeping it simple.
> > > >
> > > > This makes use of GED device to sent hotplug ACPI events to the
> > > > Guest. GED code is based on Nemu. Thanks to the efforts of Samuel and
> > > > Sebastien to add the hardware-reduced support to Nemu using GED
> > > > device[3]. (Please shout if I got the author/signed-off wrong for
> > > > those patches or missed any names).
> > > >
> > > > This is sanity tested on a HiSilicon ARM64 platform and appreciate
> > > > any further testing.
> > > >
> > > > Note:
> > > > Attempted adding dimm_pxm test case to bios-tables-test for arm/virt.
> > > > But noticed the issue decribed here[5]. This is under investigation
> > > > now.
> > > >
> > > > Thanks,
> > > > Shameer
> > >
> > >
> > > Which tree is this going through? Mine or ARM?
> >
> > I'd assume your tree???
> > (You are the wizard who knows how to handle bios-tables-test-allowed-diff.h on merge)
>
> Sure. Peter if you agree, could you send your ack for that please?
Yeah, that's as good a way to do it as any.
Acked-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 60+ messages in thread
* Re: [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support
2019-09-18 13:06 [Qemu-devel] [PATCH-for-4.2 v11 00/11] ARM virt: ACPI memory hotplug support Shameer Kolothum
` (14 preceding siblings ...)
2019-09-25 15:28 ` Michael S. Tsirkin
@ 2019-09-25 15:30 ` Michael S. Tsirkin
15 siblings, 0 replies; 60+ messages in thread
From: Michael S. Tsirkin @ 2019-09-25 15:30 UTC (permalink / raw)
To: Shameer Kolothum
Cc: peter.maydell, sameo, shannon.zhaosl, ard.biesheuvel, qemu-devel,
xuwei5, linuxarm, eric.auger, qemu-arm, imammedo,
sebastien.boeuf, lersek
On Wed, Sep 18, 2019 at 02:06:22PM +0100, Shameer Kolothum wrote:
> This series is an attempt to provide device memory hotplug support
> on ARM virt platform. This is based on Eric's recent works here[1]
> and carries some of the pc-dimm related patches dropped from his
> series.
>
> The kernel support for arm64 memory hot add was added recently by
> Robin and hence the guest kernel should be => 5.0-rc1.
>
> NVDIM support is not included currently as we still have an unresolved
> issue while hot adding NVDIMM[2]. However NVDIMM cold plug patches
> can be included, but not done for now, for keeping it simple.
>
> This makes use of GED device to sent hotplug ACPI events to the
> Guest. GED code is based on Nemu. Thanks to the efforts of Samuel and
> Sebastien to add the hardware-reduced support to Nemu using GED
> device[3]. (Please shout if I got the author/signed-off wrong for
> those patches or missed any names).
>
> This is sanity tested on a HiSilicon ARM64 platform and appreciate
> any further testing.
>
> Note:
> Attempted adding dimm_pxm test case to bios-tables-test for arm/virt.
> But noticed the issue decribed here[5]. This is under investigation
> now.
>
> Thanks,
> Shameer
in case this is going through ARM tree:
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> [1] https://patchwork.kernel.org/cover/10837565/
> [2] https://patchwork.kernel.org/cover/10783589/
> [3] https://github.com/intel/nemu/blob/topic/virt-x86/hw/acpi/ged.c
> [4] http://lists.infradead.org/pipermail/linux-arm-kernel/2019-May/651763.html
> [5] https://www.mail-archive.com/qemu-devel@nongnu.org/msg632651.html
>
> v10 --> v11
> -Changed patch #10 to update bios-tables-test-allowed-diff.h with a
> list of expected ACPI tables.
> -GED document changed to rst format (patch #9)
> -Addressed comments from Igor (patch #3 & #5)
> -Igor's R-by to #7, #8 & #11.
>
> v9 --> v10
> -Fix for "make check" failure on x86_64(Patch #1).
> -Minor updates based on Eric's comments.
> -Dropped patch "hw/arm/virt: Add 4.2 machine type" as this is already
> in master now.
> -Added R-by tags by Eric.
>
> v8 --> v9
> -Changes related to GED being a TYPE_SYS_BUS_DEVICE now.
> -Re-arranged patches 8 and 9.
> -Added GED ABI documentation(patch #10).
> -Added numamem and memhp tests to arm/virt(#11 and #12)
> -Dropped few R-by tags as code has changed a bit.
> -Please see Individual patch history for details.
>
> v7 --> v8
> -Addressed comments from Igor.Please see individual patches.
> -Updated bios-tables-test-allowed-diff.h to avoid "make check"
> failure (patch #6) and dropped patch #10
> -Added Igor's R-by to patches 4 & 5.
> -Dropped Erics's R-by from patch #9 for now.
>
> v6 --> v7
> - Added 4.2 machine support and restricted GED creation for < 4.2
> This is to address the migration test fail reported by Eric.
> - Included "tests: Update DSDT ACPI table.." patch(#10) from Eric
> to fix the "make check" bios-tables-test failure.
>
> v5 --> v6
>
> -Addressed comments from Eric.
> -Added R-by from Eric and Igor.
>
> v4 --> v5
> -Removed gsi/ged-irq routing in virt.
> -Added Migration support.
> -Dropped support for DT coldplug case based on the discussions
> here[4]
> -Added system_powerdown support through GED.
>
> v3 --> v4
> Addressed comments from Igor and Eric,
> -Renamed "virt-acpi" to "acpi-ged".
> -Changed ged device parent to TYPE_DEVICE.
> -Introduced DT memory node property "hotpluggable" to resolve device
> memory being treated as early boot memory issue(patch #7).
> -Combined patches #3 and #9 from v3 into #3.
>
> v2 --> v3
>
> Addressed comments from Igor and Eric,
> -Made virt acpi device platform independent and moved
> to hw/acpi/generic_event_device.c
> -Moved ged specific code into hw/acpi/generic_event_device.c
> -Introduced an opt-in feature "fdt" to resolve device-memory being
> treated as early boot memory.
> -Dropped patch #1 from v2.
>
> RFC --> v2
>
> -Use GED device instead of GPIO for ACPI hotplug events.
> -Removed NVDIMM support for now.
> -Includes dropped patches from Eric's v9 series.
>
> Eric Auger (1):
> hw/arm/virt: Add memory hotplug framework
>
> Samuel Ortiz (2):
> hw/acpi: Do not create memory hotplug method when handler is not
> defined
> hw/acpi: Add ACPI Generic Event Device Support
>
> Shameer Kolothum (8):
> hw/acpi: Make ACPI IO address space configurable
> hw/arm/virt: Enable device memory cold/hot plug with ACPI boot
> hw/arm/virt-acpi-build: Add PC-DIMM in SRAT
> hw/arm: Factor out powerdown notifier from GPIO
> hw/arm: Use GED for system_powerdown event
> docs/specs: Add ACPI GED documentation
> tests: Update ACPI tables list for upcoming arm/virt tests
> tests: Add bios tests to arm/virt
>
> docs/specs/acpi_hw_reduced_hotplug.rst | 70 ++++++
> docs/specs/index.rst | 1 +
> hw/acpi/Kconfig | 4 +
> hw/acpi/Makefile.objs | 1 +
> hw/acpi/generic_event_device.c | 311 +++++++++++++++++++++++++
> hw/acpi/memory_hotplug.c | 43 ++--
> hw/arm/Kconfig | 4 +
> hw/arm/virt-acpi-build.c | 35 ++-
> hw/arm/virt.c | 124 +++++++++-
> hw/i386/acpi-build.c | 7 +-
> hw/i386/pc.c | 3 +
> include/hw/acpi/acpi_dev_interface.h | 1 +
> include/hw/acpi/generic_event_device.h | 103 ++++++++
> include/hw/acpi/memory_hotplug.h | 9 +-
> include/hw/arm/virt.h | 5 +
> include/hw/i386/pc.h | 3 +
> tests/bios-tables-test-allowed-diff.h | 16 ++
> tests/bios-tables-test.c | 49 ++++
> 18 files changed, 748 insertions(+), 41 deletions(-)
> create mode 100644 docs/specs/acpi_hw_reduced_hotplug.rst
> create mode 100644 hw/acpi/generic_event_device.c
> create mode 100644 include/hw/acpi/generic_event_device.h
>
> --
> 2.17.1
>
^ permalink raw reply [flat|nested] 60+ messages in thread