From patchwork Thu Feb 20 16:21:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 25070 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yh0-f69.google.com (mail-yh0-f69.google.com [209.85.213.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 22DF3203C6 for ; Thu, 20 Feb 2014 16:22:32 +0000 (UTC) Received: by mail-yh0-f69.google.com with SMTP id a41sf1172686yho.4 for ; Thu, 20 Feb 2014 08:22:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=sIKxP+47HG3S9UOAXjY9T1K+DWSfw5Ym8M7Txn9wLF8=; b=fwMSOUvfP2YYQvHq6SCdUi1feqT7ZL9xAUUkATXPH+p50IvCP036RUKV8Ymqzxv1KZ BT+XoQdqLYmHGsDQRHX4PnBPEOIYCS6vcFExvraF67PVxEmtd94A96bTKCDWVQYpU94h 4pq87LBNQPSWWTz+saEvCVeXIYIS6ZF+OYelIYE4UQiMC2DuDKRCfuXvLml8n6j4yrT/ atQeC4pb8tXStCRnITYxLJ1k7yUE9n6Sc3qh1bZz9ZTihNdBZ53jso6UOQ3AfyyareI6 C3JptkUDgdfizrfB5hUaNkIXnkk8lbiZIlJwXj6eLozKYV7p6U1nRFd6rMG5uzYtg0L1 wfuQ== X-Gm-Message-State: ALoCoQncazjaceJ1u4C89ccLTCEgEWlpMvJyCrA0m4hLS9RWLSe6mA8ORI4wTCWTWSVRCCXcPJK4 X-Received: by 10.236.86.77 with SMTP id v53mr937505yhe.41.1392913351846; Thu, 20 Feb 2014 08:22:31 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.86.51 with SMTP id o48ls572504qgd.83.gmail; Thu, 20 Feb 2014 08:22:31 -0800 (PST) X-Received: by 10.220.175.16 with SMTP id v16mr1503007vcz.72.1392913351702; Thu, 20 Feb 2014 08:22:31 -0800 (PST) Received: from mail-ve0-f178.google.com (mail-ve0-f178.google.com [209.85.128.178]) by mx.google.com with ESMTPS id cp10si1650247ved.96.2014.02.20.08.22.31 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 20 Feb 2014 08:22:31 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.178 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.178; Received: by mail-ve0-f178.google.com with SMTP id oy12so2058590veb.37 for ; Thu, 20 Feb 2014 08:22:31 -0800 (PST) X-Received: by 10.52.164.39 with SMTP id yn7mr1235102vdb.25.1392913351582; Thu, 20 Feb 2014 08:22:31 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.174.196 with SMTP id u4csp70657vcz; Thu, 20 Feb 2014 08:22:31 -0800 (PST) X-Received: by 10.68.143.196 with SMTP id sg4mr2951976pbb.155.1392913350676; Thu, 20 Feb 2014 08:22:30 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id mp8si4178098pbc.82.2014.02.20.08.22.29; Thu, 20 Feb 2014 08:22:29 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755350AbaBTQWW (ORCPT + 26 others); Thu, 20 Feb 2014 11:22:22 -0500 Received: from mail-ee0-f43.google.com ([74.125.83.43]:47107 "EHLO mail-ee0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754469AbaBTQWV (ORCPT ); Thu, 20 Feb 2014 11:22:21 -0500 Received: by mail-ee0-f43.google.com with SMTP id e51so947913eek.16 for ; Thu, 20 Feb 2014 08:22:20 -0800 (PST) X-Received: by 10.15.45.131 with SMTP id b3mr2656585eew.105.1392913340060; Thu, 20 Feb 2014 08:22:20 -0800 (PST) Received: from belegaer.uk.xensource.com. ([185.25.64.249]) by mx.google.com with ESMTPSA id j41sm15524543eeg.10.2014.02.20.08.22.17 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 20 Feb 2014 08:22:19 -0800 (PST) From: Julien Grall To: linux-kernel@vger.kernel.org, stefano.stabellini@eu.citrix.com Cc: linux-arm-kernel@lists.infradead.org, ian.campbell@citrix.com, xen-devel@lists.xenproject.org, Julien Grall , Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , Rob Landley , Russell King , devicetree@vger.kernel.org Subject: [PATCH 2/2] arm/xen: Don't use xen DMA ops when the device is protected by an IOMMU Date: Thu, 20 Feb 2014 16:21:41 +0000 Message-Id: <1392913301-25524-1-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 1.7.10.4 Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: julien.grall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.178 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Only Xen is able to know if a device can safely avoid to use xen-swiotlb. This patch introduce a new property "protected-devices" for the hypervisor node which list device which the IOMMU are been correctly programmed by Xen. During Linux boot, Xen specific code will create an hash table which contains all these devices. The hash table will be used in need_xen_dma_ops to check if the Xen DMA ops needs to be used for the current device. Signed-off-by: Julien Grall Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: Rob Landley Cc: Russell King Cc: devicetree@vger.kernel.org --- Documentation/devicetree/bindings/arm/xen.txt | 2 + arch/arm/include/asm/xen/dma-mapping.h | 11 +++- arch/arm/xen/enlighten.c | 75 +++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/xen.txt b/Documentation/devicetree/bindings/arm/xen.txt index 0f7b9c2..ee25a57 100644 --- a/Documentation/devicetree/bindings/arm/xen.txt +++ b/Documentation/devicetree/bindings/arm/xen.txt @@ -15,6 +15,8 @@ the following properties: - interrupts: the interrupt used by Xen to inject event notifications. A GIC node is also required. +- protected-devices: (optional) List of phandles to device node where the +IOMMU has been programmed by Xen. Example (assuming #address-cells = <2> and #size-cells = <2>): diff --git a/arch/arm/include/asm/xen/dma-mapping.h b/arch/arm/include/asm/xen/dma-mapping.h index 002fc57..da8e4fe 100644 --- a/arch/arm/include/asm/xen/dma-mapping.h +++ b/arch/arm/include/asm/xen/dma-mapping.h @@ -5,9 +5,18 @@ extern struct dma_map_ops *xen_dma_ops; +#ifdef CONFIG_XEN +bool xen_is_protected_device(const struct device *dev); +#else +static inline bool xen_is_protected_device(const struct device *dev) +{ + return 0; +} +#endif + static inline bool need_xen_dma_ops(struct device *dev) { - return xen_initial_domain(); + return xen_initial_domain() && !xen_is_protected_device(dev); } #endif /* _ASM_ARM_XEN_DMA_MAPPING_H */ diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index b96723e..f124c8c 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -53,6 +54,42 @@ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug); static __read_mostly int xen_events_irq = -1; +/* Hash table for list of devices protected by an IOMMU in Xen */ +#define DEV_HASH_BITS 4 +#define DEV_HASH_SIZE (1 << DEV_HASH_BITS) + +static struct hlist_head *protected_devices; + +struct protected_device +{ + struct hlist_node hlist; + struct device_node *node; +}; + +static unsigned long pdev_hash(const struct device_node *node) +{ + return (node->phandle % DEV_HASH_SIZE); +} + +bool xen_is_protected_device(const struct device *dev) +{ + const struct device_node *node = dev->of_node; + unsigned long hash; + const struct protected_device *pdev; + + if (!node->phandle) + return 0; + + hash = pdev_hash(node); + + hlist_for_each_entry(pdev, &protected_devices[hash], hlist) { + if (node == pdev->node) + return 1; + } + + return 0; +} + /* map fgmfn of domid to lpfn in the current domain */ static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn, unsigned int domid) @@ -235,6 +272,8 @@ static int __init xen_guest_init(void) const char *xen_prefix = "xen,xen-"; struct resource res; phys_addr_t grant_frames; + int i = 0; + struct device_node *dev; node = of_find_compatible_node(NULL, NULL, "xen,xen"); if (!node) { @@ -259,6 +298,31 @@ static int __init xen_guest_init(void) if (xen_events_irq < 0) return -ENODEV; + protected_devices = kmalloc(DEV_HASH_SIZE * sizeof (*protected_devices), + GFP_KERNEL); + if (!protected_devices) + return -ENOMEM; + + for (i = 0; i < DEV_HASH_SIZE; i++) + INIT_HLIST_HEAD(&protected_devices[i]); + + pr_info("List of protected devices:\n"); + i = 0; + while ((dev = of_parse_phandle(node, "protected-devices", i))) { + struct protected_device *pdev; + unsigned long hash; + + pr_info(" - %s\n", of_node_full_name(dev)); + pdev = kmalloc(sizeof (*pdev), GFP_KERNEL); + if (!pdev) + goto free_hash; + + pdev->node = dev; + hash = pdev_hash(dev); + hlist_add_head(&pdev->hlist, &protected_devices[hash]); + i++; + } + xen_domain_type = XEN_HVM_DOMAIN; xen_setup_features(); @@ -324,6 +388,17 @@ static int __init xen_guest_init(void) register_cpu_notifier(&xen_cpu_notifier); return 0; +free_hash: + for (i = 0; i < DEV_HASH_SIZE; i++) { + struct protected_device *pdev; + struct hlist_node *next; + + hlist_for_each_entry_safe(pdev, next, &protected_devices[i], + hlist) + kfree(pdev); + } + kfree(protected_devices); + return -ENOMEM; } early_initcall(xen_guest_init);