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=-10.3 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A, SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 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 F3B72C4338F for ; Tue, 3 Aug 2021 11:26:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D6AC960555 for ; Tue, 3 Aug 2021 11:26:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235552AbhHCL01 (ORCPT ); Tue, 3 Aug 2021 07:26:27 -0400 Received: from foss.arm.com ([217.140.110.172]:47576 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235497AbhHCL01 (ORCPT ); Tue, 3 Aug 2021 07:26:27 -0400 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 EC3191396; Tue, 3 Aug 2021 04:26:15 -0700 (PDT) Received: from [10.163.67.68] (unknown [10.163.67.68]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 921433F40C; Tue, 3 Aug 2021 04:26:13 -0700 (PDT) Subject: Re: [PATCH] arm64/mm: Fix idmap on [16K|36VA|48PA] To: Catalin Marinas Cc: linux-arm-kernel@lists.infradead.org, Will Deacon , James Morse , Marc Zyngier , Mark Rutland , linux-kernel@vger.kernel.org References: <1627879359-30303-1-git-send-email-anshuman.khandual@arm.com> <20210803103440.GA5786@arm.com> From: Anshuman Khandual Message-ID: <7bad50a2-76f1-7946-3a15-35e46fb289c0@arm.com> Date: Tue, 3 Aug 2021 16:57:04 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <20210803103440.GA5786@arm.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 8/3/21 4:04 PM, Catalin Marinas wrote: > On Mon, Aug 02, 2021 at 10:12:39AM +0530, Anshuman Khandual wrote: >> When creating the idmap, the kernel may add one extra level to idmap memory >> outside the VA range. But for [16K|36VA|48PA], we need two levels to reach >> 48 bits. If the bootloader places the kernel in memory above (1 << 46), the > > Did you mean (1 << 36)? No it is actually (1 << 47). If __idmap_text_end is beyond (1 << 47), a single additional page table level in idmap would not be sufficient to map it. Rather two more levels would be required. A single additional page table level covers (PAGE_SHIFT - 3 = 14 - 3 = 11) bits on 16K pages. First additional page table level covers VA(36) --> (47) Second additional page table level covers VA(48) --> (48) > >> kernel will fail to enable the MMU. Although we are not aware of a platform >> where this happens, it is worth to accommodate such scenarios and prevent a >> possible kernel crash. >> >> Lets fix the problem on the above configuration by creating two additional >> idmap page table levels when 'idmap_text_end' is outside the VA range. This >> reduces 'idmap_t0sz' to cover the entire PA range which would prevent table >> misconfiguration (fault) when a given 'idmap_t0sz' value requires a single >> additional page table level where as two have been built. > [...] >> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S >> index c5c994a..da33bbc 100644 >> --- a/arch/arm64/kernel/head.S >> +++ b/arch/arm64/kernel/head.S >> @@ -329,7 +329,9 @@ SYM_FUNC_START_LOCAL(__create_page_tables) >> >> #if (VA_BITS < 48) >> #define EXTRA_SHIFT (PGDIR_SHIFT + PAGE_SHIFT - 3) >> +#define EXTRA_SHIFT_1 (EXTRA_SHIFT + PAGE_SHIFT - 3) >> #define EXTRA_PTRS (1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT)) >> +#define EXTRA_PTRS_1 (1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT_1)) >> >> /* >> * If VA_BITS < 48, we have to configure an additional table level. >> @@ -342,8 +344,30 @@ SYM_FUNC_START_LOCAL(__create_page_tables) >> #error "Mismatch between VA_BITS and page size/number of translation levels" >> #endif >> >> +/* >> + * In this particular CONFIG_ARM64_16K_PAGES config, there might be a >> + * scenario where 'idmap_text_end' ends up high enough in the PA range >> + * requiring two additional idmap page table levels. Reduce idmap_t0sz >> + * to cover the entire PA range. This prevents table misconfiguration >> + * when a given idmap_t0sz value just requires single additional level >> + * where as two levels have been built. >> + */ >> +#if defined(CONFIG_ARM64_VA_BITS_36) && defined(CONFIG_ARM64_PA_BITS_48) >> + mov x4, EXTRA_PTRS_1 >> + create_table_entry x0, x3, EXTRA_SHIFT_1, x4, x5, x6 >> + >> + mov x4, PTRS_PER_PTE >> + create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6 >> + >> + mov x5, #64 - PHYS_MASK_SHIFT >> + adr_l x6, idmap_t0sz >> + str x5, [x6] >> + dmb sy >> + dc ivac, x6 >> +#else >> mov x4, EXTRA_PTRS >> create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6 >> +#endif >> #else >> /* >> * If VA_BITS == 48, we don't have to configure an additional > > There's a prior idmap_t0sz setting based on __idmap_text_end. Isn't that > sufficient? We don't care about covering the whole PA space, just the > __idmap_text_end. Right but its bit tricky here. __idmap_text_end could be any where between VA_BITS (36) and PA_BITS (48) which would require (one or two) additional page table levels. But in this solution it creates two additional page table levels for idmap which would completely map upto PA_BITS, regardless of __idmap_text_end's position. So in case __idmap_text_end is between VA_BITS (36) and VA_BITS(47), a single additional page table level is required where as we have created two ! So to avoid such a situation, adjust idmap_t0sz accordingly. Otherwise there will be a MMU mis-configuration. This patch is indented for stable back port and hence tries to be as simple and minimal as possible. So it creates two additional page table levels mapping upto PA_BITS without just considering __idmap_text_end's position. Reducing __idmap_t0sz upto PA_BITS should not be a problem irrespective of ID_AA64MMFR0_EL1.PARANGE value. As __idmap_text_end would never be on a PA which is not supported. Hence out of range PA would never be on the bus for translation. 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=-11.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=unavailable 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 C9296C4338F for ; Tue, 3 Aug 2021 11:28:26 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 8D3D460EBC for ; Tue, 3 Aug 2021 11:28:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 8D3D460EBC Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date: Message-ID:From:References:Cc:To:Subject:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=BFU+Lqzzm1P0m76qBNEcQWu4W5rvDs9EiK+vnlY3QZs=; b=mIQ3wRNTT09gIcIdqOliVj/79u X7/W6a3BjkAKVlgxsM0763RSk4MCyzO8Y+cQYRl7J04kWGkh99HIiNMnAmhXVo+EJ18aIP5O5j4l5 SjkxTywGDbT/vdThOAsQFOscFFDx75yyiEF5A3paEznzJ3pnMmBeZjLDEHwkbCzO1sox1Y985HreY jpnwe4j05FpE28qligA4Fc1ubM2oqCtdPCIUUBBJrzyRwMjbN2IxnhBH/in6cv5Z9SDK9Ha+BsjE7 d07bQNs5QajkN9gz0BC8WoQJXorhXKUcpJUoerL3gS2+qwgkaBwgq627t7XyPO8otIYHFGVC5NkmI 8Yptl4pw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mAsYw-002GNJ-Eq; Tue, 03 Aug 2021 11:26:22 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mAsYr-002GMo-QL for linux-arm-kernel@lists.infradead.org; Tue, 03 Aug 2021 11:26:19 +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 EC3191396; Tue, 3 Aug 2021 04:26:15 -0700 (PDT) Received: from [10.163.67.68] (unknown [10.163.67.68]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 921433F40C; Tue, 3 Aug 2021 04:26:13 -0700 (PDT) Subject: Re: [PATCH] arm64/mm: Fix idmap on [16K|36VA|48PA] To: Catalin Marinas Cc: linux-arm-kernel@lists.infradead.org, Will Deacon , James Morse , Marc Zyngier , Mark Rutland , linux-kernel@vger.kernel.org References: <1627879359-30303-1-git-send-email-anshuman.khandual@arm.com> <20210803103440.GA5786@arm.com> From: Anshuman Khandual Message-ID: <7bad50a2-76f1-7946-3a15-35e46fb289c0@arm.com> Date: Tue, 3 Aug 2021 16:57:04 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <20210803103440.GA5786@arm.com> Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210803_042618_006382_1C4F747C X-CRM114-Status: GOOD ( 23.83 ) 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 8/3/21 4:04 PM, Catalin Marinas wrote: > On Mon, Aug 02, 2021 at 10:12:39AM +0530, Anshuman Khandual wrote: >> When creating the idmap, the kernel may add one extra level to idmap memory >> outside the VA range. But for [16K|36VA|48PA], we need two levels to reach >> 48 bits. If the bootloader places the kernel in memory above (1 << 46), the > > Did you mean (1 << 36)? No it is actually (1 << 47). If __idmap_text_end is beyond (1 << 47), a single additional page table level in idmap would not be sufficient to map it. Rather two more levels would be required. A single additional page table level covers (PAGE_SHIFT - 3 = 14 - 3 = 11) bits on 16K pages. First additional page table level covers VA(36) --> (47) Second additional page table level covers VA(48) --> (48) > >> kernel will fail to enable the MMU. Although we are not aware of a platform >> where this happens, it is worth to accommodate such scenarios and prevent a >> possible kernel crash. >> >> Lets fix the problem on the above configuration by creating two additional >> idmap page table levels when 'idmap_text_end' is outside the VA range. This >> reduces 'idmap_t0sz' to cover the entire PA range which would prevent table >> misconfiguration (fault) when a given 'idmap_t0sz' value requires a single >> additional page table level where as two have been built. > [...] >> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S >> index c5c994a..da33bbc 100644 >> --- a/arch/arm64/kernel/head.S >> +++ b/arch/arm64/kernel/head.S >> @@ -329,7 +329,9 @@ SYM_FUNC_START_LOCAL(__create_page_tables) >> >> #if (VA_BITS < 48) >> #define EXTRA_SHIFT (PGDIR_SHIFT + PAGE_SHIFT - 3) >> +#define EXTRA_SHIFT_1 (EXTRA_SHIFT + PAGE_SHIFT - 3) >> #define EXTRA_PTRS (1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT)) >> +#define EXTRA_PTRS_1 (1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT_1)) >> >> /* >> * If VA_BITS < 48, we have to configure an additional table level. >> @@ -342,8 +344,30 @@ SYM_FUNC_START_LOCAL(__create_page_tables) >> #error "Mismatch between VA_BITS and page size/number of translation levels" >> #endif >> >> +/* >> + * In this particular CONFIG_ARM64_16K_PAGES config, there might be a >> + * scenario where 'idmap_text_end' ends up high enough in the PA range >> + * requiring two additional idmap page table levels. Reduce idmap_t0sz >> + * to cover the entire PA range. This prevents table misconfiguration >> + * when a given idmap_t0sz value just requires single additional level >> + * where as two levels have been built. >> + */ >> +#if defined(CONFIG_ARM64_VA_BITS_36) && defined(CONFIG_ARM64_PA_BITS_48) >> + mov x4, EXTRA_PTRS_1 >> + create_table_entry x0, x3, EXTRA_SHIFT_1, x4, x5, x6 >> + >> + mov x4, PTRS_PER_PTE >> + create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6 >> + >> + mov x5, #64 - PHYS_MASK_SHIFT >> + adr_l x6, idmap_t0sz >> + str x5, [x6] >> + dmb sy >> + dc ivac, x6 >> +#else >> mov x4, EXTRA_PTRS >> create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6 >> +#endif >> #else >> /* >> * If VA_BITS == 48, we don't have to configure an additional > > There's a prior idmap_t0sz setting based on __idmap_text_end. Isn't that > sufficient? We don't care about covering the whole PA space, just the > __idmap_text_end. Right but its bit tricky here. __idmap_text_end could be any where between VA_BITS (36) and PA_BITS (48) which would require (one or two) additional page table levels. But in this solution it creates two additional page table levels for idmap which would completely map upto PA_BITS, regardless of __idmap_text_end's position. So in case __idmap_text_end is between VA_BITS (36) and VA_BITS(47), a single additional page table level is required where as we have created two ! So to avoid such a situation, adjust idmap_t0sz accordingly. Otherwise there will be a MMU mis-configuration. This patch is indented for stable back port and hence tries to be as simple and minimal as possible. So it creates two additional page table levels mapping upto PA_BITS without just considering __idmap_text_end's position. Reducing __idmap_t0sz upto PA_BITS should not be a problem irrespective of ID_AA64MMFR0_EL1.PARANGE value. As __idmap_text_end would never be on a PA which is not supported. Hence out of range PA would never be on the bus for translation. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel