From patchwork Fri Mar 25 19:37:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: omar ramirez X-Patchwork-Id: 663131 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2PJcQ1t004183 for ; Fri, 25 Mar 2011 19:38:26 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754707Ab1CYTiI (ORCPT ); Fri, 25 Mar 2011 15:38:08 -0400 Received: from na3sys009aog109.obsmtp.com ([74.125.149.201]:44736 "EHLO na3sys009aog109.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753136Ab1CYTiG (ORCPT ); Fri, 25 Mar 2011 15:38:06 -0400 Received: from source ([74.125.82.45]) (using TLSv1) by na3sys009aob109.postini.com ([74.125.148.12]) with SMTP ID DSNKTYzvFTji6GtZiO1d6uKSkuQIGvswR8Kl@postini.com; Fri, 25 Mar 2011 12:38:05 PDT Received: by mail-ww0-f45.google.com with SMTP id 36so979880wwi.2 for ; Fri, 25 Mar 2011 12:37:55 -0700 (PDT) MIME-Version: 1.0 Received: by 10.227.139.72 with SMTP id d8mr1123275wbu.168.1301081875582; Fri, 25 Mar 2011 12:37:55 -0700 (PDT) Received: by 10.227.195.132 with HTTP; Fri, 25 Mar 2011 12:37:55 -0700 (PDT) In-Reply-To: <4D8CB106.7030608@maxwell.research.nokia.com> References: <4D8CB106.7030608@maxwell.research.nokia.com> Date: Fri, 25 Mar 2011 14:37:55 -0500 Message-ID: Subject: Re: [PATCH 0/4] iommu: Prevent oops in iommu_get() and while arch_iommu is in use From: "Ramirez Luna, Omar" To: Sakari Ailus Cc: "linux-omap@vger.kernel.org" , "Doyu Hiroshi (Nokia-D/Helsinki)" , Laurent Pinchart , Cohen David Abraham Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 25 Mar 2011 19:38:27 +0000 (UTC) diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index adb083e..ab2f9a9 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -341,15 +341,47 @@ static const struct iommu_functions omap2_iommu_ops = { .dump_ctx = omap2_iommu_dump_ctx, }; +/** + * install_iommu_arch - Install archtecure specific iommu functions + * @ops: a pointer to architecture specific iommu functions + * + * There are several kind of iommu algorithm(tlb, pagetable) among + * omap series. This interface installs such an iommu algorighm. + **/ +int install_iommu_arch(const struct iommu_functions **ops) +{ + if (*ops) + return -EBUSY; + *ops = &omap2_iommu_ops; + + return 0; +} +EXPORT_SYMBOL_GPL(install_iommu_arch); + +/** + * uninstall_iommu_arch - Uninstall archtecure specific iommu functions + * @ops: a pointer to architecture specific iommu functions + * + * This interface uninstalls the iommu algorighm installed previously. + **/ +void uninstall_iommu_arch(const struct iommu_functions **ops) +{ + if (*ops != &omap2_iommu_ops) + pr_err("%s: not your arch\n", __func__); + + *ops = NULL; +} +EXPORT_SYMBOL_GPL(uninstall_iommu_arch); + static int __init omap2_iommu_init(void) { - return install_iommu_arch(&omap2_iommu_ops); + return 0; } module_init(omap2_iommu_init); static void __exit omap2_iommu_exit(void) { - uninstall_iommu_arch(&omap2_iommu_ops); + /* Do nothing */ } module_exit(omap2_iommu_exit); diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 174f1b9..1c8e7ee 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -177,9 +177,6 @@ extern int iommu_set_isr(const char *name, extern void iommu_save_ctx(struct iommu *obj); extern void iommu_restore_ctx(struct iommu *obj); -extern int install_iommu_arch(const struct iommu_functions *ops); -extern void uninstall_iommu_arch(const struct iommu_functions *ops); - extern int foreach_iommu_device(void *data, int (*fn)(struct device *, void *)); diff --git a/arch/arm/plat-omap/include/plat/iommu2.h b/arch/arm/plat-omap/include/plat/iommu2.h index 10ad05f..8189f58 100644 --- a/arch/arm/plat-omap/include/plat/iommu2.h +++ b/arch/arm/plat-omap/include/plat/iommu2.h @@ -80,6 +80,9 @@ #define MMU_RAM_MIXED_MASK (1 << MMU_RAM_MIXED_SHIFT) #define MMU_RAM_MIXED MMU_RAM_MIXED_MASK +extern int install_iommu_arch(const struct iommu_functions **ops); +extern void uninstall_iommu_arch(const struct iommu_functions **ops); + /* * register accessors */ diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 8a51fd5..f088929 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -37,38 +37,6 @@ static struct platform_driver omap_iommu_driver; static struct kmem_cache *iopte_cachep; /** - * install_iommu_arch - Install archtecure specific iommu functions - * @ops: a pointer to architecture specific iommu functions - * - * There are several kind of iommu algorithm(tlb, pagetable) among - * omap series. This interface installs such an iommu algorighm. - **/ -int install_iommu_arch(const struct iommu_functions *ops) -{ - if (arch_iommu) - return -EBUSY; - - arch_iommu = ops; - return 0; -} -EXPORT_SYMBOL_GPL(install_iommu_arch); - -/** - * uninstall_iommu_arch - Uninstall archtecure specific iommu functions - * @ops: a pointer to architecture specific iommu functions - * - * This interface uninstalls the iommu algorighm installed previously. - **/ -void uninstall_iommu_arch(const struct iommu_functions *ops) -{ - if (arch_iommu != ops) - pr_err("%s: not your arch\n", __func__); - - arch_iommu = NULL; -} -EXPORT_SYMBOL_GPL(uninstall_iommu_arch); - -/** * iommu_save_ctx - Save registers for pm off-mode support * @obj: target iommu **/ @@ -1072,10 +1040,15 @@ static void iopte_cachep_ctor(void *iopte) static int __init omap_iommu_init(void) { + int err; struct kmem_cache *p; const unsigned long flags = SLAB_HWCACHE_ALIGN; size_t align = 1 << 10; /* L2 pagetable alignement */ + err = install_iommu_arch(&arch_iommu); + if (err) + return err; + p = kmem_cache_create("iopte_cache", IOPTE_TABLE_SIZE, align, flags, iopte_cachep_ctor); if (!p) @@ -1090,6 +1063,8 @@ static void __exit omap_iommu_exit(void) { kmem_cache_destroy(iopte_cachep); + uninstall_iommu_arch(&arch_iommu); + platform_driver_unregister(&omap_iommu_driver); } module_exit(omap_iommu_exit);