From patchwork Mon Apr 18 09:58:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Michael S. Tsirkin" X-Patchwork-Id: 611637 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qpNrq4RHBz9t3f for ; Mon, 18 Apr 2016 19:58:51 +1000 (AEST) Received: from localhost ([::1]:34341 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1as5xB-0007U3-Pg for incoming@patchwork.ozlabs.org; Mon, 18 Apr 2016 05:58:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49293) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1as5wk-0006Xf-6Z for qemu-devel@nongnu.org; Mon, 18 Apr 2016 05:58:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1as5wj-0006Hv-10 for qemu-devel@nongnu.org; Mon, 18 Apr 2016 05:58:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55085) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1as5wi-0006HI-Q5 for qemu-devel@nongnu.org; Mon, 18 Apr 2016 05:58:20 -0400 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 4EB59C05681D; Mon, 18 Apr 2016 09:58:20 +0000 (UTC) Received: from redhat.com (ovpn-116-32.ams2.redhat.com [10.36.116.32]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id u3I9wFdf016092; Mon, 18 Apr 2016 05:58:16 -0400 Date: Mon, 18 Apr 2016 12:58:14 +0300 From: "Michael S. Tsirkin" To: linux-kernel@vger.kernel.org Message-ID: <1460973374-32719-2-git-send-email-mst@redhat.com> References: <1460973374-32719-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1460973374-32719-1-git-send-email-mst@redhat.com> X-Mutt-Fcc: =sent X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH RFC 1/3] virtio: add features for IOMMU control X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Wei Liu , kvm@vger.kernel.org, Jason Wang , qemu-devel@nongnu.org, virtualization@lists.linux-foundation.org, Christian Borntraeger , Alex Williamson , Andy Lutomirski , Cornelia Huck , David Woodhouse Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The interaction between virtio and DMA API is messy. On most systems with virtio, physical addresses match bus addresses, and it doesn't particularly matter whether we use the DMA API. On some systems, including Xen and any system with a physical device that speaks virtio behind a physical IOMMU, we must use the DMA API for virtio DMA to work at all. Add a feature bit to detect that: VIRTIO_F_IOMMU_PLATFORM. On other systems, including SPARC and PPC64, virtio-pci devices are enumerated as though they are behind an IOMMU, but the virtio host ignores the IOMMU, so we must either pretend that the IOMMU isn't there or somehow map everything as the identity. Add a feature bit for that as well: VIRTIO_F_IOMMU_PASSTHROUGH: without VIRTIO_F_IOMMU_PLATFORM, it means that virtio will bypass the IOMMU. With VIRTIO_F_IOMMU_PLATFORM, it suggests that guest maps everything as the identity (this last bit isn't trivial to implement so ignore this hint for now). If not there, we preserve historic behavior and bypass the DMA API unless within Xen guest. Signed-off-by: Michael S. Tsirkin --- include/uapi/linux/virtio_config.h | 10 +++++++++- drivers/virtio/virtio_ring.c | 18 +++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/virtio_config.h b/include/uapi/linux/virtio_config.h index 4cb65bb..952775c 100644 --- a/include/uapi/linux/virtio_config.h +++ b/include/uapi/linux/virtio_config.h @@ -49,7 +49,7 @@ * transport being used (eg. virtio_ring), the rest are per-device feature * bits. */ #define VIRTIO_TRANSPORT_F_START 28 -#define VIRTIO_TRANSPORT_F_END 33 +#define VIRTIO_TRANSPORT_F_END 35 #ifndef VIRTIO_CONFIG_NO_LEGACY /* Do we get callbacks when the ring is completely used, even if we've @@ -63,4 +63,12 @@ /* v1.0 compliant. */ #define VIRTIO_F_VERSION_1 32 +/* Request IOMMU passthrough (if available) + * Without VIRTIO_F_IOMMU_PLATFORM: bypass the IOMMU even if enabled. + * With VIRTIO_F_IOMMU_PLATFORM: suggest disabling IOMMU. + */ +#define VIRTIO_F_IOMMU_PASSTHROUGH 33 + +/* Do not bypass the IOMMU (if configured) */ +#define VIRTIO_F_IOMMU_PLATFORM 34 #endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */ diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 5c802d4..0436bd2 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -117,7 +117,10 @@ struct vring_virtqueue { #define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq) /* - * The interaction between virtio and a possible IOMMU is a mess. + * Modern virtio devices might set feature bits to specify whether + * they use or unconditionally bypass the platform IOMMU. + * + * If not there, the interaction between virtio and DMA API is messy. * * On most systems with virtio, physical addresses match bus addresses, * and it doesn't particularly matter whether we use the DMA API. @@ -137,6 +140,13 @@ struct vring_virtqueue { static bool vring_use_dma_api(struct virtio_device *vdev) { + if (virtio_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) + return true; + + if (virtio_has_feature(vdev, VIRTIO_F_IOMMU_PASSTHROUGH)) + return false; + + /* Otherwise, we are left to guess. */ /* * In theory, it's possible to have a buggy QEMU-supposed * emulated Q35 IOMMU and Xen enabled at the same time. On @@ -1099,6 +1109,12 @@ void vring_transport_features(struct virtio_device *vdev) break; case VIRTIO_F_VERSION_1: break; + case VIRTIO_F_IOMMU_PASSTHROUGH: + break; + case VIRTIO_F_IOMMU_PLATFORM: + /* Ignore passthrough hint for now, obey kernel config. */ + __virtio_clear_bit(vdev, VIRTIO_F_IOMMU_PASSTHROUGH); + break; default: /* We don't understand this bit. */ __virtio_clear_bit(vdev, i);