From patchwork Mon Oct 14 10:58:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Roberts X-Patchwork-Id: 13834921 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id D208ED16252 for ; Mon, 14 Oct 2024 12:27:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=OACUuu7EkK/bVx0oPSFpoAc1oPx/wt8iZOtMNIFSzjQ=; b=pPgtLORaWSyr4cSjoQUaY+m02o s+J+lsloOjQa+2Hl1yMe8bk4c2OefxjlYiqh1q98Fr4f5Tk8JbhDgHKDvlLuQXV75doa9Ktonmgqs wU0SvqKEIq5pfnX3GS91lHRSOvrtW66J/gFe2vW+7DP2kQT7NwMnDFtiwmYTaRH0+L2p0CigwwrnB 0IRap2zg4ytUbH394iwzq9q+OvwUfKX74UAH6fjb7kQJA3x+ZIejowqP/JcQh+Rp+lf1Qo84rVsSi e8BiKDnng2+c3etKV/rrW/hh+W1mBkC3cuXgWb3x9Tg3fDRpVx5dG350+pyHsGiytyOHFwMzkHSML PwcT9SmA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1t0KAR-000000054o8-0Bd6; Mon, 14 Oct 2024 12:27:19 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1t0Ipe-00000004oWr-0afB for linux-arm-kernel@lists.infradead.org; Mon, 14 Oct 2024 11:01:48 +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 5E6BA1764; Mon, 14 Oct 2024 04:02:15 -0700 (PDT) Received: from e125769.cambridge.arm.com (e125769.cambridge.arm.com [10.1.196.27]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5FBE13F51B; Mon, 14 Oct 2024 04:01:43 -0700 (PDT) From: Ryan Roberts To: Andrew Morton , Anshuman Khandual , Ard Biesheuvel , Catalin Marinas , David Hildenbrand , Greg Marsden , Ivan Ivanov , Kalesh Singh , Marc Zyngier , Mark Rutland , Matthias Brugger , Miroslav Benes , Will Deacon Cc: Ryan Roberts , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [RFC PATCH v1 45/57] arm64: Rework trampoline rodata mapping Date: Mon, 14 Oct 2024 11:58:52 +0100 Message-ID: <20241014105912.3207374-45-ryan.roberts@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241014105912.3207374-1-ryan.roberts@arm.com> References: <20241014105514.3206191-1-ryan.roberts@arm.com> <20241014105912.3207374-1-ryan.roberts@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20241014_040146_366337_C1B1B19E X-CRM114-Status: GOOD ( 19.45 ) 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: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Now that the trampoline rodata is aligned to the next PAGE_SIZE_MAX boundary after the end of the trampoline text, the code that maps it in the fixmap is incorrect, because it still assumes the rodata is in the next page immediately after the text. Of course it still works for now with compile-time page size but for boot-time page size when selecting a page size less than PAGE_SIZE_MAX, it will fail. So let's fix that by allocating sufficient fixmap slots to cover the extra alignment padding in the worst case (PAGE_SIZE == PAGE_SIZE_MIN) and explicitly mapping the rodata to the slot offset correctly from the text. Signed-off-by: Ryan Roberts --- ***NOTE*** Any confused maintainers may want to read the cover note here for context: https://lore.kernel.org/all/20241014105514.3206191-1-ryan.roberts@arm.com/ arch/arm64/include/asm/fixmap.h | 16 +++++++++++----- arch/arm64/include/asm/sections.h | 1 + arch/arm64/kernel/vmlinux.lds.S | 4 +++- arch/arm64/mm/mmu.c | 22 ++++++++++++++-------- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h index 87e307804b99c..9a496d54dfe6e 100644 --- a/arch/arm64/include/asm/fixmap.h +++ b/arch/arm64/include/asm/fixmap.h @@ -59,13 +59,19 @@ enum fixed_addresses { #endif /* CONFIG_ACPI_APEI_GHES */ #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 +#define TRAMP_TEXT_SIZE (PAGE_SIZE_MIN * 3) #ifdef CONFIG_RELOCATABLE - FIX_ENTRY_TRAMP_TEXT4, /* one extra slot for the data page */ +#define TRAMP_DATA_SIZE PAGE_SIZE_MIN +#define TRAMP_PAD_SIZE (PAGE_SIZE_MAX - PAGE_SIZE_MIN) +#else +#define TRAMP_DATA_SIZE 0 +#define TRAMP_PAD_SIZE 0 #endif - FIX_ENTRY_TRAMP_TEXT3, - FIX_ENTRY_TRAMP_TEXT2, - FIX_ENTRY_TRAMP_TEXT1, -#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT1)) +#define TRAMP_SIZE (TRAMP_TEXT_SIZE + TRAMP_DATA_SIZE + TRAMP_PAD_SIZE) + FIX_ENTRY_TRAMP_END, + FIX_ENTRY_TRAMP_BEGIN = FIX_ENTRY_TRAMP_END + + DIV_ROUND_UP(TRAMP_SIZE, PAGE_SIZE_MIN) - 1, +#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_BEGIN)) #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ __end_of_permanent_fixed_addresses, diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h index 40971ac1303f9..252ec58963093 100644 --- a/arch/arm64/include/asm/sections.h +++ b/arch/arm64/include/asm/sections.h @@ -21,6 +21,7 @@ extern char __exittext_begin[], __exittext_end[]; extern char __irqentry_text_start[], __irqentry_text_end[]; extern char __mmuoff_data_start[], __mmuoff_data_end[]; extern char __entry_tramp_text_start[], __entry_tramp_text_end[]; +extern char __entry_tramp_rodata_start[], __entry_tramp_rodata_end[]; extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[]; static inline size_t entry_tramp_text_size(void) diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 1ef6dea13b57c..09fcc234c0f77 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -118,7 +118,9 @@ jiffies = jiffies_64; *(.entry.tramp.text) \ __entry_tramp_text_end = .; \ . = ALIGN(PAGE_SIZE_MAX); \ - *(.entry.tramp.rodata) + __entry_tramp_rodata_start = .; \ + *(.entry.tramp.rodata) \ + __entry_tramp_rodata_end = .; #else #define TRAMP_TEXT #endif diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index a528787c1e550..84df9f278d24d 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -734,25 +734,31 @@ static int __init map_entry_trampoline(void) return 0; pgprot_t prot = kernel_exec_prot(); - phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start); + phys_addr_t pa_text = __pa_symbol(__entry_tramp_text_start); + phys_addr_t pa_data = __pa_symbol(__entry_tramp_rodata_start); + int slot = FIX_ENTRY_TRAMP_BEGIN; /* The trampoline is always mapped and can therefore be global */ pgprot_val(prot) &= ~PTE_NG; /* Map only the text into the trampoline page table */ memset(tramp_pg_dir, 0, PGD_SIZE); - __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, + __create_pgd_mapping(tramp_pg_dir, pa_text, TRAMP_VALIAS, entry_tramp_text_size(), prot, __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS); /* Map both the text and data into the kernel page table */ - for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++) - __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, - pa_start + i * PAGE_SIZE, prot); + for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++) { + __set_fixmap(slot, pa_text, prot); + pa_text += PAGE_SIZE; + slot--; + } - if (IS_ENABLED(CONFIG_RELOCATABLE)) - __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, - pa_start + i * PAGE_SIZE, PAGE_KERNEL_RO); + if (IS_ENABLED(CONFIG_RELOCATABLE)) { + slot -= (pa_data - pa_text) / PAGE_SIZE; + VM_BUG_ON(slot < FIX_ENTRY_TRAMP_END); + __set_fixmap(slot, pa_data, PAGE_KERNEL_RO); + } return 0; }