From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-by2nam03on0102.outbound.protection.outlook.com ([104.47.42.102]:45380 "EHLO NAM03-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727338AbeH3WFF (ORCPT ); Thu, 30 Aug 2018 18:05:05 -0400 From: Sasha Levin To: "stable@vger.kernel.org" CC: Suzuki K Poulose , "Michael S. Tsirkin" , Jason Wang , Marc Zyngier , Christoffer Dall , Peter Maydel , Jean-Philippe Brucker , Sasha Levin Subject: [PATCH AUTOSEL 4.18 018/113] virtio: pci-legacy: Validate queue pfn Date: Thu, 30 Aug 2018 18:01:44 +0000 Message-ID: <20180830180050.35735-18-alexander.levin@microsoft.com> References: <20180830180050.35735-1-alexander.levin@microsoft.com> In-Reply-To: <20180830180050.35735-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Suzuki K Poulose [ Upstream commit 69599206ea9a3f8f2e94d46580579cbf9d08ad6c ] Legacy PCI over virtio uses a 32bit PFN for the queue. If the queue pfn is too large to fit in 32bits, which we could hit on arm64 systems with 52bit physical addresses (even with 64K page size), we simply miss out a proper link to the other side of the queue. Add a check to validate the PFN, rather than silently breaking the devices. Cc: "Michael S. Tsirkin" Cc: Jason Wang Cc: Marc Zyngier Cc: Christoffer Dall Cc: Peter Maydel Cc: Jean-Philippe Brucker Signed-off-by: Suzuki K Poulose Signed-off-by: Michael S. Tsirkin Signed-off-by: Sasha Levin --- drivers/virtio/virtio_pci_legacy.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci= _legacy.c index 2780886e8ba3..de062fb201bc 100644 --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c @@ -122,6 +122,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_dev= ice *vp_dev, struct virtqueue *vq; u16 num; int err; + u64 q_pfn; =20 /* Select the queue we're interested in */ iowrite16(index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); @@ -141,9 +142,17 @@ static struct virtqueue *setup_vq(struct virtio_pci_de= vice *vp_dev, if (!vq) return ERR_PTR(-ENOMEM); =20 + q_pfn =3D virtqueue_get_desc_addr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT; + if (q_pfn >> 32) { + dev_err(&vp_dev->pci_dev->dev, + "platform bug: legacy virtio-mmio must not be used with RAM above 0x%ll= xGB\n", + 0x1ULL << (32 + PAGE_SHIFT - 30)); + err =3D -E2BIG; + goto out_del_vq; + } + /* activate the queue */ - iowrite32(virtqueue_get_desc_addr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT, - vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); + iowrite32(q_pfn, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); =20 vq->priv =3D (void __force *)vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY; =20 @@ -160,6 +169,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_dev= ice *vp_dev, =20 out_deactivate: iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); +out_del_vq: vring_del_virtqueue(vq); return ERR_PTR(err); } --=20 2.17.1