diff mbox series

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

Message ID 1630059440-15586-7-git-send-email-pmorel@linux.ibm.com (mailing list archive)
State New, archived
Headers show
Series Extending VIRTIO with a data transfer test | expand

Commit Message

Pierre Morel Aug. 27, 2021, 10:17 a.m. UTC
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@linux.ibm.com>
---
 s390x/Makefile      |   1 +
 s390x/unittests.cfg |   4 +
 s390x/virtio_pong.c | 208 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 213 insertions(+)
 create mode 100644 s390x/virtio_pong.c

Comments

Andrew Jones Nov. 3, 2021, 7:56 a.m. UTC | #1
On Fri, Aug 27, 2021 at 12:17:19PM +0200, Pierre Morel wrote:
> +
> +#define VIRTIO_ID_PONG         30 /* virtio pong */

I take it this is a virtio test device that ping-pong's I/O. It sounds
useful for other VIRTIO transports too. Can it be ported? Hmm, I can't
find it in QEMU at all?

Thanks,
drew
Thomas Huth Nov. 3, 2021, 8:14 a.m. UTC | #2
On 03/11/2021 08.56, Andrew Jones wrote:
> On Fri, Aug 27, 2021 at 12:17:19PM +0200, Pierre Morel wrote:
>> +
>> +#define VIRTIO_ID_PONG         30 /* virtio pong */
> 
> I take it this is a virtio test device that ping-pong's I/O. It sounds
> useful for other VIRTIO transports too. Can it be ported? Hmm, I can't
> find it in QEMU at all?

I also wonder whether we could do testing with an existing device instead? 
E.g. do a loopback with a virtio-serial device? Or use two virtio-net 
devices, connect them to a QEMU hub and send a packet from one device to the 
other? ... that would be a little bit more complicated here, but would not 
require a PONG device upstream first, so it could also be used for testing 
older versions of QEMU...

  Thomas
Pierre Morel Nov. 8, 2021, 12:53 p.m. UTC | #3
On 11/3/21 08:56, Andrew Jones wrote:
> On Fri, Aug 27, 2021 at 12:17:19PM +0200, Pierre Morel wrote:
>> +
>> +#define VIRTIO_ID_PONG         30 /* virtio pong */
> 
> I take it this is a virtio test device that ping-pong's I/O. It sounds
> useful for other VIRTIO transports too. Can it be ported? Hmm, I can't
> find it in QEMU at all?
> 
> Thanks,
> drew
> 

It could certainly be ported, I will study the question.

I sent a first version of the QEMU part here:

https://marc.info/?l=kvm&m=163006146622427&w=3


Regards,
Pierre
Pierre Morel Nov. 8, 2021, 1 p.m. UTC | #4
On 11/3/21 09:14, Thomas Huth wrote:
> On 03/11/2021 08.56, Andrew Jones wrote:
>> On Fri, Aug 27, 2021 at 12:17:19PM +0200, Pierre Morel wrote:
>>> +
>>> +#define VIRTIO_ID_PONG         30 /* virtio pong */
>>
>> I take it this is a virtio test device that ping-pong's I/O. It sounds
>> useful for other VIRTIO transports too. Can it be ported? Hmm, I can't
>> find it in QEMU at all?
> 
> I also wonder whether we could do testing with an existing device 
> instead? E.g. do a loopback with a virtio-serial device? Or use two 
> virtio-net devices, connect them to a QEMU hub and send a packet from 
> one device to the other? ... that would be a little bit more complicated 
> here, but would not require a PONG device upstream first, so it could 
> also be used for testing older versions of QEMU...
> 
>   Thomas
> 
> 

Yes having a dedicated device has the drawback that we need it in QEMU.
On the other hand using a specific device, serial or network, wouldn't 
we get trapped with a reduce set of test possibilities?

The idea was to have a dedicated test device, which could be flexible 
and extended to test all VIRTIO features, even the current 
implementation is yet far from it.

Regards,
Pierre
Thomas Huth Nov. 9, 2021, 7:10 a.m. UTC | #5
On 08/11/2021 14.00, Pierre Morel wrote:
> 
> 
> On 11/3/21 09:14, Thomas Huth wrote:
>> On 03/11/2021 08.56, Andrew Jones wrote:
>>> On Fri, Aug 27, 2021 at 12:17:19PM +0200, Pierre Morel wrote:
>>>> +
>>>> +#define VIRTIO_ID_PONG         30 /* virtio pong */
>>>
>>> I take it this is a virtio test device that ping-pong's I/O. It sounds
>>> useful for other VIRTIO transports too. Can it be ported? Hmm, I can't
>>> find it in QEMU at all?
>>
>> I also wonder whether we could do testing with an existing device instead? 
>> E.g. do a loopback with a virtio-serial device? Or use two virtio-net 
>> devices, connect them to a QEMU hub and send a packet from one device to 
>> the other? ... that would be a little bit more complicated here, but would 
>> not require a PONG device upstream first, so it could also be used for 
>> testing older versions of QEMU...
>>
>>   Thomas
>>
>>
> 
> Yes having a dedicated device has the drawback that we need it in QEMU.
> On the other hand using a specific device, serial or network, wouldn't we 
> get trapped with a reduce set of test possibilities?
> 
> The idea was to have a dedicated test device, which could be flexible and 
> extended to test all VIRTIO features, even the current implementation is yet 
> far from it.

