From patchwork Tue Jan 17 10:04:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 716110 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3v2m1G30WKz9tJD for ; Tue, 17 Jan 2017 21:04:50 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3v2m1G0ffLzDqRp for ; Tue, 17 Jan 2017 21:04:50 +1100 (AEDT) X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3v2m1B6rS8zDqHX for ; Tue, 17 Jan 2017 21:04:46 +1100 (AEDT) Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1652285541; Tue, 17 Jan 2017 10:04:46 +0000 (UTC) Received: from thinkpad.redhat.com (ovpn-116-198.ams2.redhat.com [10.36.116.198]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v0HA4hhd032486; Tue, 17 Jan 2017 05:04:44 -0500 From: Laurent Vivier To: slof@lists.ozlabs.org Date: Tue, 17 Jan 2017 11:04:42 +0100 Message-Id: <1484647482-7310-1-git-send-email-lvivier@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 17 Jan 2017 10:04:46 +0000 (UTC) Subject: [SLOF] [PATCH v2] virtio-scsi: initialize vring avail queue buffers X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" From: Laurent Vivier virtioscsi_init() uses the result of virtio_get_vring_avail() whereas the queue is not enabled: on the first boot, its value is NULL and the driver uses this to communicate with the device. After a reboot, its value is the one given by the OS driver, and it works if the address is in a range SLOF can access. In some cases, for instance with NUMA nodes and hotplugged memory, SLOF cannot access the address set by the kernel, and virtioscsi_init() fails with a data storage exception. To set the vring avail buffer address, we need to enable the queue, what is done by virtio_set_qaddr(). This patch fixes the problem by calling virtio_queue_init_vq() (like other virtio drivers) in virtioscsi_init() as it allocates memory and enables the queue. virtio_queue_init_vq() also replaces the calls to virtio_vring_size() and virtio_get_vring_avail(). Reviewed-by: Thomas Huth --- v2: move vqs declarations to the function only call virtio_cpu_to_modern16() once add CC: to Nikunj lib/libvirtio/virtio-scsi.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/libvirtio/virtio-scsi.c b/lib/libvirtio/virtio-scsi.c index 36b62d1..e95352d 100644 --- a/lib/libvirtio/virtio-scsi.c +++ b/lib/libvirtio/virtio-scsi.c @@ -99,10 +99,9 @@ int virtioscsi_send(struct virtio_device *dev, */ int virtioscsi_init(struct virtio_device *dev) { - struct vring_avail *vq_avail; - unsigned int idx = 0; - int qsize = 0; + struct vqs vq_ctrl, vq_event, vq_request; int status = VIRTIO_STAT_ACKNOWLEDGE; + uint16_t flags; /* Reset device */ // XXX That will clear the virtq base. We need to move @@ -126,17 +125,20 @@ int virtioscsi_init(struct virtio_device *dev) virtio_set_guest_features(dev, 0); } - while(1) { - qsize = virtio_get_qsize(dev, idx); - if (!qsize) - break; - virtio_vring_size(qsize); + if (virtio_queue_init_vq(dev, &vq_ctrl, VIRTIO_SCSI_CONTROL_VQ) || + virtio_queue_init_vq(dev, &vq_event, VIRTIO_SCSI_EVENT_VQ) || + virtio_queue_init_vq(dev, &vq_request, VIRTIO_SCSI_REQUEST_VQ)) + goto dev_error; - vq_avail = virtio_get_vring_avail(dev, idx); - vq_avail->flags = virtio_cpu_to_modern16(dev, VRING_AVAIL_F_NO_INTERRUPT); - vq_avail->idx = 0; - idx++; - } + flags = virtio_cpu_to_modern16(dev, VRING_AVAIL_F_NO_INTERRUPT); + vq_ctrl.avail->flags = flags; + vq_ctrl.avail->idx = 0; + + vq_event.avail->flags = flags; + vq_event.avail->idx = 0; + + vq_request.avail->flags = flags; + vq_request.avail->idx = 0; /* Tell HV that setup succeeded */ status |= VIRTIO_STAT_DRIVER_OK;