From patchwork Tue Jul 15 09:24:35 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 369896 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 88889140116 for ; Tue, 15 Jul 2014 19:33:05 +1000 (EST) Received: from ozlabs.org (ozlabs.org [103.22.144.67]) by lists.ozlabs.org (Postfix) with ESMTP id 746871A0DD2 for ; Tue, 15 Jul 2014 19:33:05 +1000 (EST) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from e23smtp06.au.ibm.com (e23smtp06.au.ibm.com [202.81.31.148]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 450F61A01A3 for ; Tue, 15 Jul 2014 19:24:55 +1000 (EST) Received: from /spool/local by e23smtp06.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 15 Jul 2014 19:24:54 +1000 Received: from d23dlp02.au.ibm.com (202.81.31.213) by e23smtp06.au.ibm.com (202.81.31.212) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 15 Jul 2014 19:24:52 +1000 Received: from d23relay04.au.ibm.com (d23relay04.au.ibm.com [9.190.234.120]) by d23dlp02.au.ibm.com (Postfix) with ESMTP id ABE2B2BB0040 for ; Tue, 15 Jul 2014 19:24:51 +1000 (EST) Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.235.139]) by d23relay04.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s6F985Xv63045748 for ; Tue, 15 Jul 2014 19:08:05 +1000 Received: from d23av04.au.ibm.com (localhost [127.0.0.1]) by d23av04.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s6F9OoUU025342 for ; Tue, 15 Jul 2014 19:24:50 +1000 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.190.163.12]) by d23av04.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id s6F9OokU025337; Tue, 15 Jul 2014 19:24:50 +1000 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.190.164.82]) by ozlabs.au.ibm.com (Postfix) with ESMTP id 35734A027E; Tue, 15 Jul 2014 19:24:50 +1000 (EST) Received: from ka1.ozlabs.ibm.com (ka1.ozlabs.ibm.com [10.61.145.11]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 94D7016AB76; Tue, 15 Jul 2014 19:24:49 +1000 (EST) From: Alexey Kardashevskiy To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v1 11/16] powerpc/iommu: Extend ppc_md.tce_build(_rm) to return old TCE values Date: Tue, 15 Jul 2014 19:24:35 +1000 Message-Id: <1405416280-12318-12-git-send-email-aik@ozlabs.ru> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1405416280-12318-1-git-send-email-aik@ozlabs.ru> References: <1405416280-12318-1-git-send-email-aik@ozlabs.ru> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14071509-7014-0000-0000-00000549147C Cc: Alexey Kardashevskiy , Paul Mackerras , Gavin Shan X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" The tce_build/tce_build_rm callbacks are used to implement H_PUT_TCE/etc hypercalls. The PAPR spec does not allow to fail if the TCE is not empty. However we cannot just overwrite the existing TCE value with the new one as we still have to do page counting. This adds an optional @old_tces return parameter. If it is not NULL, it must point to an array of @npages size where the callbacks will store old TCE values. Since tce_build receives virtual addresses, the old_tces array will contain virtual addresses as well. As this patch is mechanical, no change in behaviour is expected. Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/include/asm/machdep.h | 2 ++ arch/powerpc/kernel/iommu.c | 8 +++++--- arch/powerpc/platforms/powernv/pci.c | 13 ++++++++----- arch/powerpc/platforms/pseries/iommu.c | 7 +++++-- arch/powerpc/sysdev/dart_iommu.c | 1 + 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index f92b0b5..f11596c 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -69,6 +69,7 @@ struct machdep_calls { long index, long npages, unsigned long uaddr, + unsigned long *old_tces, enum dma_data_direction direction, struct dma_attrs *attrs); void (*tce_free)(struct iommu_table *tbl, @@ -83,6 +84,7 @@ struct machdep_calls { long index, long npages, unsigned long uaddr, + long *old_tces, enum dma_data_direction direction, struct dma_attrs *attrs); void (*tce_free_rm)(struct iommu_table *tbl, diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 01ac319..ae57910 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -324,7 +324,8 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl, /* Put the TCEs in the HW table */ build_fail = ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & - IOMMU_PAGE_MASK(tbl), direction, attrs); + IOMMU_PAGE_MASK(tbl), NULL, direction, + attrs); /* ppc_md.tce_build() only returns non-zero for transient errors. * Clean up the table bitmap in this case and return @@ -497,7 +498,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, /* Insert into HW table */ build_fail = ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK(tbl), - direction, attrs); + NULL, direction, attrs); if(unlikely(build_fail)) goto failure; @@ -1056,7 +1057,8 @@ int iommu_tce_build(struct iommu_table *tbl, unsigned long entry, oldtce = ppc_md.tce_get(tbl, entry); /* Add new entry if it is not busy */ if (!(oldtce & (TCE_PCI_WRITE | TCE_PCI_READ))) - ret = ppc_md.tce_build(tbl, entry, 1, hwaddr, direction, NULL); + ret = ppc_md.tce_build(tbl, entry, 1, hwaddr, NULL, + direction, NULL); spin_unlock(&(pool->lock)); diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 09287c7..e002c66 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -568,7 +568,8 @@ static void pnv_tce_invalidate(struct iommu_table *tbl, __be64 *startp, } static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, - unsigned long uaddr, enum dma_data_direction direction, + unsigned long uaddr, unsigned long *old_tces, + enum dma_data_direction direction, struct dma_attrs *attrs, bool rm) { u64 proto_tce; @@ -593,12 +594,12 @@ static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, } static int pnv_tce_build_vm(struct iommu_table *tbl, long index, long npages, - unsigned long uaddr, + unsigned long uaddr, unsigned long *old_tces, enum dma_data_direction direction, struct dma_attrs *attrs) { - return pnv_tce_build(tbl, index, npages, uaddr, direction, attrs, - false); + return pnv_tce_build(tbl, index, npages, uaddr, old_tces, direction, + attrs, false); } static void pnv_tce_free(struct iommu_table *tbl, long index, long npages, @@ -626,10 +627,12 @@ static unsigned long pnv_tce_get(struct iommu_table *tbl, long index) static int pnv_tce_build_rm(struct iommu_table *tbl, long index, long npages, unsigned long uaddr, + long *old_tces, enum dma_data_direction direction, struct dma_attrs *attrs) { - return pnv_tce_build(tbl, index, npages, uaddr, direction, attrs, true); + return pnv_tce_build(tbl, index, npages, uaddr, old_tces, direction, + attrs, true); } static void pnv_tce_free_rm(struct iommu_table *tbl, long index, long npages) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index a047754..6c70b7c 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -82,6 +82,7 @@ static void tce_invalidate_pSeries_sw(struct iommu_table *tbl, static int tce_build_pSeries(struct iommu_table *tbl, long index, long npages, unsigned long uaddr, + unsigned long *old_tces, enum dma_data_direction direction, struct dma_attrs *attrs) { @@ -138,6 +139,7 @@ static void tce_freemulti_pSeriesLP(struct iommu_table*, long, long); static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages, unsigned long uaddr, + unsigned long *old_tces, enum dma_data_direction direction, struct dma_attrs *attrs) { @@ -181,6 +183,7 @@ static DEFINE_PER_CPU(__be64 *, tce_page); static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages, unsigned long uaddr, + unsigned long *old_tces, enum dma_data_direction direction, struct dma_attrs *attrs) { @@ -195,7 +198,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, if (npages == 1) { return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, - direction, attrs); + old_tces, direction, attrs); } local_irq_save(flags); /* to protect tcep and the page behind it */ @@ -211,7 +214,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, if (!tcep) { local_irq_restore(flags); return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, - direction, attrs); + old_tces, direction, attrs); } __get_cpu_var(tce_page) = tcep; } diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 9e5353f..0d3cf7c 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -162,6 +162,7 @@ static void dart_flush(struct iommu_table *tbl) static int dart_build(struct iommu_table *tbl, long index, long npages, unsigned long uaddr, + unsigned long *old_tces, enum dma_data_direction direction, struct dma_attrs *attrs) {