From: Mike Rapoport <rppt@kernel.org>
To: David Hildenbrand <david@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Albert Ou <aou@eecs.berkeley.edu>,
Andy Lutomirski <luto@kernel.org>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Borislav Petkov <bp@alien8.de>,
Catalin Marinas <catalin.marinas@arm.com>,
Christian Borntraeger <borntraeger@de.ibm.com>,
Christoph Lameter <cl@linux.com>,
"David S. Miller" <davem@davemloft.net>,
Dave Hansen <dave.hansen@linux.intel.com>,
David Rientjes <rientjes@google.com>,
"Edgecombe, Rick P" <rick.p.edgecombe@intel.com>,
"H. Peter Anvin" <hpa@zytor.com>,
Heiko Carstens <hca@linux.ibm.com>,
Ingo Molnar <mingo@redhat.com>,
Joonsoo Kim <iamjoonsoo.kim@lge.com>,
"Kirill A. Shutemov" <kirill@shutemov.name>,
Len Brown <len.brown@intel.com>,
Michael Ellerman <mpe@ellerman.id.au>,
Mike Rapoport <rppt@linux.ibm.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Paul Mackerras <paulus@samba.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
Pavel Machek <pavel@ucw.cz>, Pekka Enberg <penberg@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
Thomas Gleixner <tglx@linutronix.de>,
Vasily Gorbik <gor@linux.ibm.com>, Will Deacon <will@kernel.org>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
linux-pm@vger.kernel.org, linux-riscv@lists.infradead.org,
linux-s390@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
sparclinux@vger.kernel.org, x86@kernel.org
Subject: Re: [PATCH v3 4/4] arch, mm: make kernel_page_present() always available
Date: Mon, 2 Nov 2020 17:18:29 +0200 [thread overview]
Message-ID: <20201102151829.GC4879@kernel.org> (raw)
In-Reply-To: <08db307a-b093-d7aa-7364-045f328ab147@redhat.com>
On Mon, Nov 02, 2020 at 10:28:14AM +0100, David Hildenbrand wrote:
> On 01.11.20 18:08, Mike Rapoport wrote:
> > From: Mike Rapoport <rppt@linux.ibm.com>
> >
> > For architectures that enable ARCH_HAS_SET_MEMORY having the ability to
> > verify that a page is mapped in the kernel direct map can be useful
> > regardless of hibernation.
> >
> > Add RISC-V implementation of kernel_page_present(), update its forward
> > declarations and stubs to be a part of set_memory API and remove ugly
> > ifdefery in inlcude/linux/mm.h around current declarations of
> > kernel_page_present().
> >
> > Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> > ---
> > arch/arm64/include/asm/cacheflush.h | 1 +
> > arch/arm64/mm/pageattr.c | 4 +---
> > arch/riscv/include/asm/set_memory.h | 1 +
> > arch/riscv/mm/pageattr.c | 29 +++++++++++++++++++++++++++++
> > arch/x86/include/asm/set_memory.h | 1 +
> > arch/x86/mm/pat/set_memory.c | 4 +---
> > include/linux/mm.h | 7 -------
> > include/linux/set_memory.h | 5 +++++
> > 8 files changed, 39 insertions(+), 13 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> > index 9384fd8fc13c..45217f21f1fe 100644
> > --- a/arch/arm64/include/asm/cacheflush.h
> > +++ b/arch/arm64/include/asm/cacheflush.h
> > @@ -140,6 +140,7 @@ int set_memory_valid(unsigned long addr, int numpages, int enable);
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > #include <asm-generic/cacheflush.h>
> > diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> > index 439325532be1..92eccaf595c8 100644
> > --- a/arch/arm64/mm/pageattr.c
> > +++ b/arch/arm64/mm/pageattr.c
> > @@ -186,8 +186,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > set_memory_valid((unsigned long)page_address(page), numpages, enable);
> > }
> > +#endif /* CONFIG_DEBUG_PAGEALLOC */
> > -#ifdef CONFIG_HIBERNATION
> > /*
> > * This function is used to determine if a linear map page has been marked as
> > * not-valid. Walk the page table and check the PTE_VALID bit. This is based
> > @@ -234,5 +234,3 @@ bool kernel_page_present(struct page *page)
> > ptep = pte_offset_kernel(pmdp, addr);
> > return pte_valid(READ_ONCE(*ptep));
> > }
> > -#endif /* CONFIG_HIBERNATION */
> > -#endif /* CONFIG_DEBUG_PAGEALLOC */
> > diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
> > index 4c5bae7ca01c..d690b08dff2a 100644
> > --- a/arch/riscv/include/asm/set_memory.h
> > +++ b/arch/riscv/include/asm/set_memory.h
> > @@ -24,6 +24,7 @@ static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > #endif /* __ASSEMBLY__ */
> > diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
> > index 321b09d2e2ea..87ba5a68bbb8 100644
> > --- a/arch/riscv/mm/pageattr.c
> > +++ b/arch/riscv/mm/pageattr.c
> > @@ -198,3 +198,32 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > __pgprot(0), __pgprot(_PAGE_PRESENT));
> > }
> > #endif
> > +
> > +bool kernel_page_present(struct page *page)
> > +{
> > + unsigned long addr = (unsigned long)page_address(page);
> > + pgd_t *pgd;
> > + pud_t *pud;
> > + p4d_t *p4d;
> > + pmd_t *pmd;
> > + pte_t *pte;
> > +
> > + pgd = pgd_offset_k(addr);
> > + if (!pgd_present(*pgd))
> > + return false;
> > +
> > + p4d = p4d_offset(pgd, addr);
> > + if (!p4d_present(*p4d))
> > + return false;
> > +
> > + pud = pud_offset(p4d, addr);
> > + if (!pud_present(*pud))
> > + return false;
> > +
> > + pmd = pmd_offset(pud, addr);
> > + if (!pmd_present(*pmd))
> > + return false;
> > +
> > + pte = pte_offset_kernel(pmd, addr);
> > + return pte_present(*pte);
> > +}
> > diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
> > index 5948218f35c5..4352f08bfbb5 100644
> > --- a/arch/x86/include/asm/set_memory.h
> > +++ b/arch/x86/include/asm/set_memory.h
> > @@ -82,6 +82,7 @@ int set_pages_rw(struct page *page, int numpages);
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > extern int kernel_set_to_readonly;
> > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> > index bc9be96b777f..16f878c26667 100644
> > --- a/arch/x86/mm/pat/set_memory.c
> > +++ b/arch/x86/mm/pat/set_memory.c
> > @@ -2226,8 +2226,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > arch_flush_lazy_mmu_mode();
> > }
> > +#endif /* CONFIG_DEBUG_PAGEALLOC */
> > -#ifdef CONFIG_HIBERNATION
> > bool kernel_page_present(struct page *page)
> > {
> > unsigned int level;
> > @@ -2239,8 +2239,6 @@ bool kernel_page_present(struct page *page)
> > pte = lookup_address((unsigned long)page_address(page), &level);
> > return (pte_val(*pte) & _PAGE_PRESENT);
> > }
> > -#endif /* CONFIG_HIBERNATION */
> > -#endif /* CONFIG_DEBUG_PAGEALLOC */
> > int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
> > unsigned numpages, unsigned long page_flags)
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index ab0ef6bd351d..44b82f22e76a 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -2937,16 +2937,9 @@ static inline void debug_pagealloc_map_pages(struct page *page,
> > if (debug_pagealloc_enabled_static())
> > __kernel_map_pages(page, numpages, enable);
> > }
> > -
> > -#ifdef CONFIG_HIBERNATION
> > -extern bool kernel_page_present(struct page *page);
> > -#endif /* CONFIG_HIBERNATION */
> > #else /* CONFIG_DEBUG_PAGEALLOC */
> > static inline void debug_pagealloc_map_pages(struct page *page,
> > int numpages, int enable) {}
> > -#ifdef CONFIG_HIBERNATION
> > -static inline bool kernel_page_present(struct page *page) { return true; }
> > -#endif /* CONFIG_HIBERNATION */
> > #endif /* CONFIG_DEBUG_PAGEALLOC */
> > #ifdef __HAVE_ARCH_GATE_AREA
> > diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
> > index 860e0f843c12..fe1aa4e54680 100644
> > --- a/include/linux/set_memory.h
> > +++ b/include/linux/set_memory.h
> > @@ -23,6 +23,11 @@ static inline int set_direct_map_default_noflush(struct page *page)
> > {
> > return 0;
> > }
> > +
> > +static inline bool kernel_page_present(struct page *page)
> > +{
> > + return true;
> > +}
> > #endif
> > #ifndef set_mce_nospec
> >
>
> It's somewhat weird to move this to set_memory.h - it's only one possible
> user. I think include/linux/mm.h is a better fit. Ack to making it
> independent of CONFIG_HIBERNATION.
Semantically this is a part of direct map manipulation, that's primarily
why I put it into set_memory.h
> in include/linux/mm.h , I'd prefer:
>
> #if defined(CONFIG_DEBUG_PAGEALLOC) || \
> defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP)
The second reason was to avoid this ^
and the third is -7 lines to include/linux/mm.h :)
> bool kernel_page_present(struct page *page);
> #else
> static inline bool kernel_page_present(struct page *page)
> {
> return true;
> }
> #endif
>
> --
> Thanks,
>
> David / dhildenb
>
>
--
Sincerely yours,
Mike.
WARNING: multiple messages have this Message-ID (diff)
From: Mike Rapoport <rppt@kernel.org>
To: David Hildenbrand <david@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
linux-mm@kvack.org, Paul Mackerras <paulus@samba.org>,
Pavel Machek <pavel@ucw.cz>, "H. Peter Anvin" <hpa@zytor.com>,
sparclinux@vger.kernel.org, Christoph Lameter <cl@linux.com>,
Will Deacon <will@kernel.org>,
linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org,
Michael Ellerman <mpe@ellerman.id.au>,
x86@kernel.org, Mike Rapoport <rppt@linux.ibm.com>,
Christian Borntraeger <borntraeger@de.ibm.com>,
Ingo Molnar <mingo@redhat.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Len Brown <len.brown@intel.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Vasily Gorbik <gor@linux.ibm.com>,
linux-pm@vger.kernel.org, Heiko Carstens <hca@linux.ibm.com>,
David Rientjes <rientjes@google.com>,
Borislav Petkov <bp@alien8.de>, Andy Lutomirski <luto@kernel.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
"Kirill A. Shutemov" <kirill@shutemov.name>,
Thomas Gleixner <tglx@linutronix.de>,
Joonsoo Kim <iamjoonsoo.kim@lge.com>,
linux-arm-kernel@lists.infradead.org,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
linux-kernel@vger.kernel.org, Pekka Enberg <penberg@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Andrew Morton <akpm@linux-foundation.org>,
"Edgecombe, Rick P" <rick.p.edgecombe@intel.com>,
linuxppc-dev@lists.ozlabs.org,
"David S. Miller" <davem@davemloft.net>
Subject: Re: [PATCH v3 4/4] arch, mm: make kernel_page_present() always available
Date: Mon, 2 Nov 2020 17:18:29 +0200 [thread overview]
Message-ID: <20201102151829.GC4879@kernel.org> (raw)
In-Reply-To: <08db307a-b093-d7aa-7364-045f328ab147@redhat.com>
On Mon, Nov 02, 2020 at 10:28:14AM +0100, David Hildenbrand wrote:
> On 01.11.20 18:08, Mike Rapoport wrote:
> > From: Mike Rapoport <rppt@linux.ibm.com>
> >
> > For architectures that enable ARCH_HAS_SET_MEMORY having the ability to
> > verify that a page is mapped in the kernel direct map can be useful
> > regardless of hibernation.
> >
> > Add RISC-V implementation of kernel_page_present(), update its forward
> > declarations and stubs to be a part of set_memory API and remove ugly
> > ifdefery in inlcude/linux/mm.h around current declarations of
> > kernel_page_present().
> >
> > Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> > ---
> > arch/arm64/include/asm/cacheflush.h | 1 +
> > arch/arm64/mm/pageattr.c | 4 +---
> > arch/riscv/include/asm/set_memory.h | 1 +
> > arch/riscv/mm/pageattr.c | 29 +++++++++++++++++++++++++++++
> > arch/x86/include/asm/set_memory.h | 1 +
> > arch/x86/mm/pat/set_memory.c | 4 +---
> > include/linux/mm.h | 7 -------
> > include/linux/set_memory.h | 5 +++++
> > 8 files changed, 39 insertions(+), 13 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> > index 9384fd8fc13c..45217f21f1fe 100644
> > --- a/arch/arm64/include/asm/cacheflush.h
> > +++ b/arch/arm64/include/asm/cacheflush.h
> > @@ -140,6 +140,7 @@ int set_memory_valid(unsigned long addr, int numpages, int enable);
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > #include <asm-generic/cacheflush.h>
> > diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> > index 439325532be1..92eccaf595c8 100644
> > --- a/arch/arm64/mm/pageattr.c
> > +++ b/arch/arm64/mm/pageattr.c
> > @@ -186,8 +186,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > set_memory_valid((unsigned long)page_address(page), numpages, enable);
> > }
> > +#endif /* CONFIG_DEBUG_PAGEALLOC */
> > -#ifdef CONFIG_HIBERNATION
> > /*
> > * This function is used to determine if a linear map page has been marked as
> > * not-valid. Walk the page table and check the PTE_VALID bit. This is based
> > @@ -234,5 +234,3 @@ bool kernel_page_present(struct page *page)
> > ptep = pte_offset_kernel(pmdp, addr);
> > return pte_valid(READ_ONCE(*ptep));
> > }
> > -#endif /* CONFIG_HIBERNATION */
> > -#endif /* CONFIG_DEBUG_PAGEALLOC */
> > diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
> > index 4c5bae7ca01c..d690b08dff2a 100644
> > --- a/arch/riscv/include/asm/set_memory.h
> > +++ b/arch/riscv/include/asm/set_memory.h
> > @@ -24,6 +24,7 @@ static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > #endif /* __ASSEMBLY__ */
> > diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
> > index 321b09d2e2ea..87ba5a68bbb8 100644
> > --- a/arch/riscv/mm/pageattr.c
> > +++ b/arch/riscv/mm/pageattr.c
> > @@ -198,3 +198,32 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > __pgprot(0), __pgprot(_PAGE_PRESENT));
> > }
> > #endif
> > +
> > +bool kernel_page_present(struct page *page)
> > +{
> > + unsigned long addr = (unsigned long)page_address(page);
> > + pgd_t *pgd;
> > + pud_t *pud;
> > + p4d_t *p4d;
> > + pmd_t *pmd;
> > + pte_t *pte;
> > +
> > + pgd = pgd_offset_k(addr);
> > + if (!pgd_present(*pgd))
> > + return false;
> > +
> > + p4d = p4d_offset(pgd, addr);
> > + if (!p4d_present(*p4d))
> > + return false;
> > +
> > + pud = pud_offset(p4d, addr);
> > + if (!pud_present(*pud))
> > + return false;
> > +
> > + pmd = pmd_offset(pud, addr);
> > + if (!pmd_present(*pmd))
> > + return false;
> > +
> > + pte = pte_offset_kernel(pmd, addr);
> > + return pte_present(*pte);
> > +}
> > diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
> > index 5948218f35c5..4352f08bfbb5 100644
> > --- a/arch/x86/include/asm/set_memory.h
> > +++ b/arch/x86/include/asm/set_memory.h
> > @@ -82,6 +82,7 @@ int set_pages_rw(struct page *page, int numpages);
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > extern int kernel_set_to_readonly;
> > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> > index bc9be96b777f..16f878c26667 100644
> > --- a/arch/x86/mm/pat/set_memory.c
> > +++ b/arch/x86/mm/pat/set_memory.c
> > @@ -2226,8 +2226,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > arch_flush_lazy_mmu_mode();
> > }
> > +#endif /* CONFIG_DEBUG_PAGEALLOC */
> > -#ifdef CONFIG_HIBERNATION
> > bool kernel_page_present(struct page *page)
> > {
> > unsigned int level;
> > @@ -2239,8 +2239,6 @@ bool kernel_page_present(struct page *page)
> > pte = lookup_address((unsigned long)page_address(page), &level);
> > return (pte_val(*pte) & _PAGE_PRESENT);
> > }
> > -#endif /* CONFIG_HIBERNATION */
> > -#endif /* CONFIG_DEBUG_PAGEALLOC */
> > int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
> > unsigned numpages, unsigned long page_flags)
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index ab0ef6bd351d..44b82f22e76a 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -2937,16 +2937,9 @@ static inline void debug_pagealloc_map_pages(struct page *page,
> > if (debug_pagealloc_enabled_static())
> > __kernel_map_pages(page, numpages, enable);
> > }
> > -
> > -#ifdef CONFIG_HIBERNATION
> > -extern bool kernel_page_present(struct page *page);
> > -#endif /* CONFIG_HIBERNATION */
> > #else /* CONFIG_DEBUG_PAGEALLOC */
> > static inline void debug_pagealloc_map_pages(struct page *page,
> > int numpages, int enable) {}
> > -#ifdef CONFIG_HIBERNATION
> > -static inline bool kernel_page_present(struct page *page) { return true; }
> > -#endif /* CONFIG_HIBERNATION */
> > #endif /* CONFIG_DEBUG_PAGEALLOC */
> > #ifdef __HAVE_ARCH_GATE_AREA
> > diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
> > index 860e0f843c12..fe1aa4e54680 100644
> > --- a/include/linux/set_memory.h
> > +++ b/include/linux/set_memory.h
> > @@ -23,6 +23,11 @@ static inline int set_direct_map_default_noflush(struct page *page)
> > {
> > return 0;
> > }
> > +
> > +static inline bool kernel_page_present(struct page *page)
> > +{
> > + return true;
> > +}
> > #endif
> > #ifndef set_mce_nospec
> >
>
> It's somewhat weird to move this to set_memory.h - it's only one possible
> user. I think include/linux/mm.h is a better fit. Ack to making it
> independent of CONFIG_HIBERNATION.
Semantically this is a part of direct map manipulation, that's primarily
why I put it into set_memory.h
> in include/linux/mm.h , I'd prefer:
>
> #if defined(CONFIG_DEBUG_PAGEALLOC) || \
> defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP)
The second reason was to avoid this ^
and the third is -7 lines to include/linux/mm.h :)
> bool kernel_page_present(struct page *page);
> #else
> static inline bool kernel_page_present(struct page *page)
> {
> return true;
> }
> #endif
>
> --
> Thanks,
>
> David / dhildenb
>
>
--
Sincerely yours,
Mike.
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
WARNING: multiple messages have this Message-ID (diff)
From: Mike Rapoport <rppt@kernel.org>
To: David Hildenbrand <david@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
linux-mm@kvack.org, Paul Mackerras <paulus@samba.org>,
Pavel Machek <pavel@ucw.cz>, "H. Peter Anvin" <hpa@zytor.com>,
sparclinux@vger.kernel.org, Christoph Lameter <cl@linux.com>,
Will Deacon <will@kernel.org>,
linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org,
x86@kernel.org, Mike Rapoport <rppt@linux.ibm.com>,
Christian Borntraeger <borntraeger@de.ibm.com>,
Ingo Molnar <mingo@redhat.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Len Brown <len.brown@intel.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Vasily Gorbik <gor@linux.ibm.com>,
linux-pm@vger.kernel.org, Heiko Carstens <hca@linux.ibm.com>,
David Rientjes <rientjes@google.com>,
Borislav Petkov <bp@alien8.de>, Andy Lutomirski <luto@kernel.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
"Kirill A. Shutemov" <kirill@shutemov.name>,
Thomas Gleixner <tglx@linutronix.de>,
Joonsoo Kim <iamjoonsoo.kim@lge.com>,
linux-arm-kernel@lists.infradead.org,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
linux-kernel@vger.kernel.org, Pekka Enberg <penberg@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Andrew Morton <akpm@linux-foundation.org>,
"Edgecombe, Rick P" <rick.p.edgecombe@intel.com>,
linuxppc-dev@lists.ozlabs.org,
"David S. Miller" <davem@davemloft.net>
Subject: Re: [PATCH v3 4/4] arch, mm: make kernel_page_present() always available
Date: Mon, 2 Nov 2020 17:18:29 +0200 [thread overview]
Message-ID: <20201102151829.GC4879@kernel.org> (raw)
In-Reply-To: <08db307a-b093-d7aa-7364-045f328ab147@redhat.com>
On Mon, Nov 02, 2020 at 10:28:14AM +0100, David Hildenbrand wrote:
> On 01.11.20 18:08, Mike Rapoport wrote:
> > From: Mike Rapoport <rppt@linux.ibm.com>
> >
> > For architectures that enable ARCH_HAS_SET_MEMORY having the ability to
> > verify that a page is mapped in the kernel direct map can be useful
> > regardless of hibernation.
> >
> > Add RISC-V implementation of kernel_page_present(), update its forward
> > declarations and stubs to be a part of set_memory API and remove ugly
> > ifdefery in inlcude/linux/mm.h around current declarations of
> > kernel_page_present().
> >
> > Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> > ---
> > arch/arm64/include/asm/cacheflush.h | 1 +
> > arch/arm64/mm/pageattr.c | 4 +---
> > arch/riscv/include/asm/set_memory.h | 1 +
> > arch/riscv/mm/pageattr.c | 29 +++++++++++++++++++++++++++++
> > arch/x86/include/asm/set_memory.h | 1 +
> > arch/x86/mm/pat/set_memory.c | 4 +---
> > include/linux/mm.h | 7 -------
> > include/linux/set_memory.h | 5 +++++
> > 8 files changed, 39 insertions(+), 13 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> > index 9384fd8fc13c..45217f21f1fe 100644
> > --- a/arch/arm64/include/asm/cacheflush.h
> > +++ b/arch/arm64/include/asm/cacheflush.h
> > @@ -140,6 +140,7 @@ int set_memory_valid(unsigned long addr, int numpages, int enable);
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > #include <asm-generic/cacheflush.h>
> > diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> > index 439325532be1..92eccaf595c8 100644
> > --- a/arch/arm64/mm/pageattr.c
> > +++ b/arch/arm64/mm/pageattr.c
> > @@ -186,8 +186,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > set_memory_valid((unsigned long)page_address(page), numpages, enable);
> > }
> > +#endif /* CONFIG_DEBUG_PAGEALLOC */
> > -#ifdef CONFIG_HIBERNATION
> > /*
> > * This function is used to determine if a linear map page has been marked as
> > * not-valid. Walk the page table and check the PTE_VALID bit. This is based
> > @@ -234,5 +234,3 @@ bool kernel_page_present(struct page *page)
> > ptep = pte_offset_kernel(pmdp, addr);
> > return pte_valid(READ_ONCE(*ptep));
> > }
> > -#endif /* CONFIG_HIBERNATION */
> > -#endif /* CONFIG_DEBUG_PAGEALLOC */
> > diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
> > index 4c5bae7ca01c..d690b08dff2a 100644
> > --- a/arch/riscv/include/asm/set_memory.h
> > +++ b/arch/riscv/include/asm/set_memory.h
> > @@ -24,6 +24,7 @@ static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > #endif /* __ASSEMBLY__ */
> > diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
> > index 321b09d2e2ea..87ba5a68bbb8 100644
> > --- a/arch/riscv/mm/pageattr.c
> > +++ b/arch/riscv/mm/pageattr.c
> > @@ -198,3 +198,32 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > __pgprot(0), __pgprot(_PAGE_PRESENT));
> > }
> > #endif
> > +
> > +bool kernel_page_present(struct page *page)
> > +{
> > + unsigned long addr = (unsigned long)page_address(page);
> > + pgd_t *pgd;
> > + pud_t *pud;
> > + p4d_t *p4d;
> > + pmd_t *pmd;
> > + pte_t *pte;
> > +
> > + pgd = pgd_offset_k(addr);
> > + if (!pgd_present(*pgd))
> > + return false;
> > +
> > + p4d = p4d_offset(pgd, addr);
> > + if (!p4d_present(*p4d))
> > + return false;
> > +
> > + pud = pud_offset(p4d, addr);
> > + if (!pud_present(*pud))
> > + return false;
> > +
> > + pmd = pmd_offset(pud, addr);
> > + if (!pmd_present(*pmd))
> > + return false;
> > +
> > + pte = pte_offset_kernel(pmd, addr);
> > + return pte_present(*pte);
> > +}
> > diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
> > index 5948218f35c5..4352f08bfbb5 100644
> > --- a/arch/x86/include/asm/set_memory.h
> > +++ b/arch/x86/include/asm/set_memory.h
> > @@ -82,6 +82,7 @@ int set_pages_rw(struct page *page, int numpages);
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > extern int kernel_set_to_readonly;
> > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> > index bc9be96b777f..16f878c26667 100644
> > --- a/arch/x86/mm/pat/set_memory.c
> > +++ b/arch/x86/mm/pat/set_memory.c
> > @@ -2226,8 +2226,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > arch_flush_lazy_mmu_mode();
> > }
> > +#endif /* CONFIG_DEBUG_PAGEALLOC */
> > -#ifdef CONFIG_HIBERNATION
> > bool kernel_page_present(struct page *page)
> > {
> > unsigned int level;
> > @@ -2239,8 +2239,6 @@ bool kernel_page_present(struct page *page)
> > pte = lookup_address((unsigned long)page_address(page), &level);
> > return (pte_val(*pte) & _PAGE_PRESENT);
> > }
> > -#endif /* CONFIG_HIBERNATION */
> > -#endif /* CONFIG_DEBUG_PAGEALLOC */
> > int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
> > unsigned numpages, unsigned long page_flags)
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index ab0ef6bd351d..44b82f22e76a 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -2937,16 +2937,9 @@ static inline void debug_pagealloc_map_pages(struct page *page,
> > if (debug_pagealloc_enabled_static())
> > __kernel_map_pages(page, numpages, enable);
> > }
> > -
> > -#ifdef CONFIG_HIBERNATION
> > -extern bool kernel_page_present(struct page *page);
> > -#endif /* CONFIG_HIBERNATION */
> > #else /* CONFIG_DEBUG_PAGEALLOC */
> > static inline void debug_pagealloc_map_pages(struct page *page,
> > int numpages, int enable) {}
> > -#ifdef CONFIG_HIBERNATION
> > -static inline bool kernel_page_present(struct page *page) { return true; }
> > -#endif /* CONFIG_HIBERNATION */
> > #endif /* CONFIG_DEBUG_PAGEALLOC */
> > #ifdef __HAVE_ARCH_GATE_AREA
> > diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
> > index 860e0f843c12..fe1aa4e54680 100644
> > --- a/include/linux/set_memory.h
> > +++ b/include/linux/set_memory.h
> > @@ -23,6 +23,11 @@ static inline int set_direct_map_default_noflush(struct page *page)
> > {
> > return 0;
> > }
> > +
> > +static inline bool kernel_page_present(struct page *page)
> > +{
> > + return true;
> > +}
> > #endif
> > #ifndef set_mce_nospec
> >
>
> It's somewhat weird to move this to set_memory.h - it's only one possible
> user. I think include/linux/mm.h is a better fit. Ack to making it
> independent of CONFIG_HIBERNATION.
Semantically this is a part of direct map manipulation, that's primarily
why I put it into set_memory.h
> in include/linux/mm.h , I'd prefer:
>
> #if defined(CONFIG_DEBUG_PAGEALLOC) || \
> defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP)
The second reason was to avoid this ^
and the third is -7 lines to include/linux/mm.h :)
> bool kernel_page_present(struct page *page);
> #else
> static inline bool kernel_page_present(struct page *page)
> {
> return true;
> }
> #endif
>
> --
> Thanks,
>
> David / dhildenb
>
>
--
Sincerely yours,
Mike.
WARNING: multiple messages have this Message-ID (diff)
From: Mike Rapoport <rppt@kernel.org>
To: David Hildenbrand <david@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
linux-mm@kvack.org, Paul Mackerras <paulus@samba.org>,
Pavel Machek <pavel@ucw.cz>, "H. Peter Anvin" <hpa@zytor.com>,
sparclinux@vger.kernel.org, Christoph Lameter <cl@linux.com>,
Will Deacon <will@kernel.org>,
linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org,
Michael Ellerman <mpe@ellerman.id.au>,
x86@kernel.org, Mike Rapoport <rppt@linux.ibm.com>,
Christian Borntraeger <borntraeger@de.ibm.com>,
Ingo Molnar <mingo@redhat.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Len Brown <len.brown@intel.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Vasily Gorbik <gor@linux.ibm.com>,
linux-pm@vger.kernel.org, Heiko Carstens <hca@linux.ibm.com>,
David Rientjes <rientjes@google.com>,
Borislav Petkov <bp@alien8.de>, Andy Lutomirski <luto@kernel.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
"Kirill A. Shutemov" <kirill@shutemov.name>,
Thomas Gleixner <tglx@linutronix.de>,
Joonsoo Kim <iamjoonsoo.kim@lge.com>,
linux-arm-kernel@lists.infradead.org,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
linux-kernel@vger.kernel.org, Pekka Enberg <penberg@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Andrew Morton <akpm@linux-foundation.org>,
"Edgecombe, Rick P" <rick.p.edgecombe@intel.com>,
linuxppc-dev@lists.ozlabs.org,
"David S. Miller" <davem@davemloft.net>
Subject: Re: [PATCH v3 4/4] arch, mm: make kernel_page_present() always available
Date: Mon, 02 Nov 2020 15:18:29 +0000 [thread overview]
Message-ID: <20201102151829.GC4879@kernel.org> (raw)
In-Reply-To: <08db307a-b093-d7aa-7364-045f328ab147@redhat.com>
On Mon, Nov 02, 2020 at 10:28:14AM +0100, David Hildenbrand wrote:
> On 01.11.20 18:08, Mike Rapoport wrote:
> > From: Mike Rapoport <rppt@linux.ibm.com>
> >
> > For architectures that enable ARCH_HAS_SET_MEMORY having the ability to
> > verify that a page is mapped in the kernel direct map can be useful
> > regardless of hibernation.
> >
> > Add RISC-V implementation of kernel_page_present(), update its forward
> > declarations and stubs to be a part of set_memory API and remove ugly
> > ifdefery in inlcude/linux/mm.h around current declarations of
> > kernel_page_present().
> >
> > Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> > ---
> > arch/arm64/include/asm/cacheflush.h | 1 +
> > arch/arm64/mm/pageattr.c | 4 +---
> > arch/riscv/include/asm/set_memory.h | 1 +
> > arch/riscv/mm/pageattr.c | 29 +++++++++++++++++++++++++++++
> > arch/x86/include/asm/set_memory.h | 1 +
> > arch/x86/mm/pat/set_memory.c | 4 +---
> > include/linux/mm.h | 7 -------
> > include/linux/set_memory.h | 5 +++++
> > 8 files changed, 39 insertions(+), 13 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> > index 9384fd8fc13c..45217f21f1fe 100644
> > --- a/arch/arm64/include/asm/cacheflush.h
> > +++ b/arch/arm64/include/asm/cacheflush.h
> > @@ -140,6 +140,7 @@ int set_memory_valid(unsigned long addr, int numpages, int enable);
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > #include <asm-generic/cacheflush.h>
> > diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> > index 439325532be1..92eccaf595c8 100644
> > --- a/arch/arm64/mm/pageattr.c
> > +++ b/arch/arm64/mm/pageattr.c
> > @@ -186,8 +186,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > set_memory_valid((unsigned long)page_address(page), numpages, enable);
> > }
> > +#endif /* CONFIG_DEBUG_PAGEALLOC */
> > -#ifdef CONFIG_HIBERNATION
> > /*
> > * This function is used to determine if a linear map page has been marked as
> > * not-valid. Walk the page table and check the PTE_VALID bit. This is based
> > @@ -234,5 +234,3 @@ bool kernel_page_present(struct page *page)
> > ptep = pte_offset_kernel(pmdp, addr);
> > return pte_valid(READ_ONCE(*ptep));
> > }
> > -#endif /* CONFIG_HIBERNATION */
> > -#endif /* CONFIG_DEBUG_PAGEALLOC */
> > diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
> > index 4c5bae7ca01c..d690b08dff2a 100644
> > --- a/arch/riscv/include/asm/set_memory.h
> > +++ b/arch/riscv/include/asm/set_memory.h
> > @@ -24,6 +24,7 @@ static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > #endif /* __ASSEMBLY__ */
> > diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
> > index 321b09d2e2ea..87ba5a68bbb8 100644
> > --- a/arch/riscv/mm/pageattr.c
> > +++ b/arch/riscv/mm/pageattr.c
> > @@ -198,3 +198,32 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > __pgprot(0), __pgprot(_PAGE_PRESENT));
> > }
> > #endif
> > +
> > +bool kernel_page_present(struct page *page)
> > +{
> > + unsigned long addr = (unsigned long)page_address(page);
> > + pgd_t *pgd;
> > + pud_t *pud;
> > + p4d_t *p4d;
> > + pmd_t *pmd;
> > + pte_t *pte;
> > +
> > + pgd = pgd_offset_k(addr);
> > + if (!pgd_present(*pgd))
> > + return false;
> > +
> > + p4d = p4d_offset(pgd, addr);
> > + if (!p4d_present(*p4d))
> > + return false;
> > +
> > + pud = pud_offset(p4d, addr);
> > + if (!pud_present(*pud))
> > + return false;
> > +
> > + pmd = pmd_offset(pud, addr);
> > + if (!pmd_present(*pmd))
> > + return false;
> > +
> > + pte = pte_offset_kernel(pmd, addr);
> > + return pte_present(*pte);
> > +}
> > diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
> > index 5948218f35c5..4352f08bfbb5 100644
> > --- a/arch/x86/include/asm/set_memory.h
> > +++ b/arch/x86/include/asm/set_memory.h
> > @@ -82,6 +82,7 @@ int set_pages_rw(struct page *page, int numpages);
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > extern int kernel_set_to_readonly;
> > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> > index bc9be96b777f..16f878c26667 100644
> > --- a/arch/x86/mm/pat/set_memory.c
> > +++ b/arch/x86/mm/pat/set_memory.c
> > @@ -2226,8 +2226,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > arch_flush_lazy_mmu_mode();
> > }
> > +#endif /* CONFIG_DEBUG_PAGEALLOC */
> > -#ifdef CONFIG_HIBERNATION
> > bool kernel_page_present(struct page *page)
> > {
> > unsigned int level;
> > @@ -2239,8 +2239,6 @@ bool kernel_page_present(struct page *page)
> > pte = lookup_address((unsigned long)page_address(page), &level);
> > return (pte_val(*pte) & _PAGE_PRESENT);
> > }
> > -#endif /* CONFIG_HIBERNATION */
> > -#endif /* CONFIG_DEBUG_PAGEALLOC */
> > int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
> > unsigned numpages, unsigned long page_flags)
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index ab0ef6bd351d..44b82f22e76a 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -2937,16 +2937,9 @@ static inline void debug_pagealloc_map_pages(struct page *page,
> > if (debug_pagealloc_enabled_static())
> > __kernel_map_pages(page, numpages, enable);
> > }
> > -
> > -#ifdef CONFIG_HIBERNATION
> > -extern bool kernel_page_present(struct page *page);
> > -#endif /* CONFIG_HIBERNATION */
> > #else /* CONFIG_DEBUG_PAGEALLOC */
> > static inline void debug_pagealloc_map_pages(struct page *page,
> > int numpages, int enable) {}
> > -#ifdef CONFIG_HIBERNATION
> > -static inline bool kernel_page_present(struct page *page) { return true; }
> > -#endif /* CONFIG_HIBERNATION */
> > #endif /* CONFIG_DEBUG_PAGEALLOC */
> > #ifdef __HAVE_ARCH_GATE_AREA
> > diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
> > index 860e0f843c12..fe1aa4e54680 100644
> > --- a/include/linux/set_memory.h
> > +++ b/include/linux/set_memory.h
> > @@ -23,6 +23,11 @@ static inline int set_direct_map_default_noflush(struct page *page)
> > {
> > return 0;
> > }
> > +
> > +static inline bool kernel_page_present(struct page *page)
> > +{
> > + return true;
> > +}
> > #endif
> > #ifndef set_mce_nospec
> >
>
> It's somewhat weird to move this to set_memory.h - it's only one possible
> user. I think include/linux/mm.h is a better fit. Ack to making it
> independent of CONFIG_HIBERNATION.
Semantically this is a part of direct map manipulation, that's primarily
why I put it into set_memory.h
> in include/linux/mm.h , I'd prefer:
>
> #if defined(CONFIG_DEBUG_PAGEALLOC) || \
> defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP)
The second reason was to avoid this ^
and the third is -7 lines to include/linux/mm.h :)
> bool kernel_page_present(struct page *page);
> #else
> static inline bool kernel_page_present(struct page *page)
> {
> return true;
> }
> #endif
>
> --
> Thanks,
>
> David / dhildenb
>
>
--
Sincerely yours,
Mike.
WARNING: multiple messages have this Message-ID (diff)
From: Mike Rapoport <rppt@kernel.org>
To: David Hildenbrand <david@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
linux-mm@kvack.org, Paul Mackerras <paulus@samba.org>,
Pavel Machek <pavel@ucw.cz>, "H. Peter Anvin" <hpa@zytor.com>,
sparclinux@vger.kernel.org, Christoph Lameter <cl@linux.com>,
Will Deacon <will@kernel.org>,
linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org,
Michael Ellerman <mpe@ellerman.id.au>,
x86@kernel.org, Mike Rapoport <rppt@linux.ibm.com>,
Christian Borntraeger <borntraeger@de.ibm.com>,
Ingo Molnar <mingo@redhat.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Len Brown <len.brown@intel.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Vasily Gorbik <gor@linux.ibm.com>,
linux-pm@vger.kernel.org, Heiko Carstens <hca@linux.ibm.com>,
David Rientjes <rientjes@google.com>,
Borislav Petkov <bp@alien8.de>, Andy Lutomirski <luto@kernel.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
"Kirill A. Shutemov" <kirill@shutemov.name>,
Thomas Gleixner <tglx@linutronix.de>,
Joonsoo Kim <iamjoonsoo.kim@lge.com>,
linux-arm-kernel@lists.infradead.org,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
linux-kernel@vger.kernel.org, Pekka Enberg <penberg@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Andrew Morton <akpm@linux-foundation.org>,
"Edgecombe, Rick P" <rick.p.edgecombe@intel.com>,
linuxppc-dev@lists.ozlabs.org,
"David S. Miller" <davem@davemloft.net>
Subject: Re: [PATCH v3 4/4] arch, mm: make kernel_page_present() always available
Date: Mon, 2 Nov 2020 17:18:29 +0200 [thread overview]
Message-ID: <20201102151829.GC4879@kernel.org> (raw)
In-Reply-To: <08db307a-b093-d7aa-7364-045f328ab147@redhat.com>
On Mon, Nov 02, 2020 at 10:28:14AM +0100, David Hildenbrand wrote:
> On 01.11.20 18:08, Mike Rapoport wrote:
> > From: Mike Rapoport <rppt@linux.ibm.com>
> >
> > For architectures that enable ARCH_HAS_SET_MEMORY having the ability to
> > verify that a page is mapped in the kernel direct map can be useful
> > regardless of hibernation.
> >
> > Add RISC-V implementation of kernel_page_present(), update its forward
> > declarations and stubs to be a part of set_memory API and remove ugly
> > ifdefery in inlcude/linux/mm.h around current declarations of
> > kernel_page_present().
> >
> > Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> > ---
> > arch/arm64/include/asm/cacheflush.h | 1 +
> > arch/arm64/mm/pageattr.c | 4 +---
> > arch/riscv/include/asm/set_memory.h | 1 +
> > arch/riscv/mm/pageattr.c | 29 +++++++++++++++++++++++++++++
> > arch/x86/include/asm/set_memory.h | 1 +
> > arch/x86/mm/pat/set_memory.c | 4 +---
> > include/linux/mm.h | 7 -------
> > include/linux/set_memory.h | 5 +++++
> > 8 files changed, 39 insertions(+), 13 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> > index 9384fd8fc13c..45217f21f1fe 100644
> > --- a/arch/arm64/include/asm/cacheflush.h
> > +++ b/arch/arm64/include/asm/cacheflush.h
> > @@ -140,6 +140,7 @@ int set_memory_valid(unsigned long addr, int numpages, int enable);
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > #include <asm-generic/cacheflush.h>
> > diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> > index 439325532be1..92eccaf595c8 100644
> > --- a/arch/arm64/mm/pageattr.c
> > +++ b/arch/arm64/mm/pageattr.c
> > @@ -186,8 +186,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > set_memory_valid((unsigned long)page_address(page), numpages, enable);
> > }
> > +#endif /* CONFIG_DEBUG_PAGEALLOC */
> > -#ifdef CONFIG_HIBERNATION
> > /*
> > * This function is used to determine if a linear map page has been marked as
> > * not-valid. Walk the page table and check the PTE_VALID bit. This is based
> > @@ -234,5 +234,3 @@ bool kernel_page_present(struct page *page)
> > ptep = pte_offset_kernel(pmdp, addr);
> > return pte_valid(READ_ONCE(*ptep));
> > }
> > -#endif /* CONFIG_HIBERNATION */
> > -#endif /* CONFIG_DEBUG_PAGEALLOC */
> > diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
> > index 4c5bae7ca01c..d690b08dff2a 100644
> > --- a/arch/riscv/include/asm/set_memory.h
> > +++ b/arch/riscv/include/asm/set_memory.h
> > @@ -24,6 +24,7 @@ static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > #endif /* __ASSEMBLY__ */
> > diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
> > index 321b09d2e2ea..87ba5a68bbb8 100644
> > --- a/arch/riscv/mm/pageattr.c
> > +++ b/arch/riscv/mm/pageattr.c
> > @@ -198,3 +198,32 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > __pgprot(0), __pgprot(_PAGE_PRESENT));
> > }
> > #endif
> > +
> > +bool kernel_page_present(struct page *page)
> > +{
> > + unsigned long addr = (unsigned long)page_address(page);
> > + pgd_t *pgd;
> > + pud_t *pud;
> > + p4d_t *p4d;
> > + pmd_t *pmd;
> > + pte_t *pte;
> > +
> > + pgd = pgd_offset_k(addr);
> > + if (!pgd_present(*pgd))
> > + return false;
> > +
> > + p4d = p4d_offset(pgd, addr);
> > + if (!p4d_present(*p4d))
> > + return false;
> > +
> > + pud = pud_offset(p4d, addr);
> > + if (!pud_present(*pud))
> > + return false;
> > +
> > + pmd = pmd_offset(pud, addr);
> > + if (!pmd_present(*pmd))
> > + return false;
> > +
> > + pte = pte_offset_kernel(pmd, addr);
> > + return pte_present(*pte);
> > +}
> > diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
> > index 5948218f35c5..4352f08bfbb5 100644
> > --- a/arch/x86/include/asm/set_memory.h
> > +++ b/arch/x86/include/asm/set_memory.h
> > @@ -82,6 +82,7 @@ int set_pages_rw(struct page *page, int numpages);
> > int set_direct_map_invalid_noflush(struct page *page);
> > int set_direct_map_default_noflush(struct page *page);
> > +bool kernel_page_present(struct page *page);
> > extern int kernel_set_to_readonly;
> > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> > index bc9be96b777f..16f878c26667 100644
> > --- a/arch/x86/mm/pat/set_memory.c
> > +++ b/arch/x86/mm/pat/set_memory.c
> > @@ -2226,8 +2226,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
> > arch_flush_lazy_mmu_mode();
> > }
> > +#endif /* CONFIG_DEBUG_PAGEALLOC */
> > -#ifdef CONFIG_HIBERNATION
> > bool kernel_page_present(struct page *page)
> > {
> > unsigned int level;
> > @@ -2239,8 +2239,6 @@ bool kernel_page_present(struct page *page)
> > pte = lookup_address((unsigned long)page_address(page), &level);
> > return (pte_val(*pte) & _PAGE_PRESENT);
> > }
> > -#endif /* CONFIG_HIBERNATION */
> > -#endif /* CONFIG_DEBUG_PAGEALLOC */
> > int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
> > unsigned numpages, unsigned long page_flags)
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index ab0ef6bd351d..44b82f22e76a 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -2937,16 +2937,9 @@ static inline void debug_pagealloc_map_pages(struct page *page,
> > if (debug_pagealloc_enabled_static())
> > __kernel_map_pages(page, numpages, enable);
> > }
> > -
> > -#ifdef CONFIG_HIBERNATION
> > -extern bool kernel_page_present(struct page *page);
> > -#endif /* CONFIG_HIBERNATION */
> > #else /* CONFIG_DEBUG_PAGEALLOC */
> > static inline void debug_pagealloc_map_pages(struct page *page,
> > int numpages, int enable) {}
> > -#ifdef CONFIG_HIBERNATION
> > -static inline bool kernel_page_present(struct page *page) { return true; }
> > -#endif /* CONFIG_HIBERNATION */
> > #endif /* CONFIG_DEBUG_PAGEALLOC */
> > #ifdef __HAVE_ARCH_GATE_AREA
> > diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
> > index 860e0f843c12..fe1aa4e54680 100644
> > --- a/include/linux/set_memory.h
> > +++ b/include/linux/set_memory.h
> > @@ -23,6 +23,11 @@ static inline int set_direct_map_default_noflush(struct page *page)
> > {
> > return 0;
> > }
> > +
> > +static inline bool kernel_page_present(struct page *page)
> > +{
> > + return true;
> > +}
> > #endif
> > #ifndef set_mce_nospec
> >
>
> It's somewhat weird to move this to set_memory.h - it's only one possible
> user. I think include/linux/mm.h is a better fit. Ack to making it
> independent of CONFIG_HIBERNATION.
Semantically this is a part of direct map manipulation, that's primarily
why I put it into set_memory.h
> in include/linux/mm.h , I'd prefer:
>
> #if defined(CONFIG_DEBUG_PAGEALLOC) || \
> defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP)
The second reason was to avoid this ^
and the third is -7 lines to include/linux/mm.h :)
> bool kernel_page_present(struct page *page);
> #else
> static inline bool kernel_page_present(struct page *page)
> {
> return true;
> }
> #endif
>
> --
> Thanks,
>
> David / dhildenb
>
>
--
Sincerely yours,
Mike.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-11-02 15:18 UTC|newest]
Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-01 17:08 [PATCH v3 0/4] arch, mm: improve robustness of direct map manipulation Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` [PATCH v3 1/4] mm: introduce debug_pagealloc_map_pages() helper Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` [PATCH v3 2/4] PM: hibernate: make direct map manipulations more explicit Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-02 9:19 ` David Hildenbrand
2020-11-02 9:19 ` David Hildenbrand
2020-11-02 9:19 ` David Hildenbrand
2020-11-02 9:19 ` David Hildenbrand
2020-11-02 9:19 ` David Hildenbrand
2020-11-02 15:12 ` Mike Rapoport
2020-11-02 15:12 ` Mike Rapoport
2020-11-02 15:12 ` Mike Rapoport
2020-11-02 15:12 ` Mike Rapoport
2020-11-02 15:12 ` Mike Rapoport
2020-11-03 11:08 ` Kirill A. Shutemov
2020-11-03 11:08 ` Kirill A. Shutemov
2020-11-03 11:08 ` Kirill A. Shutemov
2020-11-03 11:08 ` Kirill A. Shutemov
2020-11-03 11:08 ` Kirill A. Shutemov
2020-11-03 12:13 ` Mike Rapoport
2020-11-03 12:13 ` Mike Rapoport
2020-11-03 12:13 ` Mike Rapoport
2020-11-03 12:13 ` Mike Rapoport
2020-11-03 12:13 ` Mike Rapoport
2020-11-03 14:39 ` Kirill A. Shutemov
2020-11-03 14:39 ` Kirill A. Shutemov
2020-11-03 14:39 ` Kirill A. Shutemov
2020-11-03 14:39 ` Kirill A. Shutemov
2020-11-03 14:39 ` Kirill A. Shutemov
2020-11-03 15:56 ` Mike Rapoport
2020-11-03 15:56 ` Mike Rapoport
2020-11-03 15:56 ` Mike Rapoport
2020-11-03 15:56 ` Mike Rapoport
2020-11-03 15:56 ` Mike Rapoport
2020-11-01 17:08 ` [PATCH v3 3/4] arch, mm: restore dependency of __kernel_map_pages() of DEBUG_PAGEALLOC Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-02 9:23 ` David Hildenbrand
2020-11-02 9:23 ` David Hildenbrand
2020-11-02 9:23 ` David Hildenbrand
2020-11-02 9:23 ` David Hildenbrand
2020-11-02 9:23 ` David Hildenbrand
2020-11-02 15:15 ` Mike Rapoport
2020-11-02 15:15 ` Mike Rapoport
2020-11-02 15:15 ` Mike Rapoport
2020-11-02 15:15 ` Mike Rapoport
2020-11-02 15:15 ` Mike Rapoport
2020-11-01 17:08 ` [PATCH v3 4/4] arch, mm: make kernel_page_present() always available Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-01 17:08 ` Mike Rapoport
2020-11-02 9:28 ` David Hildenbrand
2020-11-02 9:28 ` David Hildenbrand
2020-11-02 9:28 ` David Hildenbrand
2020-11-02 9:28 ` David Hildenbrand
2020-11-02 9:28 ` David Hildenbrand
2020-11-02 15:18 ` Mike Rapoport [this message]
2020-11-02 15:18 ` Mike Rapoport
2020-11-02 15:18 ` Mike Rapoport
2020-11-02 15:18 ` Mike Rapoport
2020-11-02 15:18 ` Mike Rapoport
2020-11-03 11:15 ` [PATCH v3 0/4] arch, mm: improve robustness of direct map manipulation Kirill A. Shutemov
2020-11-03 11:15 ` Kirill A. Shutemov
2020-11-03 11:15 ` Kirill A. Shutemov
2020-11-03 11:15 ` Kirill A. Shutemov
2020-11-03 11:15 ` Kirill A. Shutemov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201102151829.GC4879@kernel.org \
--to=rppt@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=aou@eecs.berkeley.edu \
--cc=benh@kernel.crashing.org \
--cc=borntraeger@de.ibm.com \
--cc=bp@alien8.de \
--cc=catalin.marinas@arm.com \
--cc=cl@linux.com \
--cc=dave.hansen@linux.intel.com \
--cc=davem@davemloft.net \
--cc=david@redhat.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=hpa@zytor.com \
--cc=iamjoonsoo.kim@lge.com \
--cc=kirill@shutemov.name \
--cc=len.brown@intel.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-s390@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=mpe@ellerman.id.au \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=paulus@samba.org \
--cc=pavel@ucw.cz \
--cc=penberg@kernel.org \
--cc=peterz@infradead.org \
--cc=rick.p.edgecombe@intel.com \
--cc=rientjes@google.com \
--cc=rjw@rjwysocki.net \
--cc=rppt@linux.ibm.com \
--cc=sparclinux@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=will@kernel.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.