From patchwork Wed Mar 13 12:57:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pingfan Liu X-Patchwork-Id: 13591390 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 1AAE9C54E67 for ; Wed, 13 Mar 2024 13:00:50 +0000 (UTC) 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:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=izefFViaa+PI/WTPgGMwKFh0VpeG5PcQmf9VnJBy0sg=; b=cw9ZA87ym4Ih5v UpssKlUy5U5xQwp2VQz1dlOxPVRXc5R1yesW6jMDiinTS5aFpwWOVDfU3M6AxzsVAiCe3DZDdqfA8 OYY1TZD33+IYrGKO7w2dl2jv6WkCzNv32Z+d982HzrrNJo2C2dnE+2ovbbSmAOG1nAnh6GKEoGVpE UuB1PQN5hJxOgBT5PsBNK1shaW+4UbuaemNwmGAaUY+7iXyepoTGqkFk3RKKSduUPyF2bOG5CC5O0 2SoIgDqr4lSlvnyEo66HgGx8e+50QCtO6+RtHKYV9g+g7daiOTYdsB6WVyD3XEr+yTZLrSN9yJoYM ZGlI06C+JAMG1auPdyRA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rkODh-0000000A9VO-22zJ; Wed, 13 Mar 2024 13:00:33 +0000 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rkODb-0000000A9Rc-0ru3 for linux-arm-kernel@lists.infradead.org; Wed, 13 Mar 2024 13:00:29 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1710334826; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aG56RhtnSp32m8zSsqT06yRKajmUh0YjDAABkjKWEXk=; b=ezT8F1Msf62dwd3vHBpIvcUmQzjNYCjv3qOItjz+3me10Ad09VKaz4kiJmgTLdK9279/BC K+mvXsxviStplzBgXfqI6/pHyWETViz+zwrI07MSNBWRGy1kg6h2KgUKdZTnpUwWISKUQ6 dzOTSwf/UrNXOb7JrKBFJWW7vRo99HE= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-633-br_91FgdP8-84j-YrCw-CQ-1; Wed, 13 Mar 2024 08:57:36 -0400 X-MC-Unique: br_91FgdP8-84j-YrCw-CQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 58622185A784; Wed, 13 Mar 2024 12:57:36 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.72.112.95]) by smtp.corp.redhat.com (Postfix) with ESMTP id D79E610E47; Wed, 13 Mar 2024 12:57:33 +0000 (UTC) From: Pingfan Liu To: linux-arm-kernel@lists.infradead.org Cc: Pingfan Liu , Ard Biesheuvel , Catalin Marinas , Will Deacon , Mark Rutland Subject: [PATCH 03/10] arm64: mm: Use if-conditon to truncate external dependency Date: Wed, 13 Mar 2024 20:57:01 +0800 Message-ID: <20240313125711.20651-4-piliu@redhat.com> In-Reply-To: <20240313125711.20651-1-piliu@redhat.com> References: <20240313125711.20651-1-piliu@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240313_060027_465765_7F3F3DC4 X-CRM114-Status: GOOD ( 17.63 ) 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 An outside callee can present some challenging issues for the early boot stage, including posistion-dependent, instrumentation, alignment and sub-component not being ready. To mitigate these dependencies, leveraging compile-time optimization can help truncate reliance, ensuring that mmu_head is self-contained. Additionally, running checks against relocation and external dependencies in the Makefile can further enhance the robustness of the system. Signed-off-by: Pingfan Liu Cc: Ard Biesheuvel Cc: Catalin Marinas Cc: Will Deacon Cc: Mark Rutland To: linux-arm-kernel@lists.infradead.org --- arch/arm64/include/asm/pgtable.h | 11 +++++++++-- arch/arm64/mm/Makefile | 19 ++++++++++++++++++ arch/arm64/mm/mmu_head.c | 3 +++ arch/arm64/mm/mmu_inc.c | 33 ++++++++++++++++---------------- 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 79ce70fbb751..f43a93d78454 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -625,10 +625,17 @@ extern pgd_t reserved_pg_dir[PTRS_PER_PGD]; extern void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd); +#ifndef KERNEL_READY +#define KERNEL_READY true +#endif static inline bool in_swapper_pgdir(void *addr) { - return ((unsigned long)addr & PAGE_MASK) == - ((unsigned long)swapper_pg_dir & PAGE_MASK); + /* The compiling time optimization screens the calls to set_swapper_pgd() */ + if (KERNEL_READY) + return ((unsigned long)addr & PAGE_MASK) == + ((unsigned long)swapper_pg_dir & PAGE_MASK); + else + return false; } static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile index 0d92fb24a398..89d496ca970b 100644 --- a/arch/arm64/mm/Makefile +++ b/arch/arm64/mm/Makefile @@ -14,3 +14,22 @@ KASAN_SANITIZE_physaddr.o += n obj-$(CONFIG_KASAN) += kasan_init.o KASAN_SANITIZE_kasan_init.o := n + +$(obj)/mmu_head_tmp.o: $(src)/mmu_head.c FORCE + $(call if_changed_rule,cc_o_c) +OBJCOPYFLAGS_mmu_head.o := $(OBJCOPYFLAGS) +$(obj)/mmu_head.o: $(obj)/mmu_head_tmp.o FORCE + $(call if_changed,stubcopy) + +quiet_cmd_stubcopy = STUBCPY $@ + cmd_stubcopy = \ + $(STRIP) --strip-debug -o $@ $<; \ + if $(OBJDUMP) -r $@ | grep R_AARCH64_ABS; then \ + echo "$@: absolute symbol references not allowed in mmu_head.o" >&2; \ + /bin/false; \ + fi; \ + if nm -u $@ | grep "U"; then \ + echo "$@: external dependency incur uncertainty of alignment and not-PIC" >&2; \ + /bin/false; \ + fi; \ + $(OBJCOPY) $(OBJCOPYFLAGS) $< $@ diff --git a/arch/arm64/mm/mmu_head.c b/arch/arm64/mm/mmu_head.c index 4d65b7368db3..ccdd0f079c49 100644 --- a/arch/arm64/mm/mmu_head.c +++ b/arch/arm64/mm/mmu_head.c @@ -1,5 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only + +#define KERNEL_READY false + #include #include #include diff --git a/arch/arm64/mm/mmu_inc.c b/arch/arm64/mm/mmu_inc.c index 2535927d30ec..196987c120bf 100644 --- a/arch/arm64/mm/mmu_inc.c +++ b/arch/arm64/mm/mmu_inc.c @@ -81,7 +81,7 @@ static void INSTRUMENT_OPTION init_pte(pmd_t *pmdp, unsigned long addr, unsigned * After the PTE entry has been populated once, we * only allow updates to the permission attributes. */ - BUG_ON(!__pgattr_change_is_safe(pte_val(old_pte), + BUG_ON(KERNEL_READY && !__pgattr_change_is_safe(pte_val(old_pte), READ_ONCE(pte_val(*ptep)))); phys += PAGE_SIZE; @@ -99,19 +99,19 @@ static void INSTRUMENT_OPTION alloc_init_cont_pte(pmd_t *pmdp, unsigned long add unsigned long next; pmd_t pmd = READ_ONCE(*pmdp); - BUG_ON(pmd_sect(pmd)); + BUG_ON(KERNEL_READY && pmd_sect(pmd)); if (pmd_none(pmd)) { pmdval_t pmdval = PMD_TYPE_TABLE | PMD_TABLE_UXN; phys_addr_t pte_phys; if (flags & NO_EXEC_MAPPINGS) pmdval |= PMD_TABLE_PXN; - BUG_ON(!pgtable_alloc); + BUG_ON(KERNEL_READY && !pgtable_alloc); pte_phys = pgtable_alloc(PAGE_SHIFT); __pmd_populate(pmdp, pte_phys, pmdval); pmd = READ_ONCE(*pmdp); } - BUG_ON(pmd_bad(pmd)); + BUG_ON(KERNEL_READY && pmd_bad(pmd)); do { pgprot_t __prot = prot; @@ -151,14 +151,13 @@ static void INSTRUMENT_OPTION init_pmd(pud_t *pudp, unsigned long addr, unsigned * After the PMD entry has been populated once, we * only allow updates to the permission attributes. */ - BUG_ON(!__pgattr_change_is_safe(pmd_val(old_pmd), + BUG_ON(KERNEL_READY && !__pgattr_change_is_safe(pmd_val(old_pmd), READ_ONCE(pmd_val(*pmdp)))); } else { alloc_init_cont_pte(pmdp, addr, next, phys, prot, pgtable_alloc, flags); - - BUG_ON(pmd_val(old_pmd) != 0 && - pmd_val(old_pmd) != READ_ONCE(pmd_val(*pmdp))); + BUG_ON(KERNEL_READY && pmd_val(old_pmd) != 0 && + pmd_val(old_pmd) != READ_ONCE(pmd_val(*pmdp))); } phys += next - addr; } while (pmdp++, addr = next, addr != end); @@ -177,19 +176,19 @@ static void INSTRUMENT_OPTION alloc_init_cont_pmd(pud_t *pudp, unsigned long add /* * Check for initial section mappings in the pgd/pud. */ - BUG_ON(pud_sect(pud)); + BUG_ON(KERNEL_READY && pud_sect(pud)); if (pud_none(pud)) { pudval_t pudval = PUD_TYPE_TABLE | PUD_TABLE_UXN; phys_addr_t pmd_phys; if (flags & NO_EXEC_MAPPINGS) pudval |= PUD_TABLE_PXN; - BUG_ON(!pgtable_alloc); + BUG_ON(KERNEL_READY && !pgtable_alloc); pmd_phys = pgtable_alloc(PMD_SHIFT); __pud_populate(pudp, pmd_phys, pudval); pud = READ_ONCE(*pudp); } - BUG_ON(pud_bad(pud)); + BUG_ON(KERNEL_READY && pud_bad(pud)); do { pgprot_t __prot = prot; @@ -223,12 +222,12 @@ static void INSTRUMENT_OPTION alloc_init_pud(pgd_t *pgdp, unsigned long addr, un if (flags & NO_EXEC_MAPPINGS) p4dval |= P4D_TABLE_PXN; - BUG_ON(!pgtable_alloc); + BUG_ON(KERNEL_READY && !pgtable_alloc); pud_phys = pgtable_alloc(PUD_SHIFT); __p4d_populate(p4dp, pud_phys, p4dval); p4d = READ_ONCE(*p4dp); } - BUG_ON(p4d_bad(p4d)); + BUG_ON(KERNEL_READY && p4d_bad(p4d)); pudp = pud_set_fixmap_offset(p4dp, addr); do { @@ -248,14 +247,14 @@ static void INSTRUMENT_OPTION alloc_init_pud(pgd_t *pgdp, unsigned long addr, un * After the PUD entry has been populated once, we * only allow updates to the permission attributes. */ - BUG_ON(!__pgattr_change_is_safe(pud_val(old_pud), + BUG_ON(KERNEL_READY && !__pgattr_change_is_safe(pud_val(old_pud), READ_ONCE(pud_val(*pudp)))); } else { alloc_init_cont_pmd(pudp, addr, next, phys, prot, pgtable_alloc, flags); - BUG_ON(pud_val(old_pud) != 0 && - pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); + BUG_ON(KERNEL_READY && pud_val(old_pud) != 0 && + pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); } phys += next - addr; } while (pudp++, addr = next, addr != end); @@ -276,7 +275,7 @@ static void INSTRUMENT_OPTION __create_pgd_mapping_locked(pgd_t *pgdir, phys_add * If the virtual and physical address don't have the same offset * within a page, we cannot map the region as the caller expects. */ - if (WARN_ON((phys ^ virt) & ~PAGE_MASK)) + if (KERNEL_READY && WARN_ON((phys ^ virt) & ~PAGE_MASK)) return; phys &= PAGE_MASK;