From patchwork Mon May 31 08:45:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pingfan Liu X-Patchwork-Id: 12288911 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=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT 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 1279AC47096 for ; Mon, 31 May 2021 08:48:40 +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 CC9D960FEE for ; Mon, 31 May 2021 08:48:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CC9D960FEE Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.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=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=NO1jfQblCVM3lIbCu/jTdwoHgNRwko06dtpW4ZkJ8OU=; b=rt3zo8ymLe5XQf yk7g4JK9SWEv9CzRn0PFpAPW0fONhkFl022VmtVMYJJt+DIwwhYXEe4uIvuMwGh2R2DdKxa69bBew IghavhXfDej1du72Oyu4AmPenpJINHpjBF/AnWTVnF6SvgeGd7kempD46mJ1P88dCHPH41rFXSSGP 5Sc8DAfw9FvGG4hqWqIMtqODCptwd0HxojFcLL0Vl/eYYO2oIsz9+g56kha37TjgMlE3C92CNroVT e17l8fz0IUA8luXmu4cvD4jdxEmZ09pdhMDGFgwmXXWhOXeXZu6lz4eXpmzcBpZFJarG1HjnY2p4E 6c9dnfYo5Ey97dRWPqjw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1lndZF-00BWB2-FW; Mon, 31 May 2021 08:46:37 +0000 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1lndYy-00BW9m-La for linux-arm-kernel@lists.infradead.org; Mon, 31 May 2021 08:46:22 +0000 Received: by mail-pj1-x1032.google.com with SMTP id 22-20020a17090a0c16b0290164a5354ad0so945815pjs.2 for ; Mon, 31 May 2021 01:46:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2F86xve07XA7uY1FsbnVFLtV22c4Q57gB5yrbCwHOc4=; b=UnrcLB8bLa1eaU6ZB1j4Br+m2s5fCISs5QA0ZzKOWgJ5jGo5Kza902/xRGM0MYm02K FLP0b9sKGbKCDlKE5Nzl/l7dTtTWClXmttrvB0CwPj/iII6eINU3QLUl4cX6GN53AbIf bCs4Kb5ear5ZPwf3MAJaUwzkUTnVm2VWOE4KU4aaiun7tMQPICHQ5zVN3716it7xJWK9 8eWbwMYcndaBBYJRSejPYSVtPXe5zxttcJxWEYUvFDDLNNNgvC7JnHFOHlz3K8qhlONh jQ3g5A4q83+RY3czffV39RLA3UIzKDLQTpb68iEAFP+XclnugrUCj8MKmTNrxVU3bH8C QbQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2F86xve07XA7uY1FsbnVFLtV22c4Q57gB5yrbCwHOc4=; b=WlTICbIDKYNNkDcoTAJ9AtlwusZMPcdgJpyHy2fcHpNyAh/xEu6gdVJwulwdf74B/p QGQEWicJ9CPDPKJJ5tA1KHK0R51nCeeYSY33H8qQ8/uSWkpZVJLJCD/X8zdUpylia714 nhmfKba5rmLdEgSln1uNXRt66fCxF8GJxpG6IDEuGe9Y4vS6/EN+MbTKwhTTKfOD+CGb 2DNZNPiz90XIUrPldU0MDY8Mkqzs27QfpQpVuiurTeHe1bVg4eRqlaWg+GmQ6xOGNPNe gtIa0AaL/OmdOrmd6DsP5BohUT9XJL34ENmfqiqjrqTNM5HOubpT/qAhjeiYNuyUiY05 3xWA== X-Gm-Message-State: AOAM533YTNt42WNheQJ2nnugmiHA4JvJyasgN+Ljn2YybmSmQ73u8bDq IYor13RLqIntQRxrgWhw24tLmGiJNexuPOE= X-Google-Smtp-Source: ABdhPJyzNhYZQp/0j9tklWJpgprZFB6KYspaPyLBT7aVtdP7N0gg9S/C7SEgLeDALPUEpJmf5+F4pA== X-Received: by 2002:a17:90a:520f:: with SMTP id v15mr17794149pjh.23.1622450779476; Mon, 31 May 2021 01:46:19 -0700 (PDT) Received: from qualcomm-amberwing-rep-18.khw4.lab.eng.bos.redhat.com (nat-pool-bos-t.redhat.com. [66.187.233.206]) by smtp.gmail.com with ESMTPSA id fs24sm5125677pjb.6.2021.05.31.01.46.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 May 2021 01:46:19 -0700 (PDT) From: Pingfan Liu To: linux-arm-kernel@lists.infradead.org Cc: Pingfan Liu , Catalin Marinas , Will Deacon , Ard Biesheuvel , Marc Zyngier , Kristina Martsenko , James Morse , Steven Price , Jonathan Cameron , Pavel Tatashin , Anshuman Khandual , Atish Patra , Mike Rapoport , Logan Gunthorpe , Mark Brown Subject: [PATCHv3 2/5] arm64/mm: disable WARN_ON() and BUG_ON() in __create_pgd_mapping() if too early Date: Mon, 31 May 2021 04:45:37 -0400 Message-Id: <20210531084540.78546-3-kernelfans@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210531084540.78546-1-kernelfans@gmail.com> References: <20210531084540.78546-1-kernelfans@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210531_014620_737790_B59B2530 X-CRM114-Status: GOOD ( 17.79 ) 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 This patch is still one of the preparation for calling __create_pgd_mapping() from head.S When calling from head.S, printk() is not ready to work. Hence define SAFE_BUG_ON()/SAFE_WARN_ON(), wrapping around BUG_ON()/WARN_ON() to protect against early calling. Signed-off-by: Pingfan Liu Cc: Catalin Marinas Cc: Will Deacon Cc: Ard Biesheuvel Cc: Marc Zyngier Cc: Kristina Martsenko Cc: James Morse Cc: Steven Price Cc: Jonathan Cameron Cc: Pavel Tatashin Cc: Anshuman Khandual Cc: Atish Patra Cc: Mike Rapoport Cc: Logan Gunthorpe Cc: Mark Brown To: linux-arm-kernel@lists.infradead.org --- arch/arm64/mm/mmu.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index f4fc905718ca..fe16f235d1fa 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -40,6 +40,7 @@ #define NO_BLOCK_MAPPINGS BIT(0) #define NO_CONT_MAPPINGS BIT(1) #define NO_EXEC_MAPPINGS BIT(2) /* assumes FEAT_HPDS is not used */ +#define BOOT_HEAD BIT(3) u64 idmap_t0sz = TCR_T0SZ(VA_BITS_MIN); u64 idmap_ptrs_per_pgd = PTRS_PER_PGD; @@ -139,6 +140,15 @@ static phys_addr_t __init early_pgtable_alloc(int shift) return phys; } +/* + * printk is not ready in the very early stage. And this pair macro should be used + * instead + */ +#define SAFE_BUG_ON(flags, cond) \ + do { if (likely(!(flags & BOOT_HEAD))) BUG_ON(cond); } while (0) +#define SAFE_WARN_ON(flags, cond) \ + ({ (flags & BOOT_HEAD) ? false : WARN_ON(cond); }) + static bool pgattr_change_is_safe(u64 old, u64 new) { /* @@ -174,7 +184,7 @@ static bool pgattr_change_is_safe(u64 old, u64 new) } static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end, - phys_addr_t phys, pgprot_t prot) + phys_addr_t phys, pgprot_t prot, int flags) { pte_t *ptep; @@ -188,7 +198,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end, * 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), + SAFE_BUG_ON(flags, !pgattr_change_is_safe(pte_val(old_pte), READ_ONCE(pte_val(*ptep)))); phys += PAGE_SIZE; @@ -206,19 +216,19 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, unsigned long next; pmd_t pmd = READ_ONCE(*pmdp); - BUG_ON(pmd_sect(pmd)); + SAFE_BUG_ON(flags, 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); + SAFE_BUG_ON(flags, !pgtable_alloc); pte_phys = pgtable_alloc(PAGE_SHIFT); __pmd_populate(pmdp, pte_phys, pmdval); pmd = READ_ONCE(*pmdp); } - BUG_ON(pmd_bad(pmd)); + SAFE_BUG_ON(flags, pmd_bad(pmd)); do { pgprot_t __prot = prot; @@ -230,7 +240,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, (flags & NO_CONT_MAPPINGS) == 0) __prot = __pgprot(pgprot_val(prot) | PTE_CONT); - init_pte(pmdp, addr, next, phys, __prot); + init_pte(pmdp, addr, next, phys, __prot, flags); phys += next - addr; } while (addr = next, addr != end); @@ -258,13 +268,13 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end, * 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), + SAFE_BUG_ON(flags, !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 && + SAFE_BUG_ON(flags, pmd_val(old_pmd) != 0 && pmd_val(old_pmd) != READ_ONCE(pmd_val(*pmdp))); } phys += next - addr; @@ -284,19 +294,19 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, /* * Check for initial section mappings in the pgd/pud. */ - BUG_ON(pud_sect(pud)); + SAFE_BUG_ON(flags, 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); + SAFE_BUG_ON(flags, !pgtable_alloc); pmd_phys = pgtable_alloc(PMD_SHIFT); __pud_populate(pudp, pmd_phys, pudval); pud = READ_ONCE(*pudp); } - BUG_ON(pud_bad(pud)); + SAFE_BUG_ON(flags, pud_bad(pud)); do { pgprot_t __prot = prot; @@ -342,12 +352,12 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, if (flags & NO_EXEC_MAPPINGS) p4dval |= P4D_TABLE_PXN; - BUG_ON(!pgtable_alloc); + SAFE_BUG_ON(flags, !pgtable_alloc); pud_phys = pgtable_alloc(PUD_SHIFT); __p4d_populate(p4dp, pud_phys, p4dval); p4d = READ_ONCE(*p4dp); } - BUG_ON(p4d_bad(p4d)); + SAFE_BUG_ON(flags, p4d_bad(p4d)); pudp = pud_set_fixmap_offset(p4dp, addr); do { @@ -366,13 +376,13 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, * 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), + SAFE_BUG_ON(flags, !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 && + SAFE_BUG_ON(flags, pud_val(old_pud) != 0 && pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); } phys += next - addr; @@ -394,7 +404,7 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, * 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 (SAFE_WARN_ON(flags, (phys ^ virt) & ~PAGE_MASK)) return; phys &= PAGE_MASK;