Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934356AbcKILY4 (ORCPT ); Wed, 9 Nov 2016 06:24:56 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:55168 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933546AbcKILJe (ORCPT ); Wed, 9 Nov 2016 06:09:34 -0500 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Andy Lutomirski , "Michael S. Tsirkin" , Benjamin Serebrin , Will Deacon Subject: [PATCH 4.8 081/138] virtio_pci: Limit DMA mask to 44 bits for legacy virtio devices Date: Wed, 9 Nov 2016 11:46:04 +0100 Message-Id: <20161109102848.582213068@linuxfoundation.org> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20161109102844.808685475@linuxfoundation.org> References: <20161109102844.808685475@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1932 Lines: 56 4.8-stable review patch. If anyone has any objections, please let me know. ------------------ From: Will Deacon commit a0be1db4304f51c99af6b6e515549794182a94df upstream. Legacy virtio defines the virtqueue base using a 32-bit PFN field, with a read-only register indicating a fixed page size of 4k. This can cause problems for DMA allocators that allocate top down from the DMA mask, which is set to 64 bits. In this case, the addresses are silently truncated to 44-bit, leading to IOMMU faults, failure to read from the queue or data corruption. This patch restricts the coherent DMA mask for legacy PCI virtio devices to 44 bits, which matches the specification. Cc: Andy Lutomirski Cc: Michael S. Tsirkin Cc: Benjamin Serebrin Signed-off-by: Will Deacon Signed-off-by: Michael S. Tsirkin Signed-off-by: Greg Kroah-Hartman --- drivers/virtio/virtio_pci_legacy.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c @@ -212,10 +212,18 @@ int virtio_pci_legacy_probe(struct virti return -ENODEV; } - rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64)); - if (rc) - rc = dma_set_mask_and_coherent(&pci_dev->dev, - DMA_BIT_MASK(32)); + rc = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64)); + if (rc) { + rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32)); + } else { + /* + * The virtio ring base address is expressed as a 32-bit PFN, + * with a page size of 1 << VIRTIO_PCI_QUEUE_ADDR_SHIFT. + */ + dma_set_coherent_mask(&pci_dev->dev, + DMA_BIT_MASK(32 + VIRTIO_PCI_QUEUE_ADDR_SHIFT)); + } + if (rc) dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n");