[kvm-unit-tests PATCH 6/7] s390x: virtio tests setup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch can be squatch with the next one, "s390x: virtio data
transfer" and is separated to ease review.

In this patch we initialize the VIRTIO device.
There are currently no error insertion, the goal is to get an
initialized device to check data transfer within the next patch.

Future development will include error response checks.

Signed-off-by: Pierre Morel <pmorel@xxxxxxxxxxxxx>
---
 s390x/Makefile      |   1 +
 s390x/unittests.cfg |   4 +
 s390x/virtio_pong.c | 208 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 213 insertions(+)
 create mode 100644 s390x/virtio_pong.c

diff --git a/s390x/Makefile b/s390x/Makefile
index 3f4acc3e..633e1af1 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -24,6 +24,7 @@ tests += $(TEST_DIR)/mvpg.elf
 tests += $(TEST_DIR)/uv-host.elf
 tests += $(TEST_DIR)/edat.elf
 tests += $(TEST_DIR)/mvpg-sie.elf
+tests += $(TEST_DIR)/virtio_pong.elf
 
 tests_binary = $(patsubst %.elf,%.bin,$(tests))
 ifneq ($(HOST_KEY_DOCUMENT),)
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index 9e1802fd..dd84ed28 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -109,3 +109,7 @@ file = edat.elf
 
 [mvpg-sie]
 file = mvpg-sie.elf