Do you have anything in the works that could only be tested with a dedicated 
test device? If not, I'd rather go with the loopback via virtio-net, I think 
(you can peek into the s390-ccw bios sources to see how to send packets via 
virtio-net, shouldn't be too hard to do, I think).

The pong device could later be added on top for additional tests that are 
not possible with virtio-net. And having some basic tests with virito-net 
has also the advantage that the k-u-t work with QEMU binaries where the pong 
device is not available, e.g. older versions and downstream versions that 
only enable the bare minimum of devices to keep the attack surface small.

  Thomas
Andrew Jones Nov. 9, 2021, 8:42 a.m. UTC | #6
On Tue, Nov 09, 2021 at 08:10:34AM +0100, Thomas Huth wrote:
> On 08/11/2021 14.00, Pierre Morel wrote:
> > 
> > 
> > On 11/3/21 09:14, Thomas Huth wrote:
> > > On 03/11/2021 08.56, Andrew Jones wrote:
> > > > On Fri, Aug 27, 2021 at 12:17:19PM +0200, Pierre Morel wrote:
> > > > > +
> > > > > +#define VIRTIO_ID_PONG         30 /* virtio pong */
> > > > 
> > > > I take it this is a virtio test device that ping-pong's I/O. It sounds
> > > > useful for other VIRTIO transports too. Can it be ported? Hmm, I can't
> > > > find it in QEMU at all?
> > > 
> > > I also wonder whether we could do testing with an existing device
> > > instead? E.g. do a loopback with a virtio-serial device? Or use two
> > > virtio-net devices, connect them to a QEMU hub and send a packet
> > > from one device to the other? ... that would be a little bit more
> > > complicated here, but would not require a PONG device upstream
> > > first, so it could also be used for testing older versions of
> > > QEMU...
> > > 
> > >   Thomas
> > > 
> > > 
> > 
> > Yes having a dedicated device has the drawback that we need it in QEMU.
> > On the other hand using a specific device, serial or network, wouldn't
> > we get trapped with a reduce set of test possibilities?
> > 
> > The idea was to have a dedicated test device, which could be flexible
> > and extended to test all VIRTIO features, even the current
> > implementation is yet far from it.
> 
> Do you have anything in the works that could only be tested with a dedicated
> test device? If not, I'd rather go with the loopback via virtio-net, I think
> (you can peek into the s390-ccw bios sources to see how to send packets via
> virtio-net, shouldn't be too hard to do, I think).
> 
> The pong device could later be added on top for additional tests that are
> not possible with virtio-net. And having some basic tests with virito-net
> has also the advantage that the k-u-t work with QEMU binaries where the pong
> device is not available, e.g. older versions and downstream versions that
> only enable the bare minimum of devices to keep the attack surface small.
>

I'd also like to see the testdev we already have, qemu:chardev/testdev.c,
get more functions, but I'm not sure virtio-serial will allow you to
exercise all the virtio functionality that you'd like to.

Thanks,
drew
Pierre Morel Nov. 9, 2021, 9:01 a.m. UTC | #7
On 11/9/21 09:42, Andrew Jones wrote:
> On Tue, Nov 09, 2021 at 08:10:34AM +0100, Thomas Huth wrote:
>> On 08/11/2021 14.00, Pierre Morel wrote:
>>>
>>>
>>> On 11/3/21 09:14, Thomas Huth wrote:
>>>> On 03/11/2021 08.56, Andrew Jones wrote:
>>>>> On Fri, Aug 27, 2021 at 12:17:19PM +0200, Pierre Morel wrote:
>>>>>> +
>>>>>> +#define VIRTIO_ID_PONG         30 /* virtio pong */
>>>>>
>>>>> I take it this is a virtio test device that ping-pong's I/O. It sounds
>>>>> useful for other VIRTIO transports too. Can it be ported? Hmm, I can't
>>>>> find it in QEMU at all?
>>>>
>>>> I also wonder whether we could do testing with an existing device
>>>> instead? E.g. do a loopback with a virtio-serial device? Or use two
>>>> virtio-net devices, connect them to a QEMU hub and send a packet
>>>> from one device to the other? ... that would be a little bit more
>>>> complicated here, but would not require a PONG device upstream
>>>> first, so it could also be used for testing older versions of
>>>> QEMU...
>>>>
>>>>    Thomas
>>>>
>>>>
>>>
>>> Yes having a dedicated device has the drawback that we need it in QEMU.
>>> On the other hand using a specific device, serial or network, wouldn't
>>> we get trapped with a reduce set of test possibilities?
>>>
>>> The idea was to have a dedicated test device, which could be flexible
>>> and extended to test all VIRTIO features, even the current
>>> implementation is yet far from it.
>>
>> Do you have anything in the works that could only be tested with a dedicated
>> test device? If not, I'd rather go with the loopback via virtio-net, I think
>> (you can peek into the s390-ccw bios sources to see how to send packets via
>> virtio-net, shouldn't be too hard to do, I think).
>>
>> The pong device could later be added on top for additional tests that are
>> not possible with virtio-net. And having some basic tests with virito-net
>> has also the advantage that the k-u-t work with QEMU binaries where the pong
>> device is not available, e.g. older versions and downstream versions that
>> only enable the bare minimum of devices to keep the attack surface small.
>>
> 
> I'd also like to see the testdev we already have, qemu:chardev/testdev.c,
> get more functions, but I'm not sure virtio-serial will allow you to
> exercise all the virtio functionality that you'd like to.
> 
> Thanks,
> drew
> 

Yes, that is why I did not used it first.
But OK, I understand what you both want and will build something in that 
direction, virtio-net, virtio-serial and come back later to something 
independent of existing devices if we find it does have a purpose.
Thanks for the comments.

Regards,
Pierre
diff mbox series

Patch

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@linux.ibm.com>
+ *
+ */
+#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();
+}