From nobody Mon Sep 16 20:13:40 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1712734531493231.97278231573387; Wed, 10 Apr 2024 00:35:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ruSQu-0005Zs-RR; Wed, 10 Apr 2024 03:31:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ruSQW-0005Qq-8R; Wed, 10 Apr 2024 03:31:29 -0400 Received: from isrv.corpit.ru ([86.62.121.231]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ruSQU-0005QY-HE; Wed, 10 Apr 2024 03:31:23 -0400 Received: from tsrv.corpit.ru (tsrv.tls.msk.ru [192.168.177.2]) by isrv.corpit.ru (Postfix) with ESMTP id 9AB035D6C4; Wed, 10 Apr 2024 10:25:08 +0300 (MSK) Received: from tls.msk.ru (mjt.wg.tls.msk.ru [192.168.177.130]) by tsrv.corpit.ru (Postfix) with SMTP id 3E3C9B0304; Wed, 10 Apr 2024 10:23:10 +0300 (MSK) Received: (nullmailer pid 4191904 invoked by uid 1000); Wed, 10 Apr 2024 07:23:04 -0000 From: Michael Tokarev To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org, Wafer , =?UTF-8?q?Eugenio=20P=C3=A9rez?= , "Michael S . Tsirkin" , Michael Tokarev Subject: [Stable-8.2.3 84/87] hw/virtio: Fix packed virtqueue flush used_idx Date: Wed, 10 Apr 2024 10:22:57 +0300 Message-Id: <20240410072303.4191455-84-mjt@tls.msk.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=86.62.121.231; envelope-from=mjt@tls.msk.ru; helo=isrv.corpit.ru X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZM-MESSAGEID: 1712734532717100003 From: Wafer In the event of writing many chains of descriptors, the device must write just the id of the last buffer in the descriptor chain, skip forward the number of descriptors in the chain, and then repeat the operations for the rest of chains. Current QEMU code writes all the buffer ids consecutively, and then skips all the buffers altogether. This is a bug, and can be reproduced with a VirtIONet device with _F_MRG_RXBUB and without _F_INDIRECT_DESC: If a virtio-net device has the VIRTIO_NET_F_MRG_RXBUF feature but not the VIRTIO_RING_F_INDIRECT_DESC feature, 'VirtIONetQueue->rx_vq' will use the merge feature to store data in multiple 'elems'. The 'num_buffers' in the virtio header indicates how many elements are merg= ed. If the value of 'num_buffers' is greater than 1, all the merged elements will be filled into the descriptor ring. The 'idx' of the elements should be the value of 'vq->used_idx' plus 'ndesc= s'. Fixes: 86044b24e8 ("virtio: basic packed virtqueue support") Acked-by: Eugenio P=C3=A9rez Signed-off-by: Wafer Message-Id: <20240407015451.5228-2-wafer@jaguarmicro.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin (cherry picked from commit 2d9a31b3c27311eca1682cb2c076d7a300441960) Signed-off-by: Michael Tokarev diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 356d690cc9..aa02c4937c 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -957,12 +957,20 @@ static void virtqueue_packed_flush(VirtQueue *vq, uns= igned int count) return; } =20 + /* + * For indirect element's 'ndescs' is 1. + * For all other elemment's 'ndescs' is the + * number of descriptors chained by NEXT (as set in virtqueue_packed_p= op). + * So When the 'elem' be filled into the descriptor ring, + * The 'idx' of this 'elem' shall be + * the value of 'vq->used_idx' plus the 'ndescs'. + */ + ndescs +=3D vq->used_elems[0].ndescs; for (i =3D 1; i < count; i++) { - virtqueue_packed_fill_desc(vq, &vq->used_elems[i], i, false); + virtqueue_packed_fill_desc(vq, &vq->used_elems[i], ndescs, false); ndescs +=3D vq->used_elems[i].ndescs; } virtqueue_packed_fill_desc(vq, &vq->used_elems[0], 0, true); - ndescs +=3D vq->used_elems[0].ndescs; =20 vq->inuse -=3D ndescs; vq->used_idx +=3D ndescs; --=20 2.39.2