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 |
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
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
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
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
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
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
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 --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(); +}
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