+
+[virtio-pong]
+file = uv-virtio.elf
+extra_params = -device virtio-pong-cww
diff --git a/s390x/virtio_pong.c b/s390x/virtio_pong.c
new file mode 100644
index 00000000..1e050a4d
--- /dev/null
+++ b/s390x/virtio_pong.c
@@ -0,0 +1,208 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Channel Subsystem tests
+ *
+ * Copyright (c) 2021 IBM Corp
+ *
+ * Authors:
+ *  Pierre Morel <pmorel@xxxxxxxxxxxxx>
+ *
+ */
+#include <libcflat.h>
+#include <alloc_page.h>
+#include <asm/page.h>
+#include <string.h>
+#include <interrupt.h>
+#include <asm/arch_def.h>
+#include <asm/facility.h>
+#include <asm/uv.h>
+
+#include <css.h>
+#include <virtio.h>
+#include <virtio-config.h>
+#include <virtio-ccw.h>
+
+#include <malloc_io.h>
+#include <asm/time.h>
+
+#define VIRTIO_ID_PONG         30 /* virtio pong */
+
+#define VIRTIO_F_PONG_CKSUM	1
+
+#define SUPPORTED_FEATURES (1UL << VIRTIO_F_RING_INDIRECT_DESC	| \
+			    1UL << VIRTIO_F_RING_EVENT_IDX	| \
+			    1UL << VIRTIO_F_NOTIFY_ON_EMPTY	| \
+			    1UL << VIRTIO_F_ANY_LAYOUT	| \
+			    1UL << VIRTIO_F_PONG_CKSUM)
+
+static struct virtio_ccw_device *vcdev;
+static struct virtqueue *out_vq;
+static struct virtqueue *in_vq;
+
+static void test_find_vqs(void)
+{
+	struct virtio_device *vdev = &vcdev->vdev;
+	static const char *io_names[] = {"pong_input", "pong_output"};
+	struct virtqueue *vqs[2];
+	int ret;
+
+	if (vcdev->state != VCDEV_INIT) {
+		report_skip("Device non initialized");
+		vcdev->state = VCDEV_ERROR;
+		return;
+	}
+
+	ret = vdev->config->find_vqs(vdev, 2, vqs, NULL, io_names);
+	if (!ret) {
+		in_vq = vqs[0];
+		out_vq = vqs[1];
+	}
+	report(!ret, "Find virtqueues");
+}
+
+static int virtio_ccw_init_dev(struct virtio_ccw_device *vcdev)
+{
+	uint64_t features;
+	uint64_t unsupported_feat;
+	int ret;
+
+	ret = virtio_ccw_set_revision(vcdev);
+	report(!ret, "Revision 0");
+	if (ret)
+		return VCDEV_ERROR;
+
+	ret = virtio_ccw_reset(vcdev);
+	report(!ret, "RESET");
+	if (ret)
+		return VCDEV_ERROR;
+
+	ret = virtio_ccw_read_status(vcdev);
+	report(!ret && vcdev->status == 0, "Read Status : 0x%08x", vcdev->status);
+	if (ret)
+		return VCDEV_ERROR;
+
+	vcdev->status = VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER;
+	ret = virtio_ccw_write_status(vcdev);
+	report(!ret, "Write ACKNOWLEDGE and DRIVER Status: 0x%08x", vcdev->status);
+	if (ret)
+		return VCDEV_ERROR;
+
+	/* Checking features */
+	ret = virtio_ccw_read_features(vcdev, &features);
+	report(!ret, "Read features : 0x%016lx", features);
+	if (ret)
+		return VCDEV_ERROR;
+
+	report(features & 1UL << VIRTIO_F_RING_INDIRECT_DESC,
+	       "Feature: RING_INDIRECT_DESC");
+
+	report(features & 1UL << VIRTIO_F_RING_EVENT_IDX,
+	       "Feature: RING_EVENT_IDX");
+
+	unsupported_feat = features & ~SUPPORTED_FEATURES;
+	report(!unsupported_feat, "Features supported: 0x%016lx got 0x%016lx",
+	       SUPPORTED_FEATURES, features);
+	if (unsupported_feat)
+		return VCDEV_ERROR;
+
+	/* Accept supported features */
+	features &= SUPPORTED_FEATURES;
+	ret = virtio_ccw_write_features(vcdev, features);
+	report(!ret, "Write features: 0x%016lx", features);
+	if (ret)
+		return VCDEV_ERROR;
+
+	vcdev->status |= VIRTIO_CONFIG_S_FEATURES_OK;
+	ret = virtio_ccw_write_status(vcdev);
+	report(!ret, "Write FEATURES_OK Status: 0x%08x", vcdev->status);
+	if (ret)
+		return VCDEV_ERROR;
+
+	ret = virtio_ccw_read_status(vcdev);
+	report(!ret, "Read Status : 0x%08x", vcdev->status);
+	if (ret)
+		return VCDEV_ERROR;
+	report(vcdev->status & VIRTIO_CONFIG_S_FEATURES_OK, "Status: FEATURES_OK");
+	if (!(vcdev->status & VIRTIO_CONFIG_S_FEATURES_OK))
+		return VCDEV_ERROR;
+
+	ret = virtio_ccw_setup_indicators(vcdev);
+	report(!ret, "Setup indicators");
+	if (ret)
+		return VCDEV_ERROR;
+
+	vcdev->vdev.config = virtio_ccw_register();
+	if (!vcdev->vdev.config)
+		return VCDEV_ERROR;
+
+	vcdev->status |= VIRTIO_CONFIG_S_DRIVER_OK;
+	ret = virtio_ccw_write_status(vcdev);
+	report(!ret, "Write DRIVER_OK Status: 0x%08x", vcdev->status);
+	if (ret)
+		return VCDEV_ERROR;
+
+	return VCDEV_INIT;
+}
+
+static void test_virtio_device_init(void)
+{
+	struct virtio_device *vdev;
+
+	vdev = virtio_bind(VIRTIO_ID_PONG);
+	if (!vdev) {
+		report_abort("virtio_bind failed");
+		return;
+	}
+
+	vcdev = to_vc_device(vdev);
+	vcdev->state = virtio_ccw_init_dev(vcdev);
+	report(vcdev->state == VCDEV_INIT, "Initialization");
+}
+
+static void test_virtio_ccw_bus(void)
+{
+	report(virtio_ccw_init(), "Initialisation");
+}
+
+static void virtio_irq(void)
+{
+	/*
+	 * Empty function currently needed to setup IRQ by providing
+	 * an address to register_css_irq_func().
+	 * Will be use in the future to check parallel I/O.
+	 */
+}
+
+static int css_init(void)
+{
+	assert(register_css_irq_func(virtio_irq) == 0);
+	return 0;
+}
+
+static struct {
+	const char *name;
+	void (*func)(void);
+} tests[] = {
+	{ "CCW Bus", test_virtio_ccw_bus },
+	{ "CCW Device", test_virtio_device_init },
+	{ "Queues setup", test_find_vqs },
+	{ NULL, NULL }
+};
+
+int main(int argc, char *argv[])
+{
+	int i;
+
+	report_prefix_push("Virtio");
+
+	css_init();
+
+	for (i = 0; tests[i].name; i++) {
+		report_prefix_push(tests[i].name);
+		tests[i].func();
+		report_prefix_pop();
+	}
+	report_prefix_pop();
+
+	return report_summary();
+}
-- 
2.25.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux