Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp3009641ybi; Mon, 17 Jun 2019 14:36:10 -0700 (PDT) X-Google-Smtp-Source: APXvYqw/Sd/Mq+PCUIYUyUrf2ta8eAkwcDmLiM5QoEYrjf6wC/JI++u5mLS01eTqBvh1eZeTZgKs X-Received: by 2002:a62:7990:: with SMTP id u138mr578951pfc.191.1560807370459; Mon, 17 Jun 2019 14:36:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560807370; cv=none; d=google.com; s=arc-20160816; b=N6WVjhqgX0/ADI8DQLOI5AKdSNMB968kKIx/t2tQS/8cvGwzeCGQdITgi1iRdTOkLT GgJLDuuqD2JWnuKutkbb9mrZS9FfznLC3UdzQdkZKKadoYSPVM38vdGNZwr/KS4azGVi +PB99H5t2xH8wfaKZ0n1SZPpMJXVEYirp3gCWjfLG8/ErI3HiFTXhs0/RqMDq18uwxHM Ysq0QNhA3DUHFvVFvptgbnezq0e6jHPS8Vy87x6iYKLj8rvMsG+1Jrj1AfaEYXpofceJ QBBiiG0Yqms7FBS0CVaQblTkj65kwm+XSy5gkYmBOR0j7VxNpE0OyzqXtBl5SmYf+lVu tu8g== 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=U3Ge81Nu0kZTgwjrnh+4GKGEk/eTiGMVidaG5r9T6V4=; b=Pgq/MFfi6azCZJ9Zqidu+kQtWNPsxBXWIkqPcSBU0DO4N4aJRKoKv+ViS7YaMJvw1u OuCtcSKh8gIN5Y0Sos4yyipLm8t+UECbZC/+AuR5sNdPsZvXbI3RUyLxFLzVybHfd2B2 IczrMdeyfEQ6tpQg8kX7hCUlEng8U+1PukCsx+3Zf9Z4IKfvrXKEpBrnQoVNki9EQLP6 9HFXpYBkztfz/gQHCfeskt9O2qOLqF3W+70rBsEJSu7jRiJqrO3/i8vglCi76Qr1Wpfv mWxVV2PlZ37Vv57hHZuurIbTbv2jLkTH3ZGsmZ+doBOUji/FQanoZ8G8NCis2OwtO1sz xUDg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=DWbJwVwL; 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 q195si11647886pgq.119.2019.06.17.14.35.55; Mon, 17 Jun 2019 14:36:10 -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=DWbJwVwL; 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 S1728982AbfFQVXp (ORCPT + 99 others); Mon, 17 Jun 2019 17:23:45 -0400 Received: from mail.kernel.org ([198.145.29.99]:48938 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729217AbfFQVXl (ORCPT ); Mon, 17 Jun 2019 17:23:41 -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 7E95C20673; Mon, 17 Jun 2019 21:23:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1560806621; bh=MCSRIwxxf+e4jcxgu13bQxXilnsZ9stigFK+KkNydLg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DWbJwVwL3Tq1eEujaDqyqiHoBeWHPutLjY6GQ9QKzO1SJ9dIUapVcnz3VI1NBQlvs fljoIDGsMRf7/zJwqWSgprR0D2C1soJXMYzeMXesp5Ny0bGf158Lt1kFZBomybJuc3 EnnH+BRsBTg5hMB6XLE0nyfGFdGFWBq5nDxlGNto= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Nicholas Piggin , "Aneesh Kumar K.V" , Michael Ellerman Subject: [PATCH 5.1 115/115] powerpc/64s: Fix THP PMD collapse serialisation Date: Mon, 17 Jun 2019 23:10:15 +0200 Message-Id: <20190617210805.696181884@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190617210759.929316339@linuxfoundation.org> References: <20190617210759.929316339@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 From: Nicholas Piggin commit 33258a1db165cf43a9e6382587ad06e9b7f8187c upstream. Commit 1b2443a547f9 ("powerpc/book3s64: Avoid multiple endian conversion in pte helpers") changed the actual bitwise tests in pte_access_permitted by using pte_write() and pte_present() helpers rather than raw bitwise testing _PAGE_WRITE and _PAGE_PRESENT bits. The pte_present() change now returns true for PTEs which are !_PAGE_PRESENT and _PAGE_INVALID, which is the combination used by pmdp_invalidate() to synchronize access from lock-free lookups. pte_access_permitted() is used by pmd_access_permitted(), so allowing GUP lock free access to proceed with such PTEs breaks this synchronisation. This bug has been observed on a host using the hash page table MMU, with random crashes and corruption in guests, usually together with bad PMD messages in the host. Fix this by adding an explicit check in pmd_access_permitted(), and documenting the condition explicitly. The pte_write() change should be okay, and would prevent GUP from falling back to the slow path when encountering savedwrite PTEs, which matches what x86 (that does not implement savedwrite) does. Fixes: 1b2443a547f9 ("powerpc/book3s64: Avoid multiple endian conversion in pte helpers") Cc: stable@vger.kernel.org # v4.20+ Signed-off-by: Nicholas Piggin Reviewed-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/include/asm/book3s/64/pgtable.h | 30 +++++++++++++++++++++++++++ arch/powerpc/mm/pgtable-book3s64.c | 3 ++ 2 files changed, 33 insertions(+) --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -875,6 +875,23 @@ static inline int pmd_present(pmd_t pmd) return false; } +static inline int pmd_is_serializing(pmd_t pmd) +{ + /* + * If the pmd is undergoing a split, the _PAGE_PRESENT bit is clear + * and _PAGE_INVALID is set (see pmd_present, pmdp_invalidate). + * + * This condition may also occur when flushing a pmd while flushing + * it (see ptep_modify_prot_start), so callers must ensure this + * case is fine as well. + */ + if ((pmd_raw(pmd) & cpu_to_be64(_PAGE_PRESENT | _PAGE_INVALID)) == + cpu_to_be64(_PAGE_INVALID)) + return true; + + return false; +} + static inline int pmd_bad(pmd_t pmd) { if (radix_enabled()) @@ -1090,6 +1107,19 @@ static inline int pmd_protnone(pmd_t pmd #define pmd_access_permitted pmd_access_permitted static inline bool pmd_access_permitted(pmd_t pmd, bool write) { + /* + * pmdp_invalidate sets this combination (which is not caught by + * !pte_present() check in pte_access_permitted), to prevent + * lock-free lookups, as part of the serialize_against_pte_lookup() + * synchronisation. + * + * This also catches the case where the PTE's hardware PRESENT bit is + * cleared while TLB is flushed, which is suboptimal but should not + * be frequent. + */ + if (pmd_is_serializing(pmd)) + return false; + return pte_access_permitted(pmd_pte(pmd), write); } --- a/arch/powerpc/mm/pgtable-book3s64.c +++ b/arch/powerpc/mm/pgtable-book3s64.c @@ -116,6 +116,9 @@ pmd_t pmdp_invalidate(struct vm_area_str /* * This ensures that generic code that rely on IRQ disabling * to prevent a parallel THP split work as expected. + * + * Marking the entry with _PAGE_INVALID && ~_PAGE_PRESENT requires + * a special case check in pmd_access_permitted. */ serialize_against_pte_lookup(vma->vm_mm); return __pmd(old_pmd);