From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-x22a.google.com (mail-pf0-x22a.google.com [IPv6:2607:f8b0:400e:c00::22a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 257D41A0D35 for ; Tue, 12 Jan 2016 07:09:34 +1100 (AEDT) Received: by mail-pf0-x22a.google.com with SMTP id 65so49675659pff.2 for ; Mon, 11 Jan 2016 12:09:34 -0800 (PST) Date: Mon, 11 Jan 2016 12:09:24 -0800 (PST) From: Hugh Dickins To: "Aneesh Kumar K.V" cc: benh@kernel.crashing.org, paulus@samba.org, mpe@ellerman.id.au, Hugh Dickins , Andrew Morton , Laurent Dufour , linuxppc-dev@lists.ozlabs.org, linux-mm@kvack.org Subject: Re: [PATCH V2] mm/powerpc: Fix _PAGE_PTE breaking swapoff In-Reply-To: <1452527374-4886-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> Message-ID: References: <1452527374-4886-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On Mon, 11 Jan 2016, Aneesh Kumar K.V wrote: > Core kernel expect swp_entry_t to be consisting of > only swap type and swap offset. We should not leak pte bits to > swp_entry_t. This breaks swapoff which use the swap type and offset > to build a swp_entry_t and later compare that to the swp_entry_t > obtained from linux page table pte. Leaking pte bits to swp_entry_t > breaks that comparison and results in us looping in try_to_unuse. > > The stack trace can be anywhere below try_to_unuse() in mm/swapfile.c, > since swapoff is circling around and around that function, reading from > each used swap block into a page, then trying to find where that page > belongs, looking at every non-file pte of every mm that ever swapped. > > Reported-by: Hugh Dickins > Suggested-by: Hugh Dickins > Signed-off-by: Aneesh Kumar K.V I think we've seen enough of my name above, but if it helps further Acked-by: Hugh Dickins Though I don't find the code comment below on swp_entry_t enlightening - your commit description above is much more helpful. If I were writing it, I might say... hmm, it's too hard: given all the convolutions, I gave up. > --- > Changes from V1: > * improve change log and code comment > > arch/powerpc/include/asm/book3s/64/pgtable.h | 11 ++++++++--- > 1 file changed, 8 insertions(+), 3 deletions(-) > > diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h > index 03c1a5a21c0c..cecb971674a8 100644 > --- a/arch/powerpc/include/asm/book3s/64/pgtable.h > +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h > @@ -158,9 +158,14 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) > #define __swp_entry(type, offset) ((swp_entry_t) { \ > ((type) << _PAGE_BIT_SWAP_TYPE) \ > | ((offset) << PTE_RPN_SHIFT) }) > - > -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) }) > -#define __swp_entry_to_pte(x) __pte((x).val) > +/* > + * swp_entry_t should be independent of pte bits. We build a swp_entry_t from > + * swap type and offset we get from swap and convert that to pte to > + * find a matching pte in linux page table. > + * Clear bits not found in swap entries here > + */ > +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) & ~_PAGE_PTE }) > +#define __swp_entry_to_pte(x) __pte((x).val | _PAGE_PTE) > > #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY > #define _PAGE_SWP_SOFT_DIRTY (1UL << (SWP_TYPE_BITS + _PAGE_BIT_SWAP_TYPE)) > -- > 2.5.0