Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp7279504imu; Wed, 14 Nov 2018 14:46:15 -0800 (PST) X-Google-Smtp-Source: AJdET5cUIzlExP415WTsKnSZxFYaEA2DmlW2FFS7xWThLYT3C/sVw1GwTaZn21zaqHUrdWkxN0NI X-Received: by 2002:a17:902:9a44:: with SMTP id x4-v6mr3676054plv.121.1542235575378; Wed, 14 Nov 2018 14:46:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542235575; cv=none; d=google.com; s=arc-20160816; b=leyQMfw6cWHDp6kXraTADF3l3TgSc0HH4l+cw01pNDC+az4PTNrphMEbxdN8PUGliq 3SUDwQVz9T1f9WijLMf4fTheOTJLyZV+60alLqUKGA4hIF4pTWbZLTkDNWUQmWjjBGqY qcfWRva2l25Zq/Lm+Pl4++yxnmJJNF+Jg6jXkLHGi3Zr4sg9C87kojGDVNKCcj5npenI xUgBIL/p/l79yCR8RAf6aS6i5abXv1/8VNWqqqZ1fUIlBw3JSI/Vu/TekS6Hpizt62vf rd+N1mgA3lof9F5iVgAGrTm8UOodXODkapIcJqnVRdaFK0jjaFxonNENbbbJsOOBGFlr qv+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=nhqmFh25F41yNKtRW92uVPJBPaUqkwHmY2hACw/KXpI=; b=SGslJBhpofYndaHi9BG9b0GHCT0UCv5QwtC99+9mfanF5DFxd36yTe5+bHXvTREUT8 oN0bk9xDP65UyymF2qIKyv/0M7+LU01gYnWfGrx/CrqY6lrKZP6lU7uGyKKU6vIicID3 SH0UFp7DUTx0NSyB76oEs/lmqFkfUeiPxGw+2vn+A7QWhSCG+3L1mLA4WmAleRo6hS/n dbU6O/CInKRHPtlTqCAvtZ+qeWGSqfYspUmizU9WQB+AbcycZcId/1kNMjfcAp0AEWv+ 7KyXPUU/nCXbSFQ1vTb7b7vLQxZGK9a3KbskXi+4fOFoR4lD3B6WViHadRRl5LTtw6UG hLrA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=o2QMrnRh; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p3si24871868pgi.0.2018.11.14.14.46.01; Wed, 14 Nov 2018 14:46:15 -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=o2QMrnRh; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728405AbeKOI1Q (ORCPT + 99 others); Thu, 15 Nov 2018 03:27:16 -0500 Received: from mail.kernel.org ([198.145.29.99]:34470 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727258AbeKOI1P (ORCPT ); Thu, 15 Nov 2018 03:27:15 -0500 Received: from sasha-vm.mshome.net (unknown [64.114.255.114]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 780F02251F; Wed, 14 Nov 2018 22:22:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1542234131; bh=9xwGK+2urupgk2vnwrGGs4AkAQZdNSQg6tjA9ENXeOc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o2QMrnRhpCsNdyW+L6gmQYH+lITviAGcuKdZZKmPGC5JU/GKl2E96u00BCVoCe7SQ C7yOTT5Hor7Wxp7CrvQ0aU2iBl7aGvhddLTfDwvkkeUEcBNlqVcFR7MWXEWM1+SGJ7 rHgEDrbd2D6MnHwYihxdoTRpjK2gDozJ1JT5fH7s= From: Sasha Levin To: stable@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Martin Schwidefsky , Sasha Levin Subject: [PATCH AUTOSEL 4.19 13/73] s390/mm: fix mis-accounting of pgtable_bytes Date: Wed, 14 Nov 2018 17:21:07 -0500 Message-Id: <20181114222207.98701-13-sashal@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181114222207.98701-1-sashal@kernel.org> References: <20181114222207.98701-1-sashal@kernel.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Martin Schwidefsky [ 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