From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 87EAEC433ED for ; Wed, 12 May 2021 10:01:40 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D39FD61221 for ; Wed, 12 May 2021 10:01:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D39FD61221 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References:Message-ID: Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=G8rh52L+gapI32HHSoIlO4HY1tNzcO1xBUrEWpDaxGo=; b=JuufPQ1ateLg+85uVvZhWDBoL wLntnMPZe1hID2/5hWkH+YNKAG0qySBVWjytoTDJHFGosyPIulkh9cwtOKhZjidH/AXM6j1KD/ciF Xg8MUUn2Uy1P9PriQLLyK8CLZZDCpM5HzpUSRI8OuVJkLlsm6fnmeXCiFkD48uOlD9zi89fHl5R5S 4Ijaclv/9WMJjtz2o7rNvP126qeuw020uDg6OQWfV3nTngT2KkNzMdp6hIvoEAy9eeeAugF5Q8SNB Eg3JN45f1hhOsxaK7gnHIeCLQgHxqJ+3AI06Po0Tmog8BomEBt7XkjtJKpPlbgG71PkvslLTxQ7A0 LCx0Y5Cnw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lglez-002U3w-Fm; Wed, 12 May 2021 10:00:09 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lgleu-002U3j-54 for linux-arm-kernel@desiato.infradead.org; Wed, 12 May 2021 10:00:04 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=In-Reply-To:Content-Type:MIME-Version :References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=fW9cwXhxNyiDRGsdAaQg9cQeUf74UhzQJD1EpjmHGqc=; b=4T87VlcfLAgplEOuSufNCiOOUR rBosp4O4f/Q64gsl+50oi+kEz23n8hVycuyp/CmjGxZ3HJW4OWtwT2O255LuCGBEh93sPy7UzdNyl CtDsGYBeYJuXfkD52nVs3PBo4e27+p1V+sm1tIoVDKalYzek2aF5EgHm53gb8BrtbSXEtGuKY1Hz7 9phI32tkfOVaVlcM53cRa5D2gGfQdAcsDoK1FV+a3cKL/vYafH+Px65hwvZ7fTHwuJSLP5Ch+WNWr lt9GqsRm+FUqw7T839PDJDHoyuZsKVHY2gs0ZH+IV2W3oAuQ6b42uCLZSPWbz3X5StAEhdtfsWjjh AJlgUnVw==; Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lgleq-00AGvT-Lk for linux-arm-kernel@lists.infradead.org; Wed, 12 May 2021 10:00:02 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 98AECED1; Wed, 12 May 2021 02:59:52 -0700 (PDT) Received: from C02TD0UTHF1T.local (unknown [10.57.30.106]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EBAE03F719; Wed, 12 May 2021 02:59:49 -0700 (PDT) Date: Wed, 12 May 2021 10:59:35 +0100 From: Mark Rutland To: Fuad Tabba Cc: "moderated list:ARM64 PORT (AARCH64 ARCHITECTURE)" , Will Deacon , Catalin Marinas , Marc Zyngier , ardb@kernel.org, James Morse , Alexandru Elisei , Suzuki K Poulose Subject: Re: [PATCH v1 01/13] arm64: Do not enable uaccess for flush_icache_range Message-ID: <20210512095935.GA88854@C02TD0UTHF1T.local> References: <20210511144252.3779113-1-tabba@google.com> <20210511144252.3779113-2-tabba@google.com> <20210511152255.GD8933@C02TD0UTHF1T.local> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210512_030000_857547_0CBDF757 X-CRM114-Status: GOOD ( 40.92 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Wed, May 12, 2021 at 09:52:28AM +0100, Fuad Tabba wrote: > Hi Mark, > > > > No functional change intended. > > > > There is a performance change here, since the existing > > `__flush_cache_user_range` takes IDC and DIC into account, whereas > > `invalidate_icache_by_line` does not. > > You're right. There is a performance change in this patch and a couple > of the others, which I will note in v2. However, I don't think that > this patch changes the behavior when it comes to IDC and DIC, does it? It shouldn't be a functional problem, but it means that the new `__flush_icache_range` will always perform redundant I-cache maintenance rather than skipping this when the cpu has DIC=1. It would be nice if we could structure this to take DIC into account either in the new `__flush_icache_range`, or in the `invalidate_icache_by_line` helper. > > There's also an existing oversight where `__flush_cache_user_range` > > takes ARM64_WORKAROUND_CLEAN_CACHE into account, but > > `invalidate_icache_by_line` does not. Sorry about this. I was evidently confused, as this does not make any sense. This doesn't matter to `invalidate_icache_by_line`, and `invalidate_dcache_by_line` already does the right thing via `__dcache_op_workaround_clean_cache`. > I'd be happy to address that in v2, but let me make sure I understand > the issue properly. > > Errata 819472 and friends (ARM64_WORKAROUND_CLEAN_CACHE) are related > to cache maintenance operations on data caches happening concurrently > with other accesses to the same address. The two places > invalidate_icache_by_line is used in conjunction with data caches are > __flush_icache_range and __flush_cache_user_range (which share the > same code before and after my patch series). In both cases, > invalidate_icache_by_line is called after the workaround is applied. > The third and only other user of invalidate_icache_by_line is > invalidate_icache_range, which only performs cache maintenance on the > icache. > > The concern is that invalidate_icache_range might be performing a > cache maintenance operation on an address concurrently with another > processor performing a dc operation on the same address. Therefore, > invalidate_icache_range should perform DC CIVAC on the line before > invalidate_icache_by_line if ARM64_WORKAROUND_CLEAN_CACHE applies. Is > that right? > > https://documentation-service.arm.com/static/5fa29fddb209f547eebd361d Sorry, I had misread the code, and I don't think there's a bug to fix here after all. Regardless, thanks for digging into that and trying to make sense of my bogus suggestion. > > Arguably similar is true in `swsusp_arch_suspend_exit`, but for that > > we could add a comment and always use `DC CIVAC`. > > I can do that in v2 as well. A separate patch for `swsusp_arch_suspend_exit` would be great, since that is something we should backport to stable as a fix. Thanks, Mark. > > > Reported-by: Catalin Marinas > > > Reported-by: Will Deacon > > > Link: https://lore.kernel.org/linux-arch/20200511110014.lb9PEahJ4hVOYrbwIb_qUHXyNy9KQzNFdb_I3YlzY6A@z/ > > > Signed-off-by: Fuad Tabba > > > --- > > > arch/arm64/include/asm/assembler.h | 13 ++++-- > > > arch/arm64/mm/cache.S | 64 +++++++++++++++++++++--------- > > > 2 files changed, 54 insertions(+), 23 deletions(-) > > > > > > diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h > > > index 8418c1bd8f04..6ff7a3a3b238 100644 > > > --- a/arch/arm64/include/asm/assembler.h > > > +++ b/arch/arm64/include/asm/assembler.h > > > @@ -426,16 +426,21 @@ alternative_endif > > > * Macro to perform an instruction cache maintenance for the interval > > > * [start, end) > > > * > > > - * start, end: virtual addresses describing the region > > > - * label: A label to branch to on user fault. > > > - * Corrupts: tmp1, tmp2 > > > + * start, end: virtual addresses describing the region > > > + * needs_uaccess: might access user space memory > > > + * label: label to branch to on user fault (if needs_uaccess) > > > + * Corrupts: tmp1, tmp2 > > > */ > > > - .macro invalidate_icache_by_line start, end, tmp1, tmp2, label > > > + .macro invalidate_icache_by_line start, end, tmp1, tmp2, needs_uaccess, label > > > icache_line_size \tmp1, \tmp2 > > > sub \tmp2, \tmp1, #1 > > > bic \tmp2, \start, \tmp2 > > > 9997: > > > + .if \needs_uaccess > > > USER(\label, ic ivau, \tmp2) // invalidate I line PoU > > > + .else > > > + ic ivau, \tmp2 > > > + .endif > > > add \tmp2, \tmp2, \tmp1 > > > cmp \tmp2, \end > > > b.lo 9997b > > > diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S > > > index 2d881f34dd9d..092f73acdf9a 100644 > > > --- a/arch/arm64/mm/cache.S > > > +++ b/arch/arm64/mm/cache.S > > > @@ -15,30 +15,20 @@ > > > #include > > > > > > /* > > > - * flush_icache_range(start,end) > > > + * __flush_cache_range(start,end) [needs_uaccess] > > > * > > > * Ensure that the I and D caches are coherent within specified region. > > > * This is typically used when code has been written to a memory region, > > > * and will be executed. > > > * > > > - * - start - virtual start address of region > > > - * - end - virtual end address of region > > > + * - start - virtual start address of region > > > + * - end - virtual end address of region > > > + * - needs_uaccess - (macro parameter) might access user space memory > > > */ > > > -SYM_FUNC_START(__flush_icache_range) > > > - /* FALLTHROUGH */ > > > - > > > -/* > > > - * __flush_cache_user_range(start,end) > > > - * > > > - * Ensure that the I and D caches are coherent within specified region. > > > - * This is typically used when code has been written to a memory region, > > > - * and will be executed. > > > - * > > > - * - start - virtual start address of region > > > - * - end - virtual end address of region > > > - */ > > > -SYM_FUNC_START(__flush_cache_user_range) > > > +.macro __flush_cache_range, needs_uaccess > > > + .if \needs_uaccess > > > uaccess_ttbr0_enable x2, x3, x4 > > > + .endif > > > alternative_if ARM64_HAS_CACHE_IDC > > > dsb ishst > > > b 7f > > > @@ -47,7 +37,11 @@ alternative_else_nop_endif > > > sub x3, x2, #1 > > > bic x4, x0, x3 > > > 1: > > > + .if \needs_uaccess > > > user_alt 9f, "dc cvau, x4", "dc civac, x4", ARM64_WORKAROUND_CLEAN_CACHE > > > + .else > > > +alternative_insn "dc cvau, x4", "dc civac, x4", ARM64_WORKAROUND_CLEAN_CACHE > > > + .endif > > > add x4, x4, x2 > > > cmp x4, x1 > > > b.lo 1b > > > @@ -58,15 +52,47 @@ alternative_if ARM64_HAS_CACHE_DIC > > > isb > > > b 8f > > > alternative_else_nop_endif > > > - invalidate_icache_by_line x0, x1, x2, x3, 9f > > > + invalidate_icache_by_line x0, x1, x2, x3, \needs_uaccess, 9f > > > 8: mov x0, #0 > > > 1: > > > + .if \needs_uaccess > > > uaccess_ttbr0_disable x1, x2 > > > + .endif > > > ret > > > + > > > + .if \needs_uaccess > > > 9: > > > mov x0, #-EFAULT > > > b 1b > > > + .endif > > > +.endm > > > + > > > +/* > > > + * flush_icache_range(start,end) > > > + * > > > + * Ensure that the I and D caches are coherent within specified region. > > > + * This is typically used when code has been written to a memory region, > > > + * and will be executed. > > > + * > > > + * - start - virtual start address of region > > > + * - end - virtual end address of region > > > + */ > > > +SYM_FUNC_START(__flush_icache_range) > > > + __flush_cache_range needs_uaccess=0 > > > SYM_FUNC_END(__flush_icache_range) > > > + > > > +/* > > > + * __flush_cache_user_range(start,end) > > > + * > > > + * Ensure that the I and D caches are coherent within specified region. > > > + * This is typically used when code has been written to a memory region, > > > + * and will be executed. > > > + * > > > + * - start - virtual start address of region > > > + * - end - virtual end address of region > > > + */ > > > +SYM_FUNC_START(__flush_cache_user_range) > > > + __flush_cache_range needs_uaccess=1 > > > SYM_FUNC_END(__flush_cache_user_range) > > > > > > /* > > > @@ -86,7 +112,7 @@ alternative_else_nop_endif > > > > > > uaccess_ttbr0_enable x2, x3, x4 > > > > > > - invalidate_icache_by_line x0, x1, x2, x3, 2f > > > + invalidate_icache_by_line x0, x1, x2, x3, 1, 2f > > > mov x0, xzr > > > 1: > > > uaccess_ttbr0_disable x1, x2 > > > -- > > > 2.31.1.607.g51e8a6a459-goog > > > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel