Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752621AbbDQKQV (ORCPT ); Fri, 17 Apr 2015 06:16:21 -0400 Received: from mail-pd0-f170.google.com ([209.85.192.170]:35865 "EHLO mail-pd0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750744AbbDQKQU (ORCPT ); Fri, 17 Apr 2015 06:16:20 -0400 Message-ID: <5530DD6D.8000001@ozlabs.ru> Date: Fri, 17 Apr 2015 20:16:13 +1000 From: Alexey Kardashevskiy User-Agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: David Gibson CC: linuxppc-dev@lists.ozlabs.org, Benjamin Herrenschmidt , Paul Mackerras , Alex Williamson , linux-kernel@vger.kernel.org Subject: Re: [PATCH kernel v8 15/31] powerpc/iommu: Fix IOMMU ownership control functions References: <1428647473-11738-1-git-send-email-aik@ozlabs.ru> <1428647473-11738-16-git-send-email-aik@ozlabs.ru> <20150416061049.GF3632@voom.redhat.com> In-Reply-To: <20150416061049.GF3632@voom.redhat.com> Content-Type: text/plain; charset=koi8-r; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3401 Lines: 108 On 04/16/2015 04:10 PM, David Gibson wrote: > On Fri, Apr 10, 2015 at 04:30:57PM +1000, Alexey Kardashevskiy wrote: >> This adds missing locks in iommu_take_ownership()/ >> iommu_release_ownership(). >> >> This marks all pages busy in iommu_table::it_map in order to catch >> errors if there is an attempt to use this table while ownership over it >> is taken. >> >> This only clears TCE content if there is no page marked busy in it_map. >> Clearing must be done outside of the table locks as iommu_clear_tce() >> called from iommu_clear_tces_and_put_pages() does this. >> >> Signed-off-by: Alexey Kardashevskiy >> --- >> Changes: >> v5: >> * do not store bit#0 value, it has to be set for zero-based table >> anyway >> * removed test_and_clear_bit >> --- >> arch/powerpc/kernel/iommu.c | 26 ++++++++++++++++++++++---- >> 1 file changed, 22 insertions(+), 4 deletions(-) >> >> diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c >> index 7d6089b..068fe4ff 100644 >> --- a/arch/powerpc/kernel/iommu.c >> +++ b/arch/powerpc/kernel/iommu.c >> @@ -1052,17 +1052,28 @@ EXPORT_SYMBOL_GPL(iommu_tce_build); >> >> static int iommu_table_take_ownership(struct iommu_table *tbl) >> { >> - unsigned long sz = (tbl->it_size + 7) >> 3; >> + unsigned long flags, i, sz = (tbl->it_size + 7) >> 3; >> + int ret = 0; >> + >> + spin_lock_irqsave(&tbl->large_pool.lock, flags); >> + for (i = 0; i < tbl->nr_pools; i++) >> + spin_lock(&tbl->pools[i].lock); >> >> if (tbl->it_offset == 0) >> clear_bit(0, tbl->it_map); >> >> if (!bitmap_empty(tbl->it_map, tbl->it_size)) { >> pr_err("iommu_tce: it_map is not empty"); >> - return -EBUSY; >> + ret = -EBUSY; >> + if (tbl->it_offset == 0) >> + set_bit(0, tbl->it_map); > > This really needs a comment. Why on earth are you changing the it_map > on a failure case? Does this explain? /* * The platform code reserves zero address in iommu_init_table(). * As we cleared busy bit for page @0 before using bitmap_empty(), * we are restoring it now. */ > >> + } else { >> + memset(tbl->it_map, 0xff, sz); >> } >> >> - memset(tbl->it_map, 0xff, sz); >> + for (i = 0; i < tbl->nr_pools; i++) >> + spin_unlock(&tbl->pools[i].lock); >> + spin_unlock_irqrestore(&tbl->large_pool.lock, flags); >> >> return 0; >> } >> @@ -1095,7 +1106,11 @@ EXPORT_SYMBOL_GPL(iommu_take_ownership); >> >> static void iommu_table_release_ownership(struct iommu_table *tbl) >> { >> - unsigned long sz = (tbl->it_size + 7) >> 3; >> + unsigned long flags, i, sz = (tbl->it_size + 7) >> 3; >> + >> + spin_lock_irqsave(&tbl->large_pool.lock, flags); >> + for (i = 0; i < tbl->nr_pools; i++) >> + spin_lock(&tbl->pools[i].lock); >> >> memset(tbl->it_map, 0, sz); >> >> @@ -1103,6 +1118,9 @@ static void iommu_table_release_ownership(struct iommu_table *tbl) >> if (tbl->it_offset == 0) >> set_bit(0, tbl->it_map); >> >> + for (i = 0; i < tbl->nr_pools; i++) >> + spin_unlock(&tbl->pools[i].lock); >> + spin_unlock_irqrestore(&tbl->large_pool.lock, flags); >> } >> >> extern void iommu_release_ownership(struct iommu_table_group *table_group) > -- Alexey -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/