From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by dpdk.org (Postfix) with ESMTP id 58BC51D9E for ; Tue, 27 Feb 2018 15:34:59 +0100 (CET) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EBCB58182D27; Tue, 27 Feb 2018 14:34:58 +0000 (UTC) Received: from localhost.localdomain (unknown [10.36.112.12]) by smtp.corp.redhat.com (Postfix) with ESMTP id 935392024CA8; Tue, 27 Feb 2018 14:34:57 +0000 (UTC) From: Maxime Coquelin To: jianfeng.tan@intel.com, stefanha@redhat.com, tiwei.bie@intel.com, jfreimann@redhat.com, dev@dpdk.org Cc: Maxime Coquelin Date: Tue, 27 Feb 2018 15:34:41 +0100 Message-Id: <20180227143441.6471-4-maxime.coquelin@redhat.com> In-Reply-To: <20180227143441.6471-1-maxime.coquelin@redhat.com> References: <20180227143441.6471-1-maxime.coquelin@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Tue, 27 Feb 2018 14:34:58 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Tue, 27 Feb 2018 14:34:58 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'maxime.coquelin@redhat.com' RCPT:'' Subject: [dpdk-dev] [RFC v2 3/3] vhost_user: work around invalid rings addresses sent by QEMU X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Feb 2018 14:34:59 -0000 When the guest driver driver does not initialize all the queues, QEMU currently sends SET_VRING_ADDR request for these queues. In this case all the desc, avail and used addresses have GPA 0, so translating them likely succeed. The problem is that even if the uninitialized queues remain disabled, the host application may request to disable the notifications using rte_vhost_enable_guest_notification(). Doing this results in writing 0 to the used ring flag field, so resulting in writing 0 in the guest physical address 0. This patch adds a check to ensure all the ring addresses are different before their translation. When VHOST_USER_F_PROTOCOL_VIRTIO_STATUS and VIRTIO_F_VERSION_1 have been negotiated, the uninitialized queues will be removed when driver sets the DRIVER_OK status bit. Otherwise, the port will never start to avoid any guest memory corruption. Signed-off-by: Maxime Coquelin --- lib/librte_vhost/vhost_user.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index 63f501e8d..afa7f7268 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -448,6 +448,19 @@ translate_ring_addresses(struct virtio_net *dev, int vq_index) if (vq->desc && vq->avail && vq->used) return dev; + /* + * QEMU currently sends SET_VRING_ADDR request even for queues + * not initialized by the guest driver. In this case, all rings + * addresses are identical (GPA 0). + */ + if (addr->desc_user_addr == addr->avail_user_addr && + addr->desc_user_addr == addr->used_user_addr) { + RTE_LOG(INFO, VHOST_CONFIG, + "Invalid rings addresses for dev %d queue %d\n", + dev->vid, vq_index); + return dev; + } + vq->desc = (struct vring_desc *)(uintptr_t)ring_addr_to_vva(dev, vq, addr->desc_user_addr, sizeof(struct vring_desc)); if (vq->desc == 0) { -- 2.14.3