Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp5437772ybe; Tue, 10 Sep 2019 03:47:08 -0700 (PDT) X-Google-Smtp-Source: APXvYqzBXi5FJ1UHvGAR3+KW6Vsf08NhMECNFJ5Z3cqMCb4PFH6pocx+3Bj8WkqAmEX1XYez1rY2 X-Received: by 2002:a05:6402:3c5:: with SMTP id t5mr29602327edw.22.1568112428616; Tue, 10 Sep 2019 03:47:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1568112428; cv=none; d=google.com; s=arc-20160816; b=dS0p5w8Szi2idWAfHTfkLE8USSQaMUQCVd1q5yxqzT7gbKqpsYNSLPGV8+JfhnKv8j QDiTPAI9+STkWVpEn/+KtwC1sEKKUt1MBJtnNwCzRfLl/Wfl86gI+K/3F84w58Q+RolE g81gwo6JlZdh4rcw4kFgPu4JLbJC/ToRMJDWDp5XDpyZxC+5T771So9ie1HukdgxERA6 0Omk/kY3QAnLfjidEuaY65LLIQ8U9GfKAuV8AdLRX1+D0c/bbk6DItiVxNWQYBC0vif5 Ixih3ay7Sk1xnxBF6ZgSjIQUJNNE/HDany2Y+vpvW0DVBkD0TX+6J+Lch361HVw0e8W2 N8zw== 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 :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=w/QjelnzDkz8q3tOGxDBHFZzJGytd4KighvX/yeEDp0=; b=qUfn74FN3xJj+2f51wZlxebPZ/MCJtw0x2Ej0xV+mO/FS4ELvsOlRaOHFy9ipTIt9N rTFulp38/H9UkuBKnBSxcGOOK2N3fucjstcdAog1EXJ+hf5fs0TUhexi1RdmJirhmtiA OABY85uSZqXxhKf+fOn/amv52KFIzZgkyWFPUyGL9UrjDYZQJj3zMsc5F1QJ7pEzI4Xb Ug/EJAyix7UhWhWEB405JVOQ9TRWbsf1KjSGSt1PF3To+DgKrRU/nknkbmvQjnAojgfJ eHuPtZezcNDIKVpXJufd8mb631mbQazGNVNyRtfclb+ZIFwkyT6Sc+dxKtYSVAHK5Lqc OBHA== ARC-Authentication-Results: i=1; mx.google.com; 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 j9si3045808edq.304.2019.09.10.03.46.44; Tue, 10 Sep 2019 03:47:08 -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; 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 S2404351AbfIJFnM (ORCPT + 99 others); Tue, 10 Sep 2019 01:43:12 -0400 Received: from foss.arm.com ([217.140.110.172]:57826 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730118AbfIJFnM (ORCPT ); Tue, 10 Sep 2019 01:43:12 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A514B28; Mon, 9 Sep 2019 22:43:10 -0700 (PDT) Received: from [10.162.40.137] (p8cg001049571a15.blr.arm.com [10.162.40.137]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 53DA43F67D; Mon, 9 Sep 2019 22:45:25 -0700 (PDT) Subject: Re: [PATCH 1/1] mm/pgtable/debug: Add test validating architecture page table helpers To: Christophe Leroy , "Kirill A. Shutemov" Cc: Mark Rutland , linux-ia64@vger.kernel.org, linux-sh@vger.kernel.org, Tetsuo Handa , James Hogan , Heiko Carstens , Michal Hocko , linux-mm@kvack.org, Dave Hansen , Paul Mackerras , sparclinux@vger.kernel.org, Thomas Gleixner , linux-s390@vger.kernel.org, x86@kernel.org, Russell King - ARM Linux , Matthew Wilcox , Steven Price , Jason Gunthorpe , Vlastimil Babka , linux-snps-arc@lists.infradead.org, Kees Cook , Masahiro Yamada , Mark Brown , Dan Williams , Gerald Schaefer , linux-arm-kernel@lists.infradead.org, Sri Krishna chowdary , Ard Biesheuvel , Greg Kroah-Hartman , linux-mips@vger.kernel.org, Ralf Baechle , linux-kernel@vger.kernel.org, Peter Zijlstra , Mike Rapoport , Paul Burton , Vineet Gupta , Martin Schwidefsky , Andrew Morton , linuxppc-dev@lists.ozlabs.org, "David S. Miller" References: <1567497706-8649-1-git-send-email-anshuman.khandual@arm.com> <1567497706-8649-2-git-send-email-anshuman.khandual@arm.com> <20190904221618.1b624a98@thinkpad> <20e3044d-2af5-b27b-7653-cec53bdec941@arm.com> <20190905190629.523bdb87@thinkpad> <3c609e33-afbb-ffaf-481a-6d225a06d1d0@arm.com> <20190906210346.5ecbff01@thinkpad> <3d5de35f-8192-1c75-50a9-03e66e3b8e5c@arm.com> <20190909151344.ghfypjbgxyosjdk3@box> <5883d41a-8299-1584-aa3d-fac89b3d9b5b@arm.com> <94029d96-47c4-3020-57a8-4e03de1b4fc8@c-s.fr> From: Anshuman Khandual Message-ID: Date: Tue, 10 Sep 2019 11:13:07 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <94029d96-47c4-3020-57a8-4e03de1b4fc8@c-s.fr> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 09/10/2019 10:15 AM, Christophe Leroy wrote: > > > On 09/10/2019 03:56 AM, Anshuman Khandual wrote: >> >> >> On 09/09/2019 08:43 PM, Kirill A. Shutemov wrote: >>> On Mon, Sep 09, 2019 at 11:56:50AM +0530, Anshuman Khandual wrote: >>>> >>>> >>>> On 09/07/2019 12:33 AM, Gerald Schaefer wrote: >>>>> On Fri, 6 Sep 2019 11:58:59 +0530 >>>>> Anshuman Khandual wrote: >>>>> >>>>>> On 09/05/2019 10:36 PM, Gerald Schaefer wrote: >>>>>>> On Thu, 5 Sep 2019 14:48:14 +0530 >>>>>>> Anshuman Khandual wrote: >>>>>>>    >>>>>>>>> [...] >>>>>>>>>> + >>>>>>>>>> +#if !defined(__PAGETABLE_PMD_FOLDED) && !defined(__ARCH_HAS_4LEVEL_HACK) >>>>>>>>>> +static void pud_clear_tests(pud_t *pudp) >>>>>>>>>> +{ >>>>>>>>>> +    memset(pudp, RANDOM_NZVALUE, sizeof(pud_t)); >>>>>>>>>> +    pud_clear(pudp); >>>>>>>>>> +    WARN_ON(!pud_none(READ_ONCE(*pudp))); >>>>>>>>>> +} >>>>>>>>> >>>>>>>>> For pgd/p4d/pud_clear(), we only clear if the page table level is present >>>>>>>>> and not folded. The memset() here overwrites the table type bits, so >>>>>>>>> pud_clear() will not clear anything on s390 and the pud_none() check will >>>>>>>>> fail. >>>>>>>>> Would it be possible to OR a (larger) random value into the table, so that >>>>>>>>> the lower 12 bits would be preserved? >>>>>>>> >>>>>>>> So the suggestion is instead of doing memset() on entry with RANDOM_NZVALUE, >>>>>>>> it should OR a large random value preserving lower 12 bits. Hmm, this should >>>>>>>> still do the trick for other platforms, they just need non zero value. So on >>>>>>>> s390, the lower 12 bits on the page table entry already has valid value while >>>>>>>> entering this function which would make sure that pud_clear() really does >>>>>>>> clear the entry ? >>>>>>> >>>>>>> Yes, in theory the table entry on s390 would have the type set in the last >>>>>>> 4 bits, so preserving those would be enough. If it does not conflict with >>>>>>> others, I would still suggest preserving all 12 bits since those would contain >>>>>>> arch-specific flags in general, just to be sure. For s390, the pte/pmd tests >>>>>>> would also work with the memset, but for consistency I think the same logic >>>>>>> should be used in all pxd_clear_tests. >>>>>> >>>>>> Makes sense but.. >>>>>> >>>>>> There is a small challenge with this. Modifying individual bits on a given >>>>>> page table entry from generic code like this test case is bit tricky. That >>>>>> is because there are not enough helpers to create entries with an absolute >>>>>> value. This would have been easier if all the platforms provided functions >>>>>> like __pxx() which is not the case now. Otherwise something like this should >>>>>> have worked. >>>>>> >>>>>> >>>>>> pud_t pud = READ_ONCE(*pudp); >>>>>> pud = __pud(pud_val(pud) | RANDOM_VALUE (keeping lower 12 bits 0)) >>>>>> WRITE_ONCE(*pudp, pud); >>>>>> >>>>>> But __pud() will fail to build in many platforms. >>>>> >>>>> Hmm, I simply used this on my system to make pud_clear_tests() work, not >>>>> sure if it works on all archs: >>>>> >>>>> pud_val(*pudp) |= RANDOM_NZVALUE; >>>> >>>> Which compiles on arm64 but then fails on x86 because of the way pmd_val() >>>> has been defined there. >>> >>> Use instead >>> >>>     *pudp = __pud(pud_val(*pudp) | RANDOM_NZVALUE); >> >> Agreed. >> >> As I had mentioned before this would have been really the cleanest approach. >> >>> >>> It *should* be more portable. >> >> Not really, because not all the platforms have __pxx() definitions right now. >> Going with these will clearly cause build failures on affected platforms. Lets >> examine __pud() for instance. It is defined only on these platforms. >> >> arch/arm64/include/asm/pgtable-types.h:        #define __pud(x) ((pud_t) { (x) } ) >> arch/mips/include/asm/pgtable-64.h:        #define __pud(x) ((pud_t) { (x) }) >> arch/powerpc/include/asm/pgtable-be-types.h:    #define __pud(x) ((pud_t) { cpu_to_be64(x) }) >> arch/powerpc/include/asm/pgtable-types.h:    #define __pud(x) ((pud_t) { (x) }) >> arch/s390/include/asm/page.h:            #define __pud(x) ((pud_t) { (x) } ) >> arch/sparc/include/asm/page_64.h:        #define __pud(x) ((pud_t) { (x) } ) >> arch/sparc/include/asm/page_64.h:        #define __pud(x) (x) >> arch/x86/include/asm/pgtable.h:            #define __pud(x) native_make_pud(x) > > You missed: > arch/x86/include/asm/paravirt.h:static inline pud_t __pud(pudval_t val) > include/asm-generic/pgtable-nop4d-hack.h:#define __pud(x)                ((pud_t) { __pgd(x) }) > include/asm-generic/pgtable-nopud.h:#define __pud(x)        ((pud_t) { __p4d(x) }) > >> >> Similarly for __pmd() >> >> arch/alpha/include/asm/page.h:            #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/arm/include/asm/page-nommu.h:        #define __pmd(x)  (x) >> arch/arm/include/asm/pgtable-2level-types.h:    #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/arm/include/asm/pgtable-2level-types.h:    #define __pmd(x)  (x) >> arch/arm/include/asm/pgtable-3level-types.h:    #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/arm/include/asm/pgtable-3level-types.h:    #define __pmd(x)  (x) >> arch/arm64/include/asm/pgtable-types.h:        #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/m68k/include/asm/page.h:            #define __pmd(x)  ((pmd_t) { { (x) }, }) >> arch/mips/include/asm/pgtable-64.h:        #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/nds32/include/asm/page.h:            #define __pmd(x)  (x) >> arch/parisc/include/asm/page.h:            #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/parisc/include/asm/page.h:            #define __pmd(x)  (x) >> arch/powerpc/include/asm/pgtable-be-types.h:    #define __pmd(x)  ((pmd_t) { cpu_to_be64(x) }) >> arch/powerpc/include/asm/pgtable-types.h:    #define __pmd(x)  ((pmd_t) { (x) }) >> arch/riscv/include/asm/pgtable-64.h:        #define __pmd(x)  ((pmd_t) { (x) }) >> arch/s390/include/asm/page.h:            #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/sh/include/asm/pgtable-3level.h:        #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/sparc/include/asm/page_32.h:        #define __pmd(x)  ((pmd_t) { { (x) }, }) >> arch/sparc/include/asm/page_32.h:        #define __pmd(x)  ((pmd_t) { { (x) }, }) >> arch/sparc/include/asm/page_64.h:        #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/sparc/include/asm/page_64.h:        #define __pmd(x)  (x) >> arch/um/include/asm/page.h:            #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/um/include/asm/page.h:            #define __pmd(x)  ((pmd_t) { (x) } ) >> arch/x86/include/asm/pgtable.h:            #define __pmd(x)  native_make_pmd(x) > > You missed: > arch/x86/include/asm/paravirt.h:static inline pmd_t __pmd(pmdval_t val) > include/asm-generic/page.h:#define __pmd(x)     ((pmd_t) { (x) } ) > include/asm-generic/pgtable-nopmd.h:#define __pmd(x)        ((pmd_t) { __pud(x) } ) > > >> >> Similarly for __pgd() >> >> arch/alpha/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/alpha/include/asm/page.h:            #define __pgd(x)  (x) >> arch/arc/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) }) >> arch/arc/include/asm/page.h:            #define __pgd(x)  (x) >> arch/arm/include/asm/pgtable-3level-types.h:    #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/arm/include/asm/pgtable-3level-types.h:    #define __pgd(x)  (x) >> arch/arm64/include/asm/pgtable-types.h:        #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/csky/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) }) >> arch/hexagon/include/asm/page.h:        #define __pgd(x)  ((pgd_t) { (x) }) >> arch/m68k/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/mips/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/nds32/include/asm/page.h:            #define __pgd(x)  (x) >> arch/nios2/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) }) >> arch/openrisc/include/asm/page.h:        #define __pgd(x)  ((pgd_t) { (x) }) >> arch/parisc/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/parisc/include/asm/page.h:            #define __pgd(x)  (x) >> arch/powerpc/include/asm/pgtable-be-types.h:    #define __pgd(x)  ((pgd_t) { cpu_to_be64(x) }) >> arch/powerpc/include/asm/pgtable-types.h:    #define __pgd(x)  ((pgd_t) { (x) }) >> arch/riscv/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) }) >> arch/s390/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/sh/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/sparc/include/asm/page_32.h:        #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/sparc/include/asm/page_32.h:        #define __pgd(x)  (x) >> arch/sparc/include/asm/page_64.h:        #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/sparc/include/asm/page_64.h:        #define __pgd(x)  (x) >> arch/um/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) } ) >> arch/unicore32/include/asm/page.h:        #define __pgd(x)  ((pgd_t) { (x) }) >> arch/unicore32/include/asm/page.h:        #define __pgd(x)  (x) >> arch/x86/include/asm/pgtable.h:            #define __pgd(x)  native_make_pgd(x) >> arch/xtensa/include/asm/page.h:            #define __pgd(x)  ((pgd_t) { (x) } ) > > You missed: > arch/x86/include/asm/paravirt.h:static inline pgd_t __pgd(pgdval_t val) > include/asm-generic/page.h:#define __pgd(x)     ((pgd_t) { (x) } ) > > >> >> Similarly for __p4d() >> >> arch/s390/include/asm/page.h:            #define __p4d(x)  ((p4d_t) { (x) } ) >> arch/x86/include/asm/pgtable.h:            #define __p4d(x)  native_make_p4d(x) > > You missed: > arch/x86/include/asm/paravirt.h:static inline p4d_t __p4d(p4dval_t val) > include/asm-generic/5level-fixup.h:#define __p4d(x) __pgd(x) > include/asm-generic/pgtable-nop4d.h:#define __p4d(x)        ((p4d_t) { __pgd(x) }) > > >> >> The search pattern here has been "#define __pxx(". Unless I am missing something, >> I dont see how we can use these without risking build failures. >> > > I guess you missed that arches not defining them fall back on the definitions in include/asm-generic You are right. I was confused whether these generic definitions were really applicable for all those platforms as fallback (with so many page table level folding combinations available) when they dont define. Sure will take this approach and try to build them on multiple platforms.