Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5626495imu; Mon, 26 Nov 2018 03:11:21 -0800 (PST) X-Google-Smtp-Source: AJdET5f8iEbkgxr7mWu9+VCxp3aAyne8KI479Ya9k5Y+LGq4so2BR5o9aKA8WSezaJ5EK2IpJOP8 X-Received: by 2002:a62:83ce:: with SMTP id h197mr27277476pfe.187.1543230681034; Mon, 26 Nov 2018 03:11:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543230681; cv=none; d=google.com; s=arc-20160816; b=t4iVCXG0cyOntsbbo+i8zNiRSXSYKlSz2uZLi6oSmHmczsjnmq3lHuFLEwp/uJbbrX JcWx9FM8Hi1DYTmKQmmv8J7Y2R6ILMM2h9cc8ml8dQtTjRizhQVkPXV0DW7V84eUkrA8 +wyVpkL8jBXCQDFy0NuTN3TRZ3kj19tbX1Nd+ZeepFWsRNYUXmaUu6EsF5BD382dwd8G c0mDzeLX0RnM21N8nZychIcDsuxkP0AFKUpmcQdQVrO6ryP232GKBf2G5nZ98DlYqqdD xvEodCFoPLMvQCBJnoqUlbcEWuCHpYtqMcSysnb8fZ83yUhyCVEtHM8ak7Bti5EqGmXw 3lfA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Rmd7XzxIQ3dkg7TkT1w8nA6vLyvsrPsg9fkTEC/TaGU=; b=IP5yprkxJXFTAm9Ev3yPGqezP/nhRhglpLRyuuB2oUPc7saiuSMoD3NsjkCYnlgTDQ sahPv3uE2OQMDSxEaBr+VywkYgBZJJMEuYzcVjF0EX0ssKI95e1L7/T8kGCAMqHXh5Dy A3K/rMe3SdVbo2R3nkW09Ba9RTu1j+J6ohk4BtPKo7907CxOL4TCOUN4qcsE/0xmlbOE M1nDKlngaUoJmge48FkEqqc/FHPu1+xB3GMaU1F27gd1aGHEccA3ih9j3to3zNunprpU tdFU6ndhGyMY71YFDjR+SYd1j47vvcFD+rViivJQq+5xzevf+zBbIRPbsPojbtf4aq7c 5s2A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=HrmoTuWN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m8si6247956pls.400.2018.11.26.03.11.05; Mon, 26 Nov 2018 03:11:20 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=HrmoTuWN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731101AbeKZV6c (ORCPT + 99 others); Mon, 26 Nov 2018 16:58:32 -0500 Received: from mail.kernel.org ([198.145.29.99]:43726 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729291AbeKZV6a (ORCPT ); Mon, 26 Nov 2018 16:58:30 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id CC44E2089F; Mon, 26 Nov 2018 11:04:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543230284; bh=nDWsQK38MjPwn5v29HCwsoPb4koAcJiV97GXH+ZcMZ4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HrmoTuWNtLR8QrN1dl50KeGoFmiPUq+XucQFqzfLkbTCqIJjTmamJYTXQpYAel/fX wnZe3lq1JbfQS/AsyH79V2E0xVGqUmjZUKok9h5CtZV8e1hakCSgRN19VdM0VO+mLA PSY6oqzwp+LAjwMTVEJ+PpjxCI1/52QP9Crj6fCE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Li Wang , Martin Schwidefsky , Sasha Levin Subject: [PATCH 4.19 044/118] s390/mm: fix mis-accounting of pgtable_bytes Date: Mon, 26 Nov 2018 11:50:38 +0100 Message-Id: <20181126105102.565639804@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181126105059.832485122@linuxfoundation.org> References: <20181126105059.832485122@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ [ Upstream commit e12e4044aede97974f2222eb7f0ed726a5179a32 ] In case a fork or a clone system fails in copy_process and the error handling does the mmput() at the bad_fork_cleanup_mm label, the following warning messages will appear on the console: BUG: non-zero pgtables_bytes on freeing mm: 16384 The reason for that is the tricks we play with mm_inc_nr_puds() and mm_inc_nr_pmds() in init_new_context(). A normal 64-bit process has 3 levels of page table, the p4d level and the pud level are folded. On process termination the free_pud_range() function in mm/memory.c will subtract 16KB from pgtable_bytes with a mm_dec_nr_puds() call, but there actually is not really a pud table. One issue with this is the fact that pgtable_bytes is usually off by a few kilobytes, but the more severe problem is that for a failed fork or clone the free_pgtables() function is not called. In this case there is no mm_dec_nr_puds() or mm_dec_nr_pmds() that go together with the mm_inc_nr_puds() and mm_inc_nr_pmds in init_new_context(). The pgtable_bytes will be off by 16384 or 32768 bytes and we get the BUG message. The message itself is purely cosmetic, but annoying. To fix this override the mm_pmd_folded, mm_pud_folded and mm_p4d_folded function to check for the true size of the address space. Reported-by: Li Wang Tested-by: Li Wang Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin --- arch/s390/include/asm/mmu_context.h | 5 ----- arch/s390/include/asm/pgalloc.h | 6 +++--- arch/s390/include/asm/pgtable.h | 18 ++++++++++++++++++ arch/s390/include/asm/tlb.h | 6 +++--- arch/s390/mm/pgalloc.c | 1 + 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 0717ee76885d..f1ab9420ccfb 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -45,8 +45,6 @@ static inline int init_new_context(struct task_struct *tsk, mm->context.asce_limit = STACK_TOP_MAX; mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_REGION3; - /* pgd_alloc() did not account this pud */ - mm_inc_nr_puds(mm); break; case -PAGE_SIZE: /* forked 5-level task, set new asce with new_mm->pgd */ @@ -62,9 +60,6 @@ static inline int init_new_context(struct task_struct *tsk, /* forked 2-level compat task, set new asce with new mm->pgd */ mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; - /* pgd_alloc() did not account this pmd */ - mm_inc_nr_pmds(mm); - mm_inc_nr_puds(mm); } crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); return 0; diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index f0f9bcf94c03..5ee733720a57 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -36,11 +36,11 @@ static inline void crst_table_init(unsigned long *crst, unsigned long entry) static inline unsigned long pgd_entry_type(struct mm_struct *mm) { - if (mm->context.asce_limit <= _REGION3_SIZE) + if (mm_pmd_folded(mm)) return _SEGMENT_ENTRY_EMPTY; - if (mm->context.asce_limit <= _REGION2_SIZE) + if (mm_pud_folded(mm)) return _REGION3_ENTRY_EMPTY; - if (mm->context.asce_limit <= _REGION1_SIZE) + if (mm_p4d_folded(mm)) return _REGION2_ENTRY_EMPTY; return _REGION1_ENTRY_EMPTY; } diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 0e7cb0dc9c33..de05466ce50c 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -485,6 +485,24 @@ static inline int is_module_addr(void *addr) _REGION_ENTRY_PROTECT | \ _REGION_ENTRY_NOEXEC) +static inline bool mm_p4d_folded(struct mm_struct *mm) +{ + return mm->context.asce_limit <= _REGION1_SIZE; +} +#define mm_p4d_folded(mm) mm_p4d_folded(mm) + +static inline bool mm_pud_folded(struct mm_struct *mm) +{ + return mm->context.asce_limit <= _REGION2_SIZE; +} +#define mm_pud_folded(mm) mm_pud_folded(mm) + +static inline bool mm_pmd_folded(struct mm_struct *mm) +{ + return mm->context.asce_limit <= _REGION3_SIZE; +} +#define mm_pmd_folded(mm) mm_pmd_folded(mm) + static inline int mm_has_pgste(struct mm_struct *mm) { #ifdef CONFIG_PGSTE diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index 457b7ba0fbb6..b31c779cf581 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h @@ -136,7 +136,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, unsigned long address) { - if (tlb->mm->context.asce_limit <= _REGION3_SIZE) + if (mm_pmd_folded(tlb->mm)) return; pgtable_pmd_page_dtor(virt_to_page(pmd)); tlb_remove_table(tlb, pmd); @@ -152,7 +152,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, unsigned long address) { - if (tlb->mm->context.asce_limit <= _REGION1_SIZE) + if (mm_p4d_folded(tlb->mm)) return; tlb_remove_table(tlb, p4d); } @@ -167,7 +167,7 @@ static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, unsigned long address) { - if (tlb->mm->context.asce_limit <= _REGION2_SIZE) + if (mm_pud_folded(tlb->mm)) return; tlb_remove_table(tlb, pud); } diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c index 76d89ee8b428..814f26520aa2 100644 --- a/arch/s390/mm/pgalloc.c +++ b/arch/s390/mm/pgalloc.c @@ -101,6 +101,7 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long end) mm->context.asce_limit = _REGION1_SIZE; mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_REGION2; + mm_inc_nr_puds(mm); } else { crst_table_init(table, _REGION1_ENTRY_EMPTY); pgd_populate(mm, (pgd_t *) table, (p4d_t *) pgd); -- 2.17.1