Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp7150704ybi; Mon, 8 Jul 2019 15:39:59 -0700 (PDT) X-Google-Smtp-Source: APXvYqy3dmBR5z6JhuukJwINW4U6D48Hpq6xt8vjcAg/kH1pFLQ4UOFbhcZ6cgc57rbkfd+D1rTk X-Received: by 2002:a63:2259:: with SMTP id t25mr24768268pgm.298.1562625599616; Mon, 08 Jul 2019 15:39:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562625599; cv=none; d=google.com; s=arc-20160816; b=Wq3a7EnWh1JtrGZj+XCHW3er1lnEgR4//sYFum6fKtrk5W/M7Bdzcayb80qns7JdiI JzKsF/cf0UeS2rGChhlpNiJOzdRukl6kb5meM30ntCWgmkCkIr3uUcWtvx/8VRthkmpB 2Dgb1r3wCLyYl4nHPx9aWC/bdPeFwYfp6b2AJ0LQi5AsXrOUeOEyUruSxfk0e3grh7F/ JIniFQCZCb0vrTil3T2v82rTT3gjdPt42XXBJwMA4cDE/S4C9RdHwfUGOjLsyF7h1YzE Dkfs0nMB8NHlb3jvThExhqlaCSSgXpW0V3jsGLNJeWMxbVqIuwOH3H91mJtxW+diGm8x QhHg== 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=4/S95RaVVU+hr7ZOLzhcNy7WcfnMUsaT2RVFPIsMpTA=; b=wSAW63OrsYfn3ToUG7ITGD2SLlGa7qcHbCqTcH/7fE+72D3/UksxAydbIFMRRD8n0A g7z+C18ShQDTn3cnoY3Sg46S5RSijPkpKntPRZV8IsSb0z3qXZrApWikqBGfoBf6XiFM k184p8yt7kA+woGr7ZjX+H/HIQDPT9eAakqwe3V52Oe0UqFFqIL+skhN5VA2zHtS/6rF v8gOLmd4IL6T1Tj0y2hYygs1rVYgNxAdrRxS3HDrHCHfOCzVSDzk87JWJ6znMkM5n1bP pD8O4Y9F/LCbmD6azN1clrDGKg1DWkveEEnzz1eALp9NU+U+qM4+bm94ZJNRJq+N/DM+ PR9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=pXCFZoTl; 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 o1si19460800pld.278.2019.07.08.15.39.45; Mon, 08 Jul 2019 15:39:59 -0700 (PDT) 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=pXCFZoTl; 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 S2390584AbfGHPek (ORCPT + 99 others); Mon, 8 Jul 2019 11:34:40 -0400 Received: from mail.kernel.org ([198.145.29.99]:36884 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390559AbfGHPee (ORCPT ); Mon, 8 Jul 2019 11:34:34 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.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 4E499204EC; Mon, 8 Jul 2019 15:34:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1562600072; bh=3EPltH+TyhoVKGWzWdhMhsROLu5l28k94QXdN0XPeBU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pXCFZoTlok0V7OaPCpY7WW5LbsWbOqSwo5d9N1qPyQKyTjfekI6eapuGXrCbtFsAp Frk/W8atq/cikWAwIztnFeWPTQQypAF9cFOL0dNzCZ9iGi5EbWCRRh90Dr1Lqg3E+V KVHzaFz5pkXFVBDPgHS1754OKvzW2zDt5NIIbi+M= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Martin Schwidefsky , Sasha Levin Subject: [PATCH 5.1 84/96] s390/mm: fix pxd_bad with folded page tables Date: Mon, 8 Jul 2019 17:13:56 +0200 Message-Id: <20190708150530.986967549@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190708150526.234572443@linuxfoundation.org> References: <20190708150526.234572443@linuxfoundation.org> User-Agent: quilt/0.66 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 [ Upstream commit c9f621524e70774688db3cec60d85fa4c7de52e3 ] With git commit d1874a0c2805fcfa9162c972d6b7541e57adb542 "s390/mm: make the pxd_offset functions more robust" and a 2-level page table it can now happen that pgd_bad() gets asked to verify a large segment table entry. If the entry is marked as dirty pgd_bad() will incorrectly return true. Change the pgd_bad(), p4d_bad(), pud_bad() and pmd_bad() functions to first verify the table type, return false if the table level is lower than what the function is suppossed to check, return true if the table level is too high, and otherwise check the relevant region and segment table bits. pmd_bad() has to check against ~SEGMENT_ENTRY_BITS for normal page table pointers or ~SEGMENT_ENTRY_BITS_LARGE for large segment table entries. Same for pud_bad() which has to check against ~_REGION_ENTRY_BITS or ~_REGION_ENTRY_BITS_LARGE. Fixes: d1874a0c2805 ("s390/mm: make the pxd_offset functions more robust") Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin --- arch/s390/include/asm/pgtable.h | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 394bec31cb97..9f0195d5fa16 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -238,7 +238,7 @@ static inline int is_module_addr(void *addr) #define _REGION_ENTRY_NOEXEC 0x100 /* region no-execute bit */ #define _REGION_ENTRY_OFFSET 0xc0 /* region table offset */ #define _REGION_ENTRY_INVALID 0x20 /* invalid region table entry */ -#define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */ +#define _REGION_ENTRY_TYPE_MASK 0x0c /* region table type mask */ #define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */ #define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */ #define _REGION_ENTRY_TYPE_R3 0x04 /* region third table type */ @@ -277,6 +277,7 @@ static inline int is_module_addr(void *addr) #define _SEGMENT_ENTRY_PROTECT 0x200 /* segment protection bit */ #define _SEGMENT_ENTRY_NOEXEC 0x100 /* segment no-execute bit */ #define _SEGMENT_ENTRY_INVALID 0x20 /* invalid segment table entry */ +#define _SEGMENT_ENTRY_TYPE_MASK 0x0c /* segment table type mask */ #define _SEGMENT_ENTRY (0) #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INVALID) @@ -614,15 +615,9 @@ static inline int pgd_none(pgd_t pgd) static inline int pgd_bad(pgd_t pgd) { - /* - * With dynamic page table levels the pgd can be a region table - * entry or a segment table entry. Check for the bit that are - * invalid for either table entry. - */ - unsigned long mask = - ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INVALID & - ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; - return (pgd_val(pgd) & mask) != 0; + if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R1) + return 0; + return (pgd_val(pgd) & ~_REGION_ENTRY_BITS) != 0; } static inline unsigned long pgd_pfn(pgd_t pgd) @@ -703,6 +698,8 @@ static inline int pmd_large(pmd_t pmd) static inline int pmd_bad(pmd_t pmd) { + if ((pmd_val(pmd) & _SEGMENT_ENTRY_TYPE_MASK) > 0) + return 1; if (pmd_large(pmd)) return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS_LARGE) != 0; return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS) != 0; @@ -710,8 +707,12 @@ static inline int pmd_bad(pmd_t pmd) static inline int pud_bad(pud_t pud) { - if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) - return pmd_bad(__pmd(pud_val(pud))); + unsigned long type = pud_val(pud) & _REGION_ENTRY_TYPE_MASK; + + if (type > _REGION_ENTRY_TYPE_R3) + return 1; + if (type < _REGION_ENTRY_TYPE_R3) + return 0; if (pud_large(pud)) return (pud_val(pud) & ~_REGION_ENTRY_BITS_LARGE) != 0; return (pud_val(pud) & ~_REGION_ENTRY_BITS) != 0; @@ -719,8 +720,12 @@ static inline int pud_bad(pud_t pud) static inline int p4d_bad(p4d_t p4d) { - if ((p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) - return pud_bad(__pud(p4d_val(p4d))); + unsigned long type = p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK; + + if (type > _REGION_ENTRY_TYPE_R2) + return 1; + if (type < _REGION_ENTRY_TYPE_R2) + return 0; return (p4d_val(p4d) & ~_REGION_ENTRY_BITS) != 0; } -- 2.20.1