lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220704171701.127665-7-sgarzare@redhat.com>
Date:   Mon,  4 Jul 2022 19:17:01 +0200
From:   Stefano Garzarella <sgarzare@...hat.com>
To:     virtualization@...ts.linux-foundation.org
Cc:     Jason Wang <jasowang@...hat.com>,
        "Michael S. Tsirkin" <mst@...hat.com>,
        linux-kernel@...r.kernel.org,
        Eugenio PĂ©rez <eperezma@...hat.com>,
        Stefano Garzarella <sgarzare@...hat.com>
Subject: [RFC PATCH 6/6] vdpasim: add vdpa_sim_test module

This adds a test module for vhost-vdpa infrastructure to be used
with virtio_test.

Intentionally not tied to kbuild to prevent people from installing
and loading it accidentally.

Signed-off-by: Stefano Garzarella <sgarzare@...hat.com>
---
 drivers/vdpa/vdpa_sim/vdpa_sim_test.c | 203 ++++++++++++++++++++++++++
 tools/virtio/vdpa_test/vdpa_test.c    |   1 +
 tools/virtio/Makefile                 |  32 +++-
 tools/virtio/vdpa_test/Makefile       |   3 +
 4 files changed, 234 insertions(+), 5 deletions(-)
 create mode 100644 drivers/vdpa/vdpa_sim/vdpa_sim_test.c
 create mode 100644 tools/virtio/vdpa_test/vdpa_test.c
 create mode 100644 tools/virtio/vdpa_test/Makefile

diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_test.c b/drivers/vdpa/vdpa_sim/vdpa_sim_test.c
new file mode 100644
index 000000000000..17628b1a1cdd
--- /dev/null
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim_test.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * VDPA simulator for virtio-test.
+ *
+ * Copyright (c) 2022, Red Hat Inc. All rights reserved.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/vringh.h>
+#include <linux/vdpa.h>
+
+#include "vdpa_sim.h"
+
+#define DRV_VERSION  "0.1"
+#define DRV_AUTHOR   "Stefano Garzarella <sgarzare@...hat.com>"
+#define DRV_DESC     "vDPA Device Simulator for virtio-test device"
+#define DRV_LICENSE  "GPL v2"
+
+#define VDPASIM_TEST_FEATURES	(VDPASIM_FEATURES)
+#define VDPASIM_TEST_VIRTIO_ID	0
+
+/* 1 virtqueues, 1 address spaces, 1 virtqueue groups */
+#define VDPASIM_TEST_VQ_NUM	1
+#define VDPASIM_TEST_AS_NUM	1
+#define VDPASIM_TEST_GROUP_NUM	1
+
+static bool vdpasim_test_handle_req(struct vdpasim *vdpasim,
+				    struct vdpasim_virtqueue *vq)
+{
+	int ret;
+
+	ret = vringh_getdesc_iotlb(&vq->vring, &vq->out_iov, &vq->in_iov,
+				   &vq->head, GFP_ATOMIC);
+	if (ret != 1)
+		return false;
+
+	if (vq->out_iov.used == 0 || vq->in_iov.used > 0) {
+		dev_dbg(&vdpasim->vdpa.dev, "Unexpected descriptor format - out_iov: %u in_iov %u\n",
+			vq->out_iov.used, vq->in_iov.used);
+		return false;
+	}
+
+	if (vringh_kiov_length(&vq->out_iov) == 0) {
+		dev_dbg(&vdpasim->vdpa.dev, "Unexpected 0 len for out buffer\n");
+		return false;
+	}
+
+	vringh_complete_iotlb(&vq->vring, vq->head, 0);
+
+	return true;
+}
+
+static void vdpasim_test_work(struct work_struct *work)
+{
+	struct vdpasim *vdpasim = container_of(work, struct vdpasim, work);
+	bool reschedule = false;
+	int i;
+
+	spin_lock(&vdpasim->lock);
+
+	if (!(vdpasim->status & VIRTIO_CONFIG_S_DRIVER_OK))
+		goto out;
+
+	for (i = 0; i < VDPASIM_TEST_VQ_NUM; i++) {
+		struct vdpasim_virtqueue *vq = &vdpasim->vqs[i];
+		int reqs = 0;
+
+		if (!vq->ready)
+			continue;
+
+		while (vdpasim_test_handle_req(vdpasim, vq)) {
+			/* Make sure used is visible before rasing the interrupt. */
+			smp_wmb();
+
+			local_bh_disable();
+			if (vringh_need_notify_iotlb(&vq->vring) > 0)
+				vringh_notify(&vq->vring);
+			local_bh_enable();
+
+			if (++reqs > 4) {
+				reschedule = true;
+				break;
+			}
+		}
+	}
+out:
+	spin_unlock(&vdpasim->lock);
+
+	if (reschedule)
+		schedule_work(&vdpasim->work);
+}
+
+static void vdpasim_test_get_config(struct vdpasim *vdpasim, void *config)
+{
+	u64 *test_config = config;
+
+	*test_config = cpu_to_vdpasim64(vdpasim, 42);
+}
+
+static void vdpasim_test_mgmtdev_release(struct device *dev)
+{
+}
+
+static struct device vdpasim_test_mgmtdev = {
+	.init_name = "vdpasim_test",
+	.release = vdpasim_test_mgmtdev_release,
+};
+
+static int vdpasim_test_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
+				const struct vdpa_dev_set_config *config)
+{
+	struct vdpasim_dev_attr dev_attr = {};
+	struct vdpasim *simdev;
+	int ret;
+
+	dev_attr.mgmt_dev = mdev;
+	dev_attr.name = name;
+	dev_attr.id = VDPASIM_TEST_VIRTIO_ID;
+	dev_attr.supported_features = VDPASIM_TEST_FEATURES;
+	dev_attr.nvqs = VDPASIM_TEST_VQ_NUM;
+	dev_attr.ngroups = VDPASIM_TEST_GROUP_NUM;
+	dev_attr.nas = VDPASIM_TEST_AS_NUM;
+	dev_attr.config_size = sizeof(uint64_t);
+	dev_attr.get_config = vdpasim_test_get_config;
+	dev_attr.work_fn = vdpasim_test_work;
+	dev_attr.buffer_size = 0;
+
+	simdev = vdpasim_create(&dev_attr);
+	if (IS_ERR(simdev))
+		return PTR_ERR(simdev);
+
+	ret = _vdpa_register_device(&simdev->vdpa, VDPASIM_TEST_VQ_NUM);
+	if (ret)
+		goto put_dev;
+
+	return 0;
+
+put_dev:
+	put_device(&simdev->vdpa.dev);
+	return ret;
+}
+
+static void vdpasim_test_dev_del(struct vdpa_mgmt_dev *mdev,
+				 struct vdpa_device *dev)
+{
+	struct vdpasim *simdev = container_of(dev, struct vdpasim, vdpa);
+
+	_vdpa_unregister_device(&simdev->vdpa);
+}
+
+static const struct vdpa_mgmtdev_ops vdpasim_test_mgmtdev_ops = {
+	.dev_add = vdpasim_test_dev_add,
+	.dev_del = vdpasim_test_dev_del
+};
+
+static struct virtio_device_id id_table[] = {
+	{ VDPASIM_TEST_VIRTIO_ID, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+
+static struct vdpa_mgmt_dev mgmt_dev = {
+	.device = &vdpasim_test_mgmtdev,
+	.id_table = id_table,
+	.ops = &vdpasim_test_mgmtdev_ops,
+};
+
+static int __init vdpasim_test_init(void)
+{
+	int ret;
+
+	ret = device_register(&vdpasim_test_mgmtdev);
+	if (ret)
+		return ret;
+
+	ret = vdpa_mgmtdev_register(&mgmt_dev);
+	if (ret)
+		goto parent_err;
+
+	return 0;
+
+parent_err:
+	device_unregister(&vdpasim_test_mgmtdev);
+	return ret;
+}
+
+static void __exit vdpasim_test_exit(void)
+{
+	vdpa_mgmtdev_unregister(&mgmt_dev);
+	device_unregister(&vdpasim_test_mgmtdev);
+}
+
+module_init(vdpasim_test_init)
+module_exit(vdpasim_test_exit)
+
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE(DRV_LICENSE);
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESC);
diff --git a/tools/virtio/vdpa_test/vdpa_test.c b/tools/virtio/vdpa_test/vdpa_test.c
new file mode 100644
index 000000000000..779d2be2c9e5
--- /dev/null
+++ b/tools/virtio/vdpa_test/vdpa_test.c
@@ -0,0 +1 @@
+#include "vdpa_sim/vdpa_sim_test.c"
diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile
index 1b25cc7c64bb..74a3e8d649a3 100644
--- a/tools/virtio/Makefile
+++ b/tools/virtio/Makefile
@@ -10,6 +10,7 @@ LDFLAGS += -pthread
 vpath %.c ../../drivers/virtio ../../drivers/vhost
 mod:
 	${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test V=${V}
+	${MAKE} -C `pwd`/../.. M=`pwd`/vdpa_test V=${V}
 
 #oot: build vhost as an out of tree module for a distro kernel
 #no effort is taken to make it actually build or work, but tends to mostly work
@@ -18,26 +19,47 @@ mod:
 #resulting modules in production!
 OOT_KSRC=/lib/modules/$$(uname -r)/build
 OOT_VHOST=`pwd`/../../drivers/vhost
+OOT_VDPA=`pwd`/../../drivers/vdpa
 #Everyone depends on vhost
 #Tweak the below to enable more modules
 OOT_CONFIGS=\
 	CONFIG_VHOST=m \
+	CONFIG_VHOST_VDPA=m \
 	CONFIG_VHOST_NET=n \
 	CONFIG_VHOST_SCSI=n \
 	CONFIG_VHOST_VSOCK=n \
 	CONFIG_VHOST_RING=n
-OOT_BUILD=KCFLAGS="-I "${OOT_VHOST} ${MAKE} -C ${OOT_KSRC} V=${V}
+OOT_VDPA_CONFIGS=\
+	CONFIG_VDPA=m \
+	CONFIG_VDPA_SIM=m \
+	CONFIG_VDPA_SIM_NET=n \
+	CONFIG_VDPA_SIM_BLOCK=n \
+	CONFIG_VDPA_USER=n \
+	CONFIG_MLX5_VDPA=n \
+	CONFIG_MLX5_VDPA_NET=n \
+	CONFIG_IFCVF=n \
+	CONFIG_VP_VDPA=n \
+	CONFIG_ALIBABA_ENI_VDPA=n
+OOT_BUILD=KCFLAGS="-I "${OOT_VHOST}" -I "${OOT_VDPA}  ${MAKE} -C ${OOT_KSRC} V=${V}
 oot-build:
 	echo "UNSUPPORTED! Don't use the resulting modules in production!"
 	${OOT_BUILD} M=`pwd`/vhost_test
 	${OOT_BUILD} M=${OOT_VHOST} ${OOT_CONFIGS}
 
-oot-clean: oot-build
-oot: oot-build
+oot-vdpa-build: oot-build
+	echo "UNSUPPORTED! Don't use the resulting modules in production!"
+	${OOT_BUILD} M=`pwd`/vdpa_test
+	${OOT_BUILD} M=${OOT_VDPA} ${OOT_VDPA_CONFIGS}
+
+oot-clean: oot
+oot: oot-build oot-vdpa-build
 oot-clean: OOT_BUILD+=clean
 
-.PHONY: all test mod clean vhost oot oot-clean oot-build
-clean:
+.PHONY: all test mod clean vhost oot oot-clean oot-build oot-vdpa-build clean-vdpa
+clean-vdpa:
+	${RM} vdpa_test/*.o vdpa_test/.*.cmd vdpa_test/Module.symvers \
+              vdpa_test/modules.order
+clean: clean-vdpa
 	${RM} *.o vringh_test virtio_test vhost_test/*.o vhost_test/.*.cmd \
               vhost_test/Module.symvers vhost_test/modules.order *.d
 -include *.d
diff --git a/tools/virtio/vdpa_test/Makefile b/tools/virtio/vdpa_test/Makefile
new file mode 100644
index 000000000000..fce9f344d88f
--- /dev/null
+++ b/tools/virtio/vdpa_test/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-m += vdpa_test.o
+ccflags-y += -I$(srctree)/drivers/vdpa/
-- 
2.36.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