Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp3953269yba; Tue, 9 Apr 2019 08:08:19 -0700 (PDT) X-Google-Smtp-Source: APXvYqwzEKo0xIv1vDDxv72hDGqP++lPVDuqv8Ypr7FljoFq4ByAZqYtP3F0d9duN3T8ytWFk1CJ X-Received: by 2002:a62:b40b:: with SMTP id h11mr37532856pfn.133.1554822499123; Tue, 09 Apr 2019 08:08:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1554822499; cv=none; d=google.com; s=arc-20160816; b=NRITnKE5qzuINaoRsjfWgBZ5lz/Acq3ExIEA5ChIABViiRrJ4vP1dBPbmKGBAZCgGw OdVhGnmLaaiEosPmgJLnZjJyC/73mBpEcc6D7LmLHgoeOVTd6i0k1DrqG86R1FhUhgL/ Pl6z1lzmqrIMwgogSgsyVeF9YR6P7dJodJxuZtiRRpF7q0DY/UlKZE3poMctB0Jq+pYM NHNpgYf3zUZJ/fFFjRKcawGiuFkgJhyVwBspRlkHwP3oFj3QsJuaOLav8Aten7OZxq+8 atTqcXxjneAKPibBNo48O76HHeYxYS1i1pOUajJPsu0LC+uLIFfNCKTn63w/v0kJ2VHe RX+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=wk13X7iTHVwIlk6LQakUf8sVr244ULzoJ684mB+trHo=; b=Pqqqizr68gpqHZYx34tVBa2xjw4MYlrGQnuRgu+s6dyu4Sh8HVU/BjltPOLIMHs0Sd kZF0sZ9/Uy8/P52TDLgrw0wPwmCLI2MNMX73k8vUcNu3kZytnh66mzls0yQ9Bb/+uJ42 qnqlV7T7FsxMgrGde34Jgybis9LCDUf+BhhRPppNINRLAG4zmJEEgzmLiiQ6er7Rlp6x vJpUXWDd+RGrE2JrYfg/ii2AWQ9EVc0dLx1B6Mu4qRStV6xycmHOL+If+ebxp8yXHzT7 VYhdtD1dSrxxbDK7UQD0DwhPXuvM6KCqDdwxr/A8Q6PF2ZKB2dRK6BF8uKmPxVDeaxmR S4sA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p88si29435405pfi.142.2019.04.09.08.08.02; Tue, 09 Apr 2019 08:08:19 -0700 (PDT) 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; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726582AbfDIPHG (ORCPT + 99 others); Tue, 9 Apr 2019 11:07:06 -0400 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:39634 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726456AbfDIPHG (ORCPT ); Tue, 9 Apr 2019 11:07:06 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0957515AB; Tue, 9 Apr 2019 08:07:06 -0700 (PDT) Received: from [10.1.196.75] (e110467-lin.cambridge.arm.com [10.1.196.75]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9E2413F68F; Tue, 9 Apr 2019 08:07:04 -0700 (PDT) Subject: Re: [PATCH 07/21] dma-iommu: move the arm64 wrappers to common code To: Christoph Hellwig Cc: Joerg Roedel , Catalin Marinas , Will Deacon , Tom Lendacky , iommu@lists.linux-foundation.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org References: <20190327080448.5500-1-hch@lst.de> <20190327080448.5500-8-hch@lst.de> From: Robin Murphy Message-ID: <67573dd3-72c7-692d-bc1a-7edb49ff9551@arm.com> Date: Tue, 9 Apr 2019 16:07:02 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 In-Reply-To: <20190327080448.5500-8-hch@lst.de> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-GB Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 27/03/2019 08:04, Christoph Hellwig wrote: [...] > @@ -649,19 +696,44 @@ static dma_addr_t __iommu_dma_map(struct device *dev, phys_addr_t phys, > return iova + iova_off; > } > > -dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page, > +static dma_addr_t __iommu_dma_map_page(struct device *dev, struct page *page, > unsigned long offset, size_t size, int prot) > { > return __iommu_dma_map(dev, page_to_phys(page) + offset, size, prot, > iommu_get_dma_domain(dev)); > } > > -void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size, > - enum dma_data_direction dir, unsigned long attrs) > +static void __iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, > + size_t size, enum dma_data_direction dir, unsigned long attrs) > { > __iommu_dma_unmap(iommu_get_dma_domain(dev), handle, size); > } > > +static dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page, > + unsigned long offset, size_t size, enum dma_data_direction dir, > + unsigned long attrs) > +{ > + phys_addr_t phys = page_to_phys(page) + offset; > + bool coherent = dev_is_dma_coherent(dev); > + dma_addr_t dma_handle; > + > + dma_handle =__iommu_dma_map(dev, phys, size, > + dma_info_to_prot(dir, coherent, attrs), > + iommu_get_dma_domain(dev)); > + if (!coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC) && > + dma_handle != DMA_MAPPING_ERROR) > + arch_sync_dma_for_device(dev, phys, size, dir); > + return dma_handle; > +} > + > +static void iommu_dma_unmap_page(struct device *dev, dma_addr_t dma_handle, > + size_t size, enum dma_data_direction dir, unsigned long attrs) > +{ > + if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) > + iommu_dma_sync_single_for_cpu(dev, dma_handle, size, dir); > + __iommu_dma_unmap(iommu_get_domain_for_dev(dev), dma_handle, size); That wants to be iommu_get_dma_domain() there to minimise the overhead. In fact, I guess this could now be streamlined a bit in the style of iommu_dma_map_page() above - i.e. avoid doing a second domain lookup in the sync case - but that can happen later (if indeed you haven't already). > +} > + > /* > * Prepare a successfully-mapped scatterlist to give back to the caller. > * [...] > @@ -843,12 +923,257 @@ dma_addr_t iommu_dma_map_resource(struct device *dev, phys_addr_t phys, > iommu_get_dma_domain(dev)); > } > > -void iommu_dma_unmap_resource(struct device *dev, dma_addr_t handle, > +static void iommu_dma_unmap_resource(struct device *dev, dma_addr_t handle, > size_t size, enum dma_data_direction dir, unsigned long attrs) > { > __iommu_dma_unmap(iommu_get_dma_domain(dev), handle, size); > } > > +static void *iommu_dma_alloc(struct device *dev, size_t size, > + dma_addr_t *handle, gfp_t gfp, unsigned long attrs) > +{ > + bool coherent = dev_is_dma_coherent(dev); > + int ioprot = dma_info_to_prot(DMA_BIDIRECTIONAL, coherent, attrs); > + size_t iosize = size; > + void *addr; > + > + size = PAGE_ALIGN(size); > + > + /* > + * Some drivers rely on this, and we probably don't want the > + * possibility of stale kernel data being read by devices anyway. > + */ That comment can probably be dropped now that zeroing is official API behaviour. > + gfp |= __GFP_ZERO; [...] > +/* > + * The IOMMU core code allocates the default DMA domain, which the underlying > + * IOMMU driver needs to support via the dma-iommu layer. > + */ > +void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, > + const struct iommu_ops *ops) There's really no need to even pass @ops in here - in the existing arm64 logic it's merely a token representing "should I do IOMMU setup?", and after this refactoring that's already been decided by our caller here. > +{ > + struct iommu_domain *domain = iommu_get_domain_for_dev(dev); > + > + if (!domain || domain->type != IOMMU_DOMAIN_DMA) This change means we now spam the logs with spurious warnings when configured for passthrough, which is not what we want. > + goto out_err; > + if (iommu_dma_init_domain(domain, dma_base, size, dev)) > + goto out_err; > + > + dev->dma_ops = &iommu_dma_ops; > + return; > +out_err: > + pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n", > + dev_name(dev)); > +} > + > static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, > phys_addr_t msi_addr, struct iommu_domain *domain) > { > @@ -921,3 +1246,5 @@ void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) > msg->address_lo += lower_32_bits(msi_page->iova); > } > } > + > +arch_initcall(iova_cache_get); This feels a bit funky - TBH I'd rather just keep iommu_dma_init() around and make it static, if only for the sake of looking "normal". [...] > -static inline int iommu_dma_init(void) > +static inline void iommu_setup_dma_ops(struct device *dev, u64 dma_base, > + u64 size, const struct iommu_ops *ops) > { > - return 0; > } I don't think it makes sense to have a stub for that - AFAICS it should only ever be called form arch code with an inherent "select IOMMU_DMA" (much like the stuff which isn't stubbed currently). Otherwise, I'm about 97% sure the rest of the move looks OK - thanks for splitting things up. Robin. > > static inline int iommu_get_dma_cookie(struct iommu_domain *domain) >