* Re: [PATCH 02/21] mm: make early_pfn_to_nid() and related defintions close to each other
From: Baoquan He @ 2020-04-21 3:31 UTC (permalink / raw)
To: Mike Rapoport
Cc: Rich Felker, linux-ia64, linux-doc, Catalin Marinas,
Heiko Carstens, Michal Hocko, James E.J. Bottomley, Max Filippov,
Guo Ren, linux-csky, linux-parisc, sparclinux, linux-hexagon,
linux-riscv, Greg Ungerer, linux-arch, linux-s390, linux-snps-arc,
linux-c6x-dev, Brian Cain, Jonathan Corbet, linux-sh,
Helge Deller, x86, Russell King, Ley Foon Tan, Mike Rapoport,
Geert Uytterhoeven, linux-arm-kernel, Mark Salter, Matt Turner,
linux-mips, uclinux-h8-devel, linux-xtensa, linux-alpha, linux-um,
linux-m68k, Tony Luck, Greentime Hu, Paul Walmsley,
Stafford Horne, Guan Xuetao, Hoan Tran, Michal Simek,
Thomas Bogendoerfer, Yoshinori Sato, Nick Hu, linux-mm,
Vineet Gupta, linux-kernel, openrisc, Richard Weinberger,
Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <20200412194859.12663-3-rppt@kernel.org>
On 04/12/20 at 10:48pm, Mike Rapoport wrote:
> From: Mike Rapoport <rppt@linux.ibm.com>
>
> The early_pfn_to_nid() and it's helper __early_pfn_to_nid() are spread
> around include/linux/mm.h, include/linux/mmzone.h and mm/page_alloc.c.
>
> Drop unused stub for __early_pfn_to_nid() and move its actual generic
> implementation close to its users.
>
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> ---
> include/linux/mm.h | 4 ++--
> include/linux/mmzone.h | 9 --------
> mm/page_alloc.c | 51 +++++++++++++++++++++---------------------
> 3 files changed, 27 insertions(+), 37 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 5a323422d783..a404026d14d4 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2388,9 +2388,9 @@ extern void sparse_memory_present_with_active_regions(int nid);
>
> #if !defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) && \
> !defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID)
> -static inline int __early_pfn_to_nid(unsigned long pfn,
> - struct mminit_pfnnid_cache *state)
> +static inline int early_pfn_to_nid(unsigned long pfn)
> {
> + BUILD_BUG_ON(IS_ENABLED(CONFIG_NUMA));
> return 0;
> }
> #else
> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index 1b9de7d220fb..7b5b6eba402f 100644
> --- a/include/linux/mmzone.h
> +++ b/include/linux/mmzone.h
> @@ -1078,15 +1078,6 @@ static inline struct zoneref *first_zones_zonelist(struct zonelist *zonelist,
> #include <asm/sparsemem.h>
> #endif
>
> -#if !defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) && \
> - !defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP)
> -static inline unsigned long early_pfn_to_nid(unsigned long pfn)
> -{
> - BUILD_BUG_ON(IS_ENABLED(CONFIG_NUMA));
> - return 0;
> -}
> -#endif
> -
> #ifdef CONFIG_FLATMEM
> #define pfn_to_nid(pfn) (0)
> #endif
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 0d012eda1694..1ac775bfc9cf 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -1504,6 +1504,31 @@ void __free_pages_core(struct page *page, unsigned int order)
>
> static struct mminit_pfnnid_cache early_pfnnid_cache __meminitdata;
>
> +#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
> +
> +/*
> + * Required by SPARSEMEM. Given a PFN, return what node the PFN is on.
> + */
> +int __meminit __early_pfn_to_nid(unsigned long pfn,
> + struct mminit_pfnnid_cache *state)
> +{
> + unsigned long start_pfn, end_pfn;
> + int nid;
> +
> + if (state->last_start <= pfn && pfn < state->last_end)
> + return state->last_nid;
> +
> + nid = memblock_search_pfn_nid(pfn, &start_pfn, &end_pfn);
> + if (nid != NUMA_NO_NODE) {
> + state->last_start = start_pfn;
> + state->last_end = end_pfn;
> + state->last_nid = nid;
> + }
> +
> + return nid;
> +}
> +#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
> +
> int __meminit early_pfn_to_nid(unsigned long pfn)
> {
> static DEFINE_SPINLOCK(early_pfn_lock);
> @@ -6298,32 +6323,6 @@ void __meminit init_currently_empty_zone(struct zone *zone,
> zone->initialized = 1;
> }
>
> -#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
Here it's apparently removing CONFIG_HAVE_MEMBLOCK_NODE_MAP too early,
it should be done in patch 3, and its #end is kept there. I just found
it when I almost became dizzy in reviewing patch 3.
> -#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
> -
> -/*
> - * Required by SPARSEMEM. Given a PFN, return what node the PFN is on.
> - */
> -int __meminit __early_pfn_to_nid(unsigned long pfn,
> - struct mminit_pfnnid_cache *state)
> -{
> - unsigned long start_pfn, end_pfn;
> - int nid;
> -
> - if (state->last_start <= pfn && pfn < state->last_end)
> - return state->last_nid;
> -
> - nid = memblock_search_pfn_nid(pfn, &start_pfn, &end_pfn);
> - if (nid != NUMA_NO_NODE) {
> - state->last_start = start_pfn;
> - state->last_end = end_pfn;
> - state->last_nid = nid;
> - }
> -
> - return nid;
> -}
> -#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
> -
> /**
> * free_bootmem_with_active_regions - Call memblock_free_early_nid for each active range
> * @nid: The node to free memory on. If MAX_NUMNODES, all nodes are freed.
> --
> 2.25.1
>
^ permalink raw reply
* Re: [PATCH v2 5/5] uaccess: Rename user_access_begin/end() to user_full_access_begin/end()
From: Al Viro @ 2020-04-21 2:49 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-arch, Kees Cook, Dave Airlie, intel-gfx, Peter Anvin,
Linux Kernel Mailing List, Russell King, Linux-MM, Paul Mackerras,
Daniel Vetter, Andrew Morton, linuxppc-dev
In-Reply-To: <20200403205205.GK23230@ZenIV.linux.org.uk>
[rmk Cc'd]
On Fri, Apr 03, 2020 at 09:52:05PM +0100, Al Viro wrote:
> I can do a 5.7-rc1-based branch with that; depending upon what we end
> up doing for arm and s390 we can always change the calling conventions
> come next cycle ;-/
>
> My impressions after digging through arm side of things:
>
> 1) the only instance of nesting I'd found there (so far) is a mistake.
> The rule should be "no fucking nesting, TYVM".
OK, after quite a bit of digging:
1) everything outside of arm is quite happy with not passing
anything to user_access_end(). s390 is a red herring in that respect.
2) on arm we definitely can get rid of nesting. However,
there are some unpleasant sides of the logics in there. What we have
is an MMU register; everything except for two 2bit fields in it is
constant. One of those fields is a function of get_fs(), another might
serve an analogue of x86 EFLAGS.AC. Rules:
DACR.USER is 0 if CONFIG_SW_DOMAIN_PAN is enabled and we are
*not* in uaccess section; otherwise it's 1.
DACR.KERNEL is 3 if CONFIG_USE_DOMAINS is enabled and we are
under KERNEL_DS; otherwise it's 1.
[USE_DOMAINS is forced to "yes" on v5 and earlier, configurable on v6+]
[SW_DOMAIN_PAN is forced to "no" on v7 if we want support of huge physical
space, configurable with default to "yes" otherwise]
On entry into kernel we get into USER_DS state before we get
out of asm glue. Original settings are restored on return. That goes
both for ->addr_limit (get_fs() value) and for DACR.KERNEL contents.
DACR.USER ("uaccess allowed") is switched to "disabled" state before
we reach C code and restored on return from kernel.
The costs are interesting; setting the register is costly, in
the same manner STAC/CLAC is. Reading it... hell knows; I don't see any
explicit information about that. As it is, both set_fs() and starting
uaccess block (uaccess_save_and_enable() - the thing that would've
gone into user_access_begin()) do both read and write to register; with
minimal massage we could get rid of reading the damn thing in set_fs().
user_access_end() candidate does a plain write to register, with value
kept around since the beginning of uaccess block.
*IF* read from that register is cheap, we can trivially get rid
of passing the cookie there - it's a matter of reading the register
and clearing one bit in it before writing it back. If that is costly,
though... We can easily calculate it from ->addr_limit, which we already
have in cache at that point, or will need shortly anyway. In that
case it would probably make sense to do the same to user_access_begin()
and set_fs(). Note that I'm not suggesting to do anything of that sort
in switch_to() - existing mechanism doesn't need any changes, and neither
does the asm glue in entry*.S.
The only source I'd been able to find speeks of >= 60 cycles
(and possibly much more) for non-pipelined coprocessor instructions;
the list of such does contain loads and stores to a bunch of registers.
However, the register in question (p15/c3) has only store mentioned there,
so loads might be cheap; no obvious reasons for those to be slow.
That's a question to arm folks, I'm afraid... rmk?
Note that we can keep the current variant (i.e.
user_access_begin() being just the check for access_ok(), user_access_end()
being empty and uaccess_save_and_enable()/uaccess_restore() done manually
inside the primitives); after all, a lot of architectures don't _have_
anything of that sort. It's just that decisions regarding the calling
conventions for these primitives will be much harder to change later on...
Again, arm (32bit one) is the only architectures that has something
of that sort and needs to pass cookie from beginning to the end of uaccess
blocks. Everything else splits into several classes:
1) has MMU, shared address space for kernel/userland, no stac analogues.
alpha, arc, csky, hexagon, itanic, nds32, nios32, openrisc, sh,
sparc32, unicore32, xtensa/MMU, microblaze/MMU, mips/MMU,
m68k/MMU/COLDFIRE.
No way to do anything other than plain access_ok() for user_access_begin().
2) has MMU, shared address space for kernel/userland, has stac analogue,
possibly with separate "for read" and "for write" variants. Can live
without passing any cookies.
arm64, powerpc, riscv, x86
Current variant with changes in this patchset covers those.
3) non-MMU, uses memcpy() for everything, or at least ought to:
c6x, h8300, m68k/!MMU, xtensa/!MMU(?), microblaze/!MMU(?), mips/!MMU(?),
arm/!MMU
No memory protection of any sort...
4) sparc-like: MMU, separate address spaces for userland and kernel,
has explicit insns for uaccess + some register(s) to choose what those
insns actually hit.
sparc64, parisc, m68k/MMU/!COLDFIRE
No stac/clac analogue would make sense.
5) s390: weird one - there is an stac analogue as far the hardware is
concerned, but it can't be separated from inline asm where
actual uaccess insns are. From the kernel POV it's sparc-like.
Nothing that would reasonably map to user_access_begin/user_access_end
6) um: no uaccess, in a sense of dereferencing non-kernel pointers. What
it does is simulation of page table walk + explicit call of #PF handler
on missing pages + kmap_atomic() to get a kernel alias.
^ permalink raw reply
* [PATCH V17 2/2] mm/debug: Add tests validating architecture page table helpers
From: Anshuman Khandual @ 2020-04-21 2:34 UTC (permalink / raw)
To: linux-mm
Cc: Heiko Carstens, Paul Mackerras, H. Peter Anvin, linux-riscv,
Will Deacon, linux-arch, linux-s390, x86, Mike Rapoport,
Christian Borntraeger, Ingo Molnar, Catalin Marinas,
linux-snps-arc, Vasily Gorbik, Anshuman Khandual, Borislav Petkov,
Paul Walmsley, Kirill A . Shutemov, Thomas Gleixner,
linux-arm-kernel, Vineet Gupta, linux-kernel, Palmer Dabbelt,
Qian Cai, Andrew Morton, linuxppc-dev
In-Reply-To: <1587436495-22033-1-git-send-email-anshuman.khandual@arm.com>
This adds tests which will validate architecture page table helpers and
other accessors in their compliance with expected generic MM semantics.
This will help various architectures in validating changes to existing
page table helpers or addition of new ones.
This test covers basic page table entry transformations including but not
limited to old, young, dirty, clean, write, write protect etc at various
level along with populating intermediate entries with next page table page
and validating them.
Test page table pages are allocated from system memory with required size
and alignments. The mapped pfns at page table levels are derived from a
real pfn representing a valid kernel text symbol. This test gets called
via late_initcall().
This test gets built and run when CONFIG_DEBUG_VM_PGTABLE is selected. Any
architecture, which is willing to subscribe this test will need to select
ARCH_HAS_DEBUG_VM_PGTABLE. For now this is limited to arc, arm64, x86, s390
and powerpc platforms where the test is known to build and run successfully
Going forward, other architectures too can subscribe the test after fixing
any build or runtime problems with their page table helpers. Meanwhile for
better platform coverage, the test can also be enabled with CONFIG_EXPERT
even without ARCH_HAS_DEBUG_VM_PGTABLE.
Folks interested in making sure that a given platform's page table helpers
conform to expected generic MM semantics should enable the above config
which will just trigger this test during boot. Any non conformity here will
be reported as an warning which would need to be fixed. This test will help
catch any changes to the agreed upon semantics expected from generic MM and
enable platforms to accommodate it thereafter.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mike Rapoport <rppt@linux.ibm.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: linux-snps-arc@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: linux-riscv@lists.infradead.org
Cc: x86@kernel.org
Cc: linux-arch@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Tested-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> # s390
Tested-by: Christophe Leroy <christophe.leroy@c-s.fr> # ppc32
Signed-off-by: Qian Cai <cai@lca.pw>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
.../debug/debug-vm-pgtable/arch-support.txt | 34 ++
arch/arc/Kconfig | 1 +
arch/arm64/Kconfig | 1 +
arch/powerpc/Kconfig | 1 +
arch/s390/Kconfig | 1 +
arch/x86/Kconfig | 1 +
lib/Kconfig.debug | 25 ++
mm/Makefile | 1 +
mm/debug_vm_pgtable.c | 382 ++++++++++++++++++
9 files changed, 447 insertions(+)
create mode 100644 Documentation/features/debug/debug-vm-pgtable/arch-support.txt
create mode 100644 mm/debug_vm_pgtable.c
diff --git a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
new file mode 100644
index 000000000000..c527d05c0459
--- /dev/null
+++ b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
@@ -0,0 +1,34 @@
+#
+# Feature name: debug-vm-pgtable
+# Kconfig: ARCH_HAS_DEBUG_VM_PGTABLE
+# description: arch supports pgtable tests for semantics compliance
+#
+ -----------------------
+ | arch |status|
+ -----------------------
+ | alpha: | TODO |
+ | arc: | ok |
+ | arm: | TODO |
+ | arm64: | ok |
+ | c6x: | TODO |
+ | csky: | TODO |
+ | h8300: | TODO |
+ | hexagon: | TODO |
+ | ia64: | TODO |
+ | m68k: | TODO |
+ | microblaze: | TODO |
+ | mips: | TODO |
+ | nds32: | TODO |
+ | nios2: | TODO |
+ | openrisc: | TODO |
+ | parisc: | TODO |
+ | powerpc: | ok |
+ | riscv: | TODO |
+ | s390: | ok |
+ | sh: | TODO |
+ | sparc: | TODO |
+ | um: | TODO |
+ | unicore32: | TODO |
+ | x86: | ok |
+ | xtensa: | TODO |
+ -----------------------
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index ff306246d0f8..471ef22216c4 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -6,6 +6,7 @@
config ARC
def_bool y
select ARC_TIMERS
+ select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_SETUP_DMA_OPS
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 40fb05d96c60..0efb46abaf3d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -10,6 +10,7 @@ config ARM64
select ACPI_SPCR_TABLE if ACPI
select ACPI_PPTT if ACPI
select ARCH_HAS_DEBUG_VIRTUAL
+ select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 924c541a9260..4e89f22cdd27 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -116,6 +116,7 @@ config PPC
#
select ARCH_32BIT_OFF_T if PPC32
select ARCH_HAS_DEBUG_VIRTUAL
+ select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 2167bce993ff..8206b2c19aa8 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -59,6 +59,7 @@ config KASAN_SHADOW_OFFSET
config S390
def_bool y
select ARCH_BINFMT_ELF_STATE
+ select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1d6104ea8af0..eaba476f4660 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -59,6 +59,7 @@ config X86
select ARCH_CLOCKSOURCE_INIT
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_DEBUG_VIRTUAL
+ select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FAST_MULTIPLIER
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 21d9c5f6e7ec..6a492e32579a 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -653,6 +653,12 @@ config SCHED_STACK_END_CHECK
data corruption or a sporadic crash at a later stage once the region
is examined. The runtime overhead introduced is minimal.
+config ARCH_HAS_DEBUG_VM_PGTABLE
+ bool
+ help
+ An architecture should select this when it can successfully
+ build and run DEBUG_VM_PGTABLE.
+
config DEBUG_VM
bool "Debug VM"
depends on DEBUG_KERNEL
@@ -688,6 +694,25 @@ config DEBUG_VM_PGFLAGS
If unsure, say N.
+config DEBUG_VM_PGTABLE
+ bool "Debug arch page table for semantics compliance"
+ depends on MMU
+ depends on !IA64 && !ARM
+ depends on ARCH_HAS_DEBUG_VM_PGTABLE || EXPERT
+ default y if ARCH_HAS_DEBUG_VM_PGTABLE && DEBUG_VM
+ help
+ This option provides a debug method which can be used to test
+ architecture page table helper functions on various platforms in
+ verifying if they comply with expected generic MM semantics. This
+ will help architecture code in making sure that any changes or
+ new additions of these helpers still conform to expected
+ semantics of the generic MM. Platforms will have to opt in for
+ this through ARCH_HAS_DEBUG_VM_PGTABLE. Although it can also be
+ enabled through EXPERT without requiring code change. This test
+ is disabled on IA64 and ARM platforms where it fails to build.
+
+ If unsure, say N.
+
config ARCH_HAS_DEBUG_VIRTUAL
bool
diff --git a/mm/Makefile b/mm/Makefile
index fccd3756b25f..662fd1504646 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o
obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o
obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o
obj-$(CONFIG_DEBUG_RODATA_TEST) += rodata_test.o
+obj-$(CONFIG_DEBUG_VM_PGTABLE) += debug_vm_pgtable.o
obj-$(CONFIG_PAGE_OWNER) += page_owner.o
obj-$(CONFIG_CLEANCACHE) += cleancache.o
obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o
diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
new file mode 100644
index 000000000000..188c18908964
--- /dev/null
+++ b/mm/debug_vm_pgtable.c
@@ -0,0 +1,382 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This kernel test validates architecture page table helpers and
+ * accessors and helps in verifying their continued compliance with
+ * expected generic MM semantics.
+ *
+ * Copyright (C) 2019 ARM Ltd.
+ *
+ * Author: Anshuman Khandual <anshuman.khandual@arm.com>
+ */
+#define pr_fmt(fmt) "debug_vm_pgtable: %s: " fmt, __func__
+
+#include <linux/gfp.h>
+#include <linux/highmem.h>
+#include <linux/hugetlb.h>
+#include <linux/kernel.h>
+#include <linux/kconfig.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/mm_types.h>
+#include <linux/module.h>
+#include <linux/pfn_t.h>
+#include <linux/printk.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
+#include <linux/start_kernel.h>
+#include <linux/sched/mm.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+#define VMFLAGS (VM_READ|VM_WRITE|VM_EXEC)
+
+/*
+ * On s390 platform, the lower 4 bits are used to identify given page table
+ * entry type. But these bits might affect the ability to clear entries with
+ * pxx_clear() because of how dynamic page table folding works on s390. So
+ * while loading up the entries do not change the lower 4 bits. It does not
+ * have affect any other platform.
+ */
+#define S390_MASK_BITS 4
+#define RANDOM_ORVALUE GENMASK(BITS_PER_LONG - 1, S390_MASK_BITS)
+#define RANDOM_NZVALUE GENMASK(7, 0)
+
+static void __init pte_basic_tests(unsigned long pfn, pgprot_t prot)
+{
+ pte_t pte = pfn_pte(pfn, prot);
+
+ WARN_ON(!pte_same(pte, pte));
+ WARN_ON(!pte_young(pte_mkyoung(pte_mkold(pte))));
+ WARN_ON(!pte_dirty(pte_mkdirty(pte_mkclean(pte))));
+ WARN_ON(!pte_write(pte_mkwrite(pte_wrprotect(pte))));
+ WARN_ON(pte_young(pte_mkold(pte_mkyoung(pte))));
+ WARN_ON(pte_dirty(pte_mkclean(pte_mkdirty(pte))));
+ WARN_ON(pte_write(pte_wrprotect(pte_mkwrite(pte))));
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static void __init pmd_basic_tests(unsigned long pfn, pgprot_t prot)
+{
+ pmd_t pmd = pfn_pmd(pfn, prot);
+
+ WARN_ON(!pmd_same(pmd, pmd));
+ WARN_ON(!pmd_young(pmd_mkyoung(pmd_mkold(pmd))));
+ WARN_ON(!pmd_dirty(pmd_mkdirty(pmd_mkclean(pmd))));
+ WARN_ON(!pmd_write(pmd_mkwrite(pmd_wrprotect(pmd))));
+ WARN_ON(pmd_young(pmd_mkold(pmd_mkyoung(pmd))));
+ WARN_ON(pmd_dirty(pmd_mkclean(pmd_mkdirty(pmd))));
+ WARN_ON(pmd_write(pmd_wrprotect(pmd_mkwrite(pmd))));
+ /*
+ * A huge page does not point to next level page table
+ * entry. Hence this must qualify as pmd_bad().
+ */
+ WARN_ON(!pmd_bad(pmd_mkhuge(pmd)));
+}
+
+#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
+static void __init pud_basic_tests(unsigned long pfn, pgprot_t prot)
+{
+ pud_t pud = pfn_pud(pfn, prot);
+
+ WARN_ON(!pud_same(pud, pud));
+ WARN_ON(!pud_young(pud_mkyoung(pud_mkold(pud))));
+ WARN_ON(!pud_write(pud_mkwrite(pud_wrprotect(pud))));
+ WARN_ON(pud_write(pud_wrprotect(pud_mkwrite(pud))));
+ WARN_ON(pud_young(pud_mkold(pud_mkyoung(pud))));
+
+ if (mm_pmd_folded(mm))
+ return;
+
+ /*
+ * A huge page does not point to next level page table
+ * entry. Hence this must qualify as pud_bad().
+ */
+ WARN_ON(!pud_bad(pud_mkhuge(pud)));
+}
+#else /* !CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
+static void __init pud_basic_tests(unsigned long pfn, pgprot_t prot) { }
+#endif /* CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
+#else /* !CONFIG_TRANSPARENT_HUGEPAGE */
+static void __init pmd_basic_tests(unsigned long pfn, pgprot_t prot) { }
+static void __init pud_basic_tests(unsigned long pfn, pgprot_t prot) { }
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
+static void __init p4d_basic_tests(unsigned long pfn, pgprot_t prot)
+{
+ p4d_t p4d;
+
+ memset(&p4d, RANDOM_NZVALUE, sizeof(p4d_t));
+ WARN_ON(!p4d_same(p4d, p4d));
+}
+
+static void __init pgd_basic_tests(unsigned long pfn, pgprot_t prot)
+{
+ pgd_t pgd;
+
+ memset(&pgd, RANDOM_NZVALUE, sizeof(pgd_t));
+ WARN_ON(!pgd_same(pgd, pgd));
+}
+
+#ifndef __PAGETABLE_PUD_FOLDED
+static void __init pud_clear_tests(struct mm_struct *mm, pud_t *pudp)
+{
+ pud_t pud = READ_ONCE(*pudp);
+
+ if (mm_pmd_folded(mm))
+ return;
+
+ pud = __pud(pud_val(pud) | RANDOM_ORVALUE);
+ WRITE_ONCE(*pudp, pud);
+ pud_clear(pudp);
+ pud = READ_ONCE(*pudp);
+ WARN_ON(!pud_none(pud));
+}
+
+static void __init pud_populate_tests(struct mm_struct *mm, pud_t *pudp,
+ pmd_t *pmdp)
+{
+ pud_t pud;
+
+ if (mm_pmd_folded(mm))
+ return;
+ /*
+ * This entry points to next level page table page.
+ * Hence this must not qualify as pud_bad().
+ */
+ pmd_clear(pmdp);
+ pud_clear(pudp);
+ pud_populate(mm, pudp, pmdp);
+ pud = READ_ONCE(*pudp);
+ WARN_ON(pud_bad(pud));
+}
+#else /* !__PAGETABLE_PUD_FOLDED */
+static void __init pud_clear_tests(struct mm_struct *mm, pud_t *pudp) { }
+static void __init pud_populate_tests(struct mm_struct *mm, pud_t *pudp,
+ pmd_t *pmdp)
+{
+}
+#endif /* PAGETABLE_PUD_FOLDED */
+
+#ifndef __PAGETABLE_P4D_FOLDED
+static void __init p4d_clear_tests(struct mm_struct *mm, p4d_t *p4dp)
+{
+ p4d_t p4d = READ_ONCE(*p4dp);
+
+ if (mm_pud_folded(mm))
+ return;
+
+ p4d = __p4d(p4d_val(p4d) | RANDOM_ORVALUE);
+ WRITE_ONCE(*p4dp, p4d);
+ p4d_clear(p4dp);
+ p4d = READ_ONCE(*p4dp);
+ WARN_ON(!p4d_none(p4d));
+}
+
+static void __init p4d_populate_tests(struct mm_struct *mm, p4d_t *p4dp,
+ pud_t *pudp)
+{
+ p4d_t p4d;
+
+ if (mm_pud_folded(mm))
+ return;
+
+ /*
+ * This entry points to next level page table page.
+ * Hence this must not qualify as p4d_bad().
+ */
+ pud_clear(pudp);
+ p4d_clear(p4dp);
+ p4d_populate(mm, p4dp, pudp);
+ p4d = READ_ONCE(*p4dp);
+ WARN_ON(p4d_bad(p4d));
+}
+
+static void __init pgd_clear_tests(struct mm_struct *mm, pgd_t *pgdp)
+{
+ pgd_t pgd = READ_ONCE(*pgdp);
+
+ if (mm_p4d_folded(mm))
+ return;
+
+ pgd = __pgd(pgd_val(pgd) | RANDOM_ORVALUE);
+ WRITE_ONCE(*pgdp, pgd);
+ pgd_clear(pgdp);
+ pgd = READ_ONCE(*pgdp);
+ WARN_ON(!pgd_none(pgd));
+}
+
+static void __init pgd_populate_tests(struct mm_struct *mm, pgd_t *pgdp,
+ p4d_t *p4dp)
+{
+ pgd_t pgd;
+
+ if (mm_p4d_folded(mm))
+ return;
+
+ /*
+ * This entry points to next level page table page.
+ * Hence this must not qualify as pgd_bad().
+ */
+ p4d_clear(p4dp);
+ pgd_clear(pgdp);
+ pgd_populate(mm, pgdp, p4dp);
+ pgd = READ_ONCE(*pgdp);
+ WARN_ON(pgd_bad(pgd));
+}
+#else /* !__PAGETABLE_P4D_FOLDED */
+static void __init p4d_clear_tests(struct mm_struct *mm, p4d_t *p4dp) { }
+static void __init pgd_clear_tests(struct mm_struct *mm, pgd_t *pgdp) { }
+static void __init p4d_populate_tests(struct mm_struct *mm, p4d_t *p4dp,
+ pud_t *pudp)
+{
+}
+static void __init pgd_populate_tests(struct mm_struct *mm, pgd_t *pgdp,
+ p4d_t *p4dp)
+{
+}
+#endif /* PAGETABLE_P4D_FOLDED */
+
+static void __init pte_clear_tests(struct mm_struct *mm, pte_t *ptep,
+ unsigned long vaddr)
+{
+ pte_t pte = READ_ONCE(*ptep);
+
+ pte = __pte(pte_val(pte) | RANDOM_ORVALUE);
+ set_pte_at(mm, vaddr, ptep, pte);
+ barrier();
+ pte_clear(mm, vaddr, ptep);
+ pte = READ_ONCE(*ptep);
+ WARN_ON(!pte_none(pte));
+}
+
+static void __init pmd_clear_tests(struct mm_struct *mm, pmd_t *pmdp)
+{
+ pmd_t pmd = READ_ONCE(*pmdp);
+
+ pmd = __pmd(pmd_val(pmd) | RANDOM_ORVALUE);
+ WRITE_ONCE(*pmdp, pmd);
+ pmd_clear(pmdp);
+ pmd = READ_ONCE(*pmdp);
+ WARN_ON(!pmd_none(pmd));
+}
+
+static void __init pmd_populate_tests(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pgtable)
+{
+ pmd_t pmd;
+
+ /*
+ * This entry points to next level page table page.
+ * Hence this must not qualify as pmd_bad().
+ */
+ pmd_clear(pmdp);
+ pmd_populate(mm, pmdp, pgtable);
+ pmd = READ_ONCE(*pmdp);
+ WARN_ON(pmd_bad(pmd));
+}
+
+static unsigned long __init get_random_vaddr(void)
+{
+ unsigned long random_vaddr, random_pages, total_user_pages;
+
+ total_user_pages = (TASK_SIZE - FIRST_USER_ADDRESS) / PAGE_SIZE;
+
+ random_pages = get_random_long() % total_user_pages;
+ random_vaddr = FIRST_USER_ADDRESS + random_pages * PAGE_SIZE;
+
+ return random_vaddr;
+}
+
+static int __init debug_vm_pgtable(void)
+{
+ struct mm_struct *mm;
+ pgd_t *pgdp;
+ p4d_t *p4dp, *saved_p4dp;
+ pud_t *pudp, *saved_pudp;
+ pmd_t *pmdp, *saved_pmdp, pmd;
+ pte_t *ptep;
+ pgtable_t saved_ptep;
+ pgprot_t prot;
+ phys_addr_t paddr;
+ unsigned long vaddr, pte_aligned, pmd_aligned;
+ unsigned long pud_aligned, p4d_aligned, pgd_aligned;
+ spinlock_t *uninitialized_var(ptl);
+
+ pr_info("Validating architecture page table helpers\n");
+ prot = vm_get_page_prot(VMFLAGS);
+ vaddr = get_random_vaddr();
+ mm = mm_alloc();
+ if (!mm) {
+ pr_err("mm_struct allocation failed\n");
+ return 1;
+ }
+
+ /*
+ * PFN for mapping at PTE level is determined from a standard kernel
+ * text symbol. But pfns for higher page table levels are derived by
+ * masking lower bits of this real pfn. These derived pfns might not
+ * exist on the platform but that does not really matter as pfn_pxx()
+ * helpers will still create appropriate entries for the test. This
+ * helps avoid large memory block allocations to be used for mapping
+ * at higher page table levels.
+ */
+ paddr = __pa_symbol(&start_kernel);
+
+ pte_aligned = (paddr & PAGE_MASK) >> PAGE_SHIFT;
+ pmd_aligned = (paddr & PMD_MASK) >> PAGE_SHIFT;
+ pud_aligned = (paddr & PUD_MASK) >> PAGE_SHIFT;
+ p4d_aligned = (paddr & P4D_MASK) >> PAGE_SHIFT;
+ pgd_aligned = (paddr & PGDIR_MASK) >> PAGE_SHIFT;
+ WARN_ON(!pfn_valid(pte_aligned));
+
+ pgdp = pgd_offset(mm, vaddr);
+ p4dp = p4d_alloc(mm, pgdp, vaddr);
+ pudp = pud_alloc(mm, p4dp, vaddr);
+ pmdp = pmd_alloc(mm, pudp, vaddr);
+ ptep = pte_alloc_map_lock(mm, pmdp, vaddr, &ptl);
+
+ /*
+ * Save all the page table page addresses as the page table
+ * entries will be used for testing with random or garbage
+ * values. These saved addresses will be used for freeing
+ * page table pages.
+ */
+ pmd = READ_ONCE(*pmdp);
+ saved_p4dp = p4d_offset(pgdp, 0UL);
+ saved_pudp = pud_offset(p4dp, 0UL);
+ saved_pmdp = pmd_offset(pudp, 0UL);
+ saved_ptep = pmd_pgtable(pmd);
+
+ pte_basic_tests(pte_aligned, prot);
+ pmd_basic_tests(pmd_aligned, prot);
+ pud_basic_tests(pud_aligned, prot);
+ p4d_basic_tests(p4d_aligned, prot);
+ pgd_basic_tests(pgd_aligned, prot);
+
+ pte_clear_tests(mm, ptep, vaddr);
+ pmd_clear_tests(mm, pmdp);
+ pud_clear_tests(mm, pudp);
+ p4d_clear_tests(mm, p4dp);
+ pgd_clear_tests(mm, pgdp);
+
+ pte_unmap_unlock(ptep, ptl);
+
+ pmd_populate_tests(mm, pmdp, saved_ptep);
+ pud_populate_tests(mm, pudp, saved_pmdp);
+ p4d_populate_tests(mm, p4dp, saved_pudp);
+ pgd_populate_tests(mm, pgdp, saved_p4dp);
+
+ p4d_free(mm, saved_p4dp);
+ pud_free(mm, saved_pudp);
+ pmd_free(mm, saved_pmdp);
+ pte_free(mm, saved_ptep);
+
+ mm_dec_nr_puds(mm);
+ mm_dec_nr_pmds(mm);
+ mm_dec_nr_ptes(mm);
+ mmdrop(mm);
+ return 0;
+}
+late_initcall(debug_vm_pgtable);
--
2.20.1
^ permalink raw reply related
* [PATCH V17 0/2] mm/debug: Add tests validating architecture page table helpers
From: Anshuman Khandual @ 2020-04-21 2:34 UTC (permalink / raw)
To: linux-mm
Cc: Heiko Carstens, Paul Mackerras, H. Peter Anvin, linux-riscv,
Will Deacon, linux-arch, linux-s390, x86, Mike Rapoport,
Christian Borntraeger, Ingo Molnar, Catalin Marinas,
linux-snps-arc, Vasily Gorbik, Anshuman Khandual, Borislav Petkov,
Paul Walmsley, Kirill A . Shutemov, Thomas Gleixner,
linux-arm-kernel, Vineet Gupta, linux-kernel, Palmer Dabbelt,
Andrew Morton, linuxppc-dev
This adds a test validation for architecture exported page table helpers.
Patch adds basic transformation tests at various levels of the page table.
This test was originally suggested by Catalin during arm64 THP migration
RFC discussion earlier. Going forward it can include more specific tests
with respect to various generic MM functions like THP, HugeTLB etc and
platform specific tests.
https://lore.kernel.org/linux-mm/20190628102003.GA56463@arrakis.emea.arm.com/
Needs to be applied on linux V5.7-rc2
Changes in V17:
- debug_vm_pgtable() is now called from late_initcall() per Linus
- Explicitly enable DEBUG_VM_PGTABLE when ARCH_HAS_DEBUG_VM_PGTABLE and DEBUG_VM
- Added #ifdef documentation per Gerald
- Dropped page table helper semantics documentation (will be added via later patches)
- Split the X86 changes defining mm_p4d_folded() into a new prerequisite patch
Changes in V16: (https://patchwork.kernel.org/patch/11431277/)
- Replaced WRITE_ONCE() with set_pte_at() with a new barrier() in pte_clear_tests() per Qian
- Enabled all powerpc platforms and updated the feature list
Changes in V15: (https://patchwork.kernel.org/patch/11422803/)
- Replaced __pa() with __pa_symbol() (https://patchwork.kernel.org/patch/11407715/)
- Replaced pte_alloc_map() with pte_alloc_map_lock() per Qian
- Replaced pte_unmap() with pte_unmap_unlock() per Qian
- Added address to pte_clear_tests() and passed it down till pte_clear() per Qian
Changes in V14: (https://patchwork.kernel.org/project/linux-mm/list/?series=242305)
- Disabled DEBUG_VM_PGTABLE for IA64 and ARM (32 Bit) per Andrew and Christophe
- Updated DEBUG_VM_PGTABLE documentation wrt EXPERT and disabled platforms
- Updated RANDOM_[OR|NZ]VALUE open encodings with GENMASK() per Catalin
- Updated s390 constraint bits from 12 to 4 (S390_MASK_BITS) per Gerald
- Updated in-code documentation for RANDOM_ORVALUE per Gerald
- Updated pxx_basic_tests() to use invert functions first per Catalin
- Dropped ARCH_HAS_4LEVEL_HACK check from pud_basic_tests()
- Replaced __ARCH_HAS_[4|5]LEVEL_HACK with __PAGETABLE_[PUD|P4D]_FOLDED per Catalin
- Trimmed the CC list on the commit message per Catalin
Changes in V13: (https://patchwork.kernel.org/project/linux-mm/list/?series=237125)
- Subscribed s390 platform and updated debug-vm-pgtable/arch-support.txt per Gerald
- Dropped keyword 'extern' from debug_vm_pgtable() declaration per Christophe
- Moved debug_vm_pgtable() declarations to <linux/mmdebug.h> per Christophe
- Moved debug_vm_pgtable() call site into kernel_init() per Christophe
- Changed CONFIG_DEBUG_VM_PGTABLE rules per Christophe
- Updated commit to include new supported platforms and changed config selection
Changes in V12: (https://patchwork.kernel.org/project/linux-mm/list/?series=233905)
- Replaced __mmdrop() with mmdrop()
- Enable ARCH_HAS_DEBUG_VM_PGTABLE on X86 for non CONFIG_X86_PAE platforms as the
test procedure interfere with pre-allocated PMDs attached to the PGD resulting
in runtime failures with VM_BUG_ON()
Changes in V11: (https://patchwork.kernel.org/project/linux-mm/list/?series=221135)
- Rebased the patch on V5.4
Changes in V10: (https://patchwork.kernel.org/project/linux-mm/list/?series=205529)
- Always enable DEBUG_VM_PGTABLE when DEBUG_VM is enabled per Ingo
- Added tags from Ingo
Changes in V9: (https://patchwork.kernel.org/project/linux-mm/list/?series=201429)
- Changed feature support enumeration for powerpc platforms per Christophe
- Changed config wrapper for basic_[pmd|pud]_tests() to enable ARC platform
- Enabled the test on ARC platform
Changes in V8: (https://patchwork.kernel.org/project/linux-mm/list/?series=194297)
- Enabled ARCH_HAS_DEBUG_VM_PGTABLE on PPC32 platform per Christophe
- Updated feature documentation as DEBUG_VM_PGTABLE is now enabled on PPC32 platform
- Moved ARCH_HAS_DEBUG_VM_PGTABLE earlier to indent it with DEBUG_VM per Christophe
- Added an information message in debug_vm_pgtable() per Christophe
- Dropped random_vaddr boundary condition checks per Christophe and Qian
- Replaced virt_addr_valid() check with pfn_valid() check in debug_vm_pgtable()
- Slightly changed pr_fmt(fmt) information
Changes in V7: (https://patchwork.kernel.org/project/linux-mm/list/?series=193051)
- Memory allocation and free routines for mapped pages have been droped
- Mapped pfns are derived from standard kernel text symbol per Matthew
- Moved debug_vm_pgtaable() after page_alloc_init_late() per Michal and Qian
- Updated the commit message per Michal
- Updated W=1 GCC warning problem on x86 per Qian Cai
- Addition of new alloc_contig_pages() helper has been submitted separately
Changes in V6: (https://patchwork.kernel.org/project/linux-mm/list/?series=187589)
- Moved alloc_gigantic_page_order() into mm/page_alloc.c per Michal
- Moved alloc_gigantic_page_order() within CONFIG_CONTIG_ALLOC in the test
- Folded Andrew's include/asm-generic/pgtable.h fix into the test patch 2/2
Changes in V5: (https://patchwork.kernel.org/project/linux-mm/list/?series=185991)
- Redefined and moved X86 mm_p4d_folded() into a different header per Kirill/Ingo
- Updated the config option comment per Ingo and dropped 'kernel module' reference
- Updated the commit message and dropped 'kernel module' reference
- Changed DEBUG_ARCH_PGTABLE_TEST into DEBUG_VM_PGTABLE per Ingo
- Moved config option from mm/Kconfig.debug into lib/Kconfig.debug
- Renamed core test function arch_pgtable_tests() as debug_vm_pgtable()
- Renamed mm/arch_pgtable_test.c as mm/debug_vm_pgtable.c
- debug_vm_pgtable() gets called from kernel_init_freeable() after init_mm_internals()
- Added an entry in Documentation/features/debug/ per Ingo
- Enabled the test on arm64 and x86 platforms for now
Changes in V4: (https://patchwork.kernel.org/project/linux-mm/list/?series=183465)
- Disable DEBUG_ARCH_PGTABLE_TEST for ARM and IA64 platforms
Changes in V3: (https://lore.kernel.org/patchwork/project/lkml/list/?series=411216)
- Changed test trigger from module format into late_initcall()
- Marked all functions with __init to be freed after completion
- Changed all __PGTABLE_PXX_FOLDED checks as mm_pxx_folded()
- Folded in PPC32 fixes from Christophe
Changes in V2:
https://lore.kernel.org/linux-mm/1568268173-31302-1-git-send-email-anshuman.khandual@arm.com/T/#t
- Fixed small typo error in MODULE_DESCRIPTION()
- Fixed m64k build problems for lvalue concerns in pmd_xxx_tests()
- Fixed dynamic page table level folding problems on x86 as per Kirril
- Fixed second pointers during pxx_populate_tests() per Kirill and Gerald
- Allocate and free pte table with pte_alloc_one/pte_free per Kirill
- Modified pxx_clear_tests() to accommodate s390 lower 12 bits situation
- Changed RANDOM_NZVALUE value from 0xbe to 0xff
- Changed allocation, usage, free sequence for saved_ptep
- Renamed VMA_FLAGS as VMFLAGS
- Implemented a new method for random vaddr generation
- Implemented some other cleanups
- Dropped extern reference to mm_alloc()
- Created and exported new alloc_gigantic_page_order()
- Dropped the custom allocator and used new alloc_gigantic_page_order()
Changes in V1:
https://lore.kernel.org/linux-mm/1567497706-8649-1-git-send-email-anshuman.khandual@arm.com/
- Added fallback mechanism for PMD aligned memory allocation failure
Changes in RFC V2:
https://lore.kernel.org/linux-mm/1565335998-22553-1-git-send-email-anshuman.khandual@arm.com/T/#u
- Moved test module and it's config from lib/ to mm/
- Renamed config TEST_ARCH_PGTABLE as DEBUG_ARCH_PGTABLE_TEST
- Renamed file from test_arch_pgtable.c to arch_pgtable_test.c
- Added relevant MODULE_DESCRIPTION() and MODULE_AUTHOR() details
- Dropped loadable module config option
- Basic tests now use memory blocks with required size and alignment
- PUD aligned memory block gets allocated with alloc_contig_range()
- If PUD aligned memory could not be allocated it falls back on PMD aligned
memory block from page allocator and pud_* tests are skipped
- Clear and populate tests now operate on real in memory page table entries
- Dummy mm_struct gets allocated with mm_alloc()
- Dummy page table entries get allocated with [pud|pmd|pte]_alloc_[map]()
- Simplified [p4d|pgd]_basic_tests(), now has random values in the entries
Original RFC V1:
https://lore.kernel.org/linux-mm/1564037723-26676-1-git-send-email-anshuman.khandual@arm.com/
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mike Rapoport <rppt@linux.ibm.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: linux-snps-arc@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: linux-riscv@lists.infradead.org
Cc: x86@kernel.org
Cc: linux-arch@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Anshuman Khandual (2):
x86/mm: Define mm_p4d_folded()
mm/debug: Add tests validating architecture page table helpers
.../debug/debug-vm-pgtable/arch-support.txt | 34 ++
arch/arc/Kconfig | 1 +
arch/arm64/Kconfig | 1 +
arch/powerpc/Kconfig | 1 +
arch/s390/Kconfig | 1 +
arch/x86/Kconfig | 1 +
arch/x86/include/asm/pgtable_64.h | 6 +
lib/Kconfig.debug | 25 ++
mm/Makefile | 1 +
mm/debug_vm_pgtable.c | 382 ++++++++++++++++++
10 files changed, 453 insertions(+)
create mode 100644 Documentation/features/debug/debug-vm-pgtable/arch-support.txt
create mode 100644 mm/debug_vm_pgtable.c
--
2.20.1
^ permalink raw reply
* Re: [PATCH 02/21] mm: make early_pfn_to_nid() and related defintions close to each other
From: Baoquan He @ 2020-04-21 2:24 UTC (permalink / raw)
To: Mike Rapoport
Cc: Rich Felker, linux-ia64, linux-doc, Catalin Marinas,
Heiko Carstens, Michal Hocko, James E.J. Bottomley, Max Filippov,
Guo Ren, linux-csky, linux-parisc, sparclinux, linux-hexagon,
linux-riscv, Greg Ungerer, linux-arch, linux-s390, linux-snps-arc,
linux-c6x-dev, Brian Cain, Jonathan Corbet, linux-sh,
Helge Deller, x86, Russell King, Ley Foon Tan, Mike Rapoport,
Geert Uytterhoeven, linux-arm-kernel, Mark Salter, Matt Turner,
linux-mips, uclinux-h8-devel, linux-xtensa, linux-alpha, linux-um,
linux-m68k, Tony Luck, Greentime Hu, Paul Walmsley,
Stafford Horne, Guan Xuetao, Hoan Tran, Michal Simek,
Thomas Bogendoerfer, Yoshinori Sato, Nick Hu, linux-mm,
Vineet Gupta, linux-kernel, openrisc, Richard Weinberger,
Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <20200412194859.12663-3-rppt@kernel.org>
On 04/12/20 at 10:48pm, Mike Rapoport wrote:
> From: Mike Rapoport <rppt@linux.ibm.com>
>
> The early_pfn_to_nid() and it's helper __early_pfn_to_nid() are spread
> around include/linux/mm.h, include/linux/mmzone.h and mm/page_alloc.c.
>
> Drop unused stub for __early_pfn_to_nid() and move its actual generic
> implementation close to its users.
>
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> ---
> include/linux/mm.h | 4 ++--
> include/linux/mmzone.h | 9 --------
> mm/page_alloc.c | 51 +++++++++++++++++++++---------------------
> 3 files changed, 27 insertions(+), 37 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 5a323422d783..a404026d14d4 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2388,9 +2388,9 @@ extern void sparse_memory_present_with_active_regions(int nid);
>
> #if !defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) && \
> !defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID)
> -static inline int __early_pfn_to_nid(unsigned long pfn,
> - struct mminit_pfnnid_cache *state)
> +static inline int early_pfn_to_nid(unsigned long pfn)
> {
> + BUILD_BUG_ON(IS_ENABLED(CONFIG_NUMA));
> return 0;
> }
It's better to make a separate patch to drop __early_pfn_to_nid() here.
> #else
> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index 1b9de7d220fb..7b5b6eba402f 100644
> --- a/include/linux/mmzone.h
> +++ b/include/linux/mmzone.h
> @@ -1078,15 +1078,6 @@ static inline struct zoneref *first_zones_zonelist(struct zonelist *zonelist,
> #include <asm/sparsemem.h>
> #endif
>
> -#if !defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) && \
> - !defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP)
> -static inline unsigned long early_pfn_to_nid(unsigned long pfn)
> -{
> - BUILD_BUG_ON(IS_ENABLED(CONFIG_NUMA));
> - return 0;
> -}
> -#endif
> -
> #ifdef CONFIG_FLATMEM
> #define pfn_to_nid(pfn) (0)
> #endif
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 0d012eda1694..1ac775bfc9cf 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -1504,6 +1504,31 @@ void __free_pages_core(struct page *page, unsigned int order)
#if defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) || \
defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP)
This is the upper layer of ifdeffery scope.
>
> static struct mminit_pfnnid_cache early_pfnnid_cache __meminitdata;
>
> +#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
Moving __early_pfn_to_nid() here makes the upper layer of ifdeferry
scope a little werid. But seems no better way to optimize it.
Otherwise, this patch looks good to me.
Reviewed-by: Baoquan He <bhe@redhat.com>
> +
> +/*
> + * Required by SPARSEMEM. Given a PFN, return what node the PFN is on.
> + */
> +int __meminit __early_pfn_to_nid(unsigned long pfn,
> + struct mminit_pfnnid_cache *state)
> +{
> + unsigned long start_pfn, end_pfn;
> + int nid;
> +
> + if (state->last_start <= pfn && pfn < state->last_end)
> + return state->last_nid;
> +
> + nid = memblock_search_pfn_nid(pfn, &start_pfn, &end_pfn);
> + if (nid != NUMA_NO_NODE) {
> + state->last_start = start_pfn;
> + state->last_end = end_pfn;
> + state->last_nid = nid;
> + }
> +
> + return nid;
> +}
> +#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
> +
> int __meminit early_pfn_to_nid(unsigned long pfn)
> {
> static DEFINE_SPINLOCK(early_pfn_lock);
> @@ -6298,32 +6323,6 @@ void __meminit init_currently_empty_zone(struct zone *zone,
> zone->initialized = 1;
> }
>
> -#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
> -#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
> -
> -/*
> - * Required by SPARSEMEM. Given a PFN, return what node the PFN is on.
> - */
> -int __meminit __early_pfn_to_nid(unsigned long pfn,
> - struct mminit_pfnnid_cache *state)
> -{
> - unsigned long start_pfn, end_pfn;
> - int nid;
> -
> - if (state->last_start <= pfn && pfn < state->last_end)
> - return state->last_nid;
> -
> - nid = memblock_search_pfn_nid(pfn, &start_pfn, &end_pfn);
> - if (nid != NUMA_NO_NODE) {
> - state->last_start = start_pfn;
> - state->last_end = end_pfn;
> - state->last_nid = nid;
> - }
> -
> - return nid;
> -}
> -#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
> -
> /**
> * free_bootmem_with_active_regions - Call memblock_free_early_nid for each active range
> * @nid: The node to free memory on. If MAX_NUMNODES, all nodes are freed.
> --
> 2.25.1
>
^ permalink raw reply
* [PATCH 4/4] powerpc: Use trap metadata to prevent double restart rather than zeroing trap
From: Nicholas Piggin @ 2020-04-21 2:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Piggin
In-Reply-To: <20200421021955.772023-1-npiggin@gmail.com>
It's not very nice to zero trap for this, because then system calls no
longer have TRAP_IS_SYSCALL(regs) invariant, and we can't distinguish
between sc and scv system calls (in a later patch).
Take one last unused bit from the low bits of the pt_regs.trap word for
this instead. There is not a really good reason why it should be in trap
as opposed to another field, but trap has some concept of flags and it
exists. Ideally I think we would move trap to 2-byte field and have 2
more bytes available independently.
Add a selftests case for this, which can be seen to fail if
TRAP_NORESTART is defined to false.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/ptrace.h | 15 +-
arch/powerpc/kernel/signal.c | 7 +-
arch/powerpc/kernel/signal_32.c | 2 +-
arch/powerpc/kernel/signal_64.c | 10 +-
.../testing/selftests/powerpc/signal/Makefile | 2 +-
.../powerpc/signal/sig_sc_double_restart.c | 174 ++++++++++++++++++
6 files changed, 194 insertions(+), 16 deletions(-)
create mode 100644 tools/testing/selftests/powerpc/signal/sig_sc_double_restart.c
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 5eb249c725bd..5ee7eb128fb9 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -184,13 +184,13 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
#ifdef __powerpc64__
#ifdef CONFIG_PPC_BOOK3S
-#define TRAP(regs) ((regs)->trap)
-#define SET_TRAP(regs, val) ((regs)->trap = (val))
+#define TRAP(regs) ((regs)->trap & ~0x10)
+#define SET_TRAP(regs, val) ((regs)->trap = ((regs)->trap & 0x10) | ((val) & ~0x10))
#define FULL_REGS(regs) true
#define SET_FULL_REGS(regs) do { } while (0)
#else
-#define TRAP(regs) ((regs)->trap & ~0x1)
-#define SET_TRAP(regs, val) ((regs)->trap = ((regs)->trap & 0x1) | ((val) & ~0x1))
+#define TRAP(regs) ((regs)->trap & ~0x11)
+#define SET_TRAP(regs, val) ((regs)->trap = ((regs)->trap & 0x11) | ((val) & ~0x11))
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
#endif
@@ -204,8 +204,8 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
* On 4xx we use the next bit to indicate whether the exception
* is a critical exception (1 means it is).
*/
-#define TRAP(regs) ((regs)->trap & ~0xF)
-#define SET_TRAP(regs, val) ((regs)->trap = ((regs)->trap & 0xF) | ((val) & ~0xF))
+#define TRAP(regs) ((regs)->trap & ~0x1F)
+#define SET_TRAP(regs, val) ((regs)->trap = ((regs)->trap & 0x1F) | ((val) & ~0x1F))
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
@@ -219,6 +219,9 @@ do { \
} while (0)
#endif /* __powerpc64__ */
+#define TRAP_NORESTART(regs) (((regs)->trap & 16) == 16)
+#define SET_TRAP_NORESTART(regs) ((regs)->trap |= 16)
+
#define arch_has_single_step() (1)
#ifndef CONFIG_BOOK3S_601
#define arch_has_block_step() (true)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 4b74eef1d881..0de314075a8f 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -201,6 +201,9 @@ static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
if (!TRAP_IS_SYSCALL(regs))
return;
+ if (TRAP_NORESTART(regs))
+ return;
+
/* error signalled ? */
if (!(regs->ccr & 0x10000000))
return;
@@ -258,7 +261,7 @@ static void do_signal(struct task_struct *tsk)
if (ksig.sig <= 0) {
/* No signal to deliver -- put the saved sigmask back */
restore_saved_sigmask();
- tsk->thread.regs->trap = 0;
+ SET_TRAP_NORESTART(tsk->thread.regs);
return; /* no signals delivered */
}
@@ -285,7 +288,7 @@ static void do_signal(struct task_struct *tsk)
ret = handle_rt_signal64(&ksig, oldset, tsk);
}
- tsk->thread.regs->trap = 0;
+ SET_TRAP_NORESTART(tsk->thread.regs);
signal_setup_done(ret, &ksig, test_thread_flag(TIF_SINGLESTEP));
}
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 4f96d29a22bf..2970e1fd8d02 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -500,7 +500,7 @@ static long restore_user_regs(struct pt_regs *regs,
if (!sig)
save_r2 = (unsigned int)regs->gpr[2];
err = restore_general_regs(regs, sr);
- regs->trap = 0;
+ SET_TRAP_NORESTART(regs);
err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
if (!sig)
regs->gpr[2] = (unsigned long) save_r2;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index adfde59cf4ba..1f6565dbe248 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -350,8 +350,8 @@ static long restore_sigcontext(struct task_struct *tsk, sigset_t *set, int sig,
err |= __get_user(regs->link, &sc->gp_regs[PT_LNK]);
err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]);
err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]);
- /* skip SOFTE */
- regs->trap = 0;
+ /* Don't allow userspace to set SOFTE */
+ SET_TRAP_NORESTART(regs);
err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
@@ -472,10 +472,8 @@ static long restore_tm_sigcontexts(struct task_struct *tsk,
&sc->gp_regs[PT_XER]);
err |= __get_user(tsk->thread.ckpt_regs.ccr,
&sc->gp_regs[PT_CCR]);
-
- /* Don't allow userspace to set the trap value */
- regs->trap = 0;
-
+ /* Don't allow userspace to set SOFTE */
+ SET_TRAP_NORESTART(regs);
/* These regs are not checkpointed; they can go in 'regs'. */
err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
diff --git a/tools/testing/selftests/powerpc/signal/Makefile b/tools/testing/selftests/powerpc/signal/Makefile
index 932a032bf036..d6ae54663aed 100644
--- a/tools/testing/selftests/powerpc/signal/Makefile
+++ b/tools/testing/selftests/powerpc/signal/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-TEST_GEN_PROGS := signal signal_tm sigfuz sigreturn_vdso
+TEST_GEN_PROGS := signal signal_tm sigfuz sigreturn_vdso sig_sc_double_restart
CFLAGS += -maltivec
$(OUTPUT)/signal_tm: CFLAGS += -mhtm
diff --git a/tools/testing/selftests/powerpc/signal/sig_sc_double_restart.c b/tools/testing/selftests/powerpc/signal/sig_sc_double_restart.c
new file mode 100644
index 000000000000..64732adf3d91
--- /dev/null
+++ b/tools/testing/selftests/powerpc/signal/sig_sc_double_restart.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Test that a syscall does not get restarted twice.
+ *
+ * Based on Al's description, and a test for the bug fixed in this commit:
+ *
+ * commit 9a81c16b527528ad307843be5571111aa8d35a80
+ * Author: Al Viro <viro@zeniv.linux.org.uk>
+ * Date: Mon Sep 20 21:48:57 2010 +0100
+ *
+ * powerpc: fix double syscall restarts
+ *
+ * Make sigreturn zero regs->trap, make do_signal() do the same on all
+ * paths. As it is, signal interrupting e.g. read() from fd 512 (==
+ * ERESTARTSYS) with another signal getting unblocked when the first
+ * handler finishes will lead to restart one insn earlier than it ought
+ * to. Same for multiple signals with in-kernel handlers interrupting
+ * that sucker at the same time. Same for multiple signals of any kind
+ * interrupting that sucker on 64bit...
+ */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "utils.h"
+
+static void SIGUSR1_handler(int sig)
+{
+ kill(getpid(), SIGUSR2);
+ /*
+ * SIGUSR2 is blocked until the handler exits, at which point it will
+ * be raised again and think there is a restart to be done because the
+ * pending restarted syscall has 512 (ERESTARTSYS) in r3. The second
+ * restart will retreat NIP another 4 bytes to fail case branch.
+ */
+}
+
+static void SIGUSR2_handler(int sig)
+{
+}
+
+static ssize_t raw_read(int fd, void *buf, size_t count)
+{
+ register long nr asm("r0") = __NR_read;
+ register long _fd asm("r3") = fd;
+ register void *_buf asm("r4") = buf;
+ register size_t _count asm("r5") = count;
+
+ asm volatile(
+" b 0f \n"
+" b 1f \n"
+" 0: sc 0 \n"
+" bns 2f \n"
+" neg %0,%0 \n"
+" b 2f \n"
+" 1: \n"
+" li %0,%4 \n"
+" 2: \n"
+ : "+r"(_fd), "+r"(nr), "+r"(_buf), "+r"(_count)
+ : "i"(-ENOANO)
+ : "memory", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "cr0");
+
+ if (_fd < 0) {
+ errno = -_fd;
+ _fd = -1;
+ }
+
+ return _fd;
+}
+
+#define DATA "test 123"
+#define DLEN (strlen(DATA)+1)
+
+int test_restart(void)
+{
+ int pipefd[2];
+ pid_t pid;
+ char buf[512];
+
+ if (pipe(pipefd) == -1) {
+ perror("pipe");
+ exit(EXIT_FAILURE);
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ perror("fork");
+ exit(EXIT_FAILURE);
+ }
+
+ if (pid == 0) { /* Child reads from pipe */
+ struct sigaction act;
+ int fd;
+
+ memset(&act, 0, sizeof(act));
+ sigaddset(&act.sa_mask, SIGUSR2);
+ act.sa_handler = SIGUSR1_handler;
+ act.sa_flags = SA_RESTART;
+ if (sigaction(SIGUSR1, &act, NULL) == -1) {
+ perror("sigaction");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = SIGUSR2_handler;
+ act.sa_flags = SA_RESTART;
+ if (sigaction(SIGUSR2, &act, NULL) == -1) {
+ perror("sigaction");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Let's get ERESTARTSYS into r3 */
+ while ((fd = dup(pipefd[0])) != 512) {
+ if (fd == -1) {
+ perror("dup");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (raw_read(fd, buf, 512) == -1) {
+ if (errno == ENOANO) {
+ fprintf(stderr, "Double restart moved restart before sc instruction.\n");
+ _exit(EXIT_FAILURE);
+ }
+ perror("read");
+ exit(EXIT_FAILURE);
+ }
+
+ if (strncmp(buf, DATA, DLEN)) {
+ fprintf(stderr, "bad test string %s\n", buf);
+ exit(EXIT_FAILURE);
+ }
+
+ return 0;
+
+ } else {
+ int wstatus;
+
+ usleep(100000); /* Hack to get reader waiting */
+ kill(pid, SIGUSR1);
+ usleep(100000);
+ if (write(pipefd[1], DATA, DLEN) != DLEN) {
+ perror("write");
+ exit(EXIT_FAILURE);
+ }
+ close(pipefd[0]);
+ close(pipefd[1]);
+ if (wait(&wstatus) == -1) {
+ perror("wait");
+ exit(EXIT_FAILURE);
+ }
+ if (!WIFEXITED(wstatus)) {
+ fprintf(stderr, "child exited abnormally\n");
+ exit(EXIT_FAILURE);
+ }
+
+ FAIL_IF(WEXITSTATUS(wstatus) != EXIT_SUCCESS);
+
+ return 0;
+ }
+}
+
+int main(void)
+{
+ test_harness_set_timeout(10);
+ return test_harness(test_restart, "sig sys restart");
+}
--
2.23.0
^ permalink raw reply related
* [PATCH 3/4] powerpc: TRAP_IS_SYSCALL helper to hide syscall trap number
From: Nicholas Piggin @ 2020-04-21 2:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Piggin
In-Reply-To: <20200421021955.772023-1-npiggin@gmail.com>
A new system call interrupt will be added with a new trap number.
Hide the explicit 0xc00 test behind an accessor to reduce churn
in callers.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/ptrace.h | 2 ++
arch/powerpc/include/asm/syscall.h | 5 ++++-
arch/powerpc/kernel/process.c | 2 +-
arch/powerpc/kernel/signal.c | 2 +-
arch/powerpc/xmon/xmon.c | 2 +-
5 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 7eaa2ecfd0b7..5eb249c725bd 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -180,6 +180,8 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
#define current_pt_regs() \
((struct pt_regs *)((unsigned long)task_stack_page(current) + THREAD_SIZE) - 1)
+#define TRAP_IS_SYSCALL(regs) (TRAP(regs) == 0xc00)
+
#ifdef __powerpc64__
#ifdef CONFIG_PPC_BOOK3S
#define TRAP(regs) ((regs)->trap)
diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h
index 38d62acfdce7..1e0446d6ba45 100644
--- a/arch/powerpc/include/asm/syscall.h
+++ b/arch/powerpc/include/asm/syscall.h
@@ -26,7 +26,10 @@ static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
* This is important for seccomp so that compat tasks can set r0 = -1
* to reject the syscall.
*/
- return TRAP(regs) == 0xc00 ? regs->gpr[0] : -1;
+ if (TRAP_IS_SYSCALL(regs))
+ return regs->gpr[0];
+ else
+ return -1;
}
static inline void syscall_rollback(struct task_struct *task,
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 6599a3099d10..0dce642ca39d 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1412,7 +1412,7 @@ void show_regs(struct pt_regs * regs)
print_msr_bits(regs->msr);
pr_cont(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
trap = TRAP(regs);
- if ((TRAP(regs) != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))
+ if (!TRAP_IS_SYSCALL(regs) && cpu_has_feature(CPU_FTR_CFAR))
pr_cont("CFAR: "REG" ", regs->orig_gpr3);
if (trap == 0x200 || trap == 0x300 || trap == 0x600)
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a264989626fd..4b74eef1d881 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -198,7 +198,7 @@ static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
int restart = 1;
/* syscall ? */
- if (TRAP(regs) != 0x0C00)
+ if (!TRAP_IS_SYSCALL(regs))
return;
/* error signalled ? */
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 20c1fc08819b..8da771e025fa 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1776,7 +1776,7 @@ static void prregs(struct pt_regs *fp)
#endif
printf("pc = ");
xmon_print_symbol(fp->nip, " ", "\n");
- if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
+ if (!TRAP_IS_SYSCALL(fp) && cpu_has_feature(CPU_FTR_CFAR)) {
printf("cfar= ");
xmon_print_symbol(fp->orig_gpr3, " ", "\n");
}
--
2.23.0
^ permalink raw reply related
* [PATCH 2/4] powerpc: Use SET_TRAP and avoid open-coding trap masking
From: Nicholas Piggin @ 2020-04-21 2:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Piggin
In-Reply-To: <20200421021955.772023-1-npiggin@gmail.com>
The pt_regs.trap field keeps 4 low bits for some metadata about the
trap or how it was handled, which is masked off in order to test the
architectural trap number.
Add a SET_TRAP() accessor to set this, equivalent to TRAP() for
returning it. This is actually not quite the equivalent of TRAP()
because it always clears the low bits, which may be harmless if
it can only be updated via ptrace syscall, but it seems dangerous.
In fact settting TRAP from ptrace doesn't seem like a great idea
so maybe it's better deleted.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/ptrace.h | 3 +++
arch/powerpc/kernel/ptrace/ptrace-tm.c | 2 +-
arch/powerpc/kernel/ptrace/ptrace-view.c | 2 +-
arch/powerpc/xmon/xmon.c | 2 +-
4 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 89f31d5a8062..7eaa2ecfd0b7 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -183,10 +183,12 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
#ifdef __powerpc64__
#ifdef CONFIG_PPC_BOOK3S
#define TRAP(regs) ((regs)->trap)
+#define SET_TRAP(regs, val) ((regs)->trap = (val))
#define FULL_REGS(regs) true
#define SET_FULL_REGS(regs) do { } while (0)
#else
#define TRAP(regs) ((regs)->trap & ~0x1)
+#define SET_TRAP(regs, val) ((regs)->trap = ((regs)->trap & 0x1) | ((val) & ~0x1))
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
#endif
@@ -201,6 +203,7 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
* is a critical exception (1 means it is).
*/
#define TRAP(regs) ((regs)->trap & ~0xF)
+#define SET_TRAP(regs, val) ((regs)->trap = ((regs)->trap & 0xF) | ((val) & ~0xF))
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
diff --git a/arch/powerpc/kernel/ptrace/ptrace-tm.c b/arch/powerpc/kernel/ptrace/ptrace-tm.c
index d75aff31f637..ac76b2924a1a 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-tm.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-tm.c
@@ -43,7 +43,7 @@ static int set_user_ckpt_msr(struct task_struct *task, unsigned long msr)
static int set_user_ckpt_trap(struct task_struct *task, unsigned long trap)
{
- task->thread.ckpt_regs.trap = trap & 0xfff0;
+ SET_TRAP(&task->thread.ckpt_regs, trap);
return 0;
}
diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c
index 15e3b79b6395..87c8bd67512c 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-view.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-view.c
@@ -149,7 +149,7 @@ static int set_user_dscr(struct task_struct *task, unsigned long dscr)
*/
static int set_user_trap(struct task_struct *task, unsigned long trap)
{
- task->thread.regs->trap = trap & 0xfff0;
+ SET_TRAP(task->thread.regs, trap);
return 0;
}
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 7af840c0fc93..20c1fc08819b 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1178,7 +1178,7 @@ static int do_step(struct pt_regs *regs)
return 0;
}
if (stepped > 0) {
- regs->trap = 0xd00 | (regs->trap & 1);
+ SET_TRAP(regs, 0xd00);
printf("stepped to ");
xmon_print_symbol(regs->nip, " ", "\n");
ppc_inst_dump(regs->nip, 1, 0);
--
2.23.0
^ permalink raw reply related
* [PATCH 1/4] powerpc/64s: Always has full regs, so remove remnant checks
From: Nicholas Piggin @ 2020-04-21 2:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Piggin
In-Reply-To: <20200421021955.772023-1-npiggin@gmail.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/ptrace.h | 23 ++++++++++++++++-------
arch/powerpc/kernel/process.c | 2 +-
2 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index e0195e6b892b..89f31d5a8062 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -179,6 +179,20 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
#define current_pt_regs() \
((struct pt_regs *)((unsigned long)task_stack_page(current) + THREAD_SIZE) - 1)
+
+#ifdef __powerpc64__
+#ifdef CONFIG_PPC_BOOK3S
+#define TRAP(regs) ((regs)->trap)
+#define FULL_REGS(regs) true
+#define SET_FULL_REGS(regs) do { } while (0)
+#else
+#define TRAP(regs) ((regs)->trap & ~0x1)
+#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
+#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
+#endif
+#define CHECK_FULL_REGS(regs) BUG_ON(!FULL_REGS(regs))
+#define NV_REG_POISON 0xdeadbeefdeadbeefUL
+#else
/*
* We use the least-significant bit of the trap field to indicate
* whether we have saved the full set of registers, or only a
@@ -186,17 +200,12 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
* On 4xx we use the next bit to indicate whether the exception
* is a critical exception (1 means it is).
*/
+#define TRAP(regs) ((regs)->trap & ~0xF)
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
-#ifndef __powerpc64__
+#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
#define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0)
-#endif /* ! __powerpc64__ */
-#define TRAP(regs) ((regs)->trap & ~0xF)
-#ifdef __powerpc64__
-#define NV_REG_POISON 0xdeadbeefdeadbeefUL
-#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1)
-#else
#define NV_REG_POISON 0xdeadbeef
#define CHECK_FULL_REGS(regs) \
do { \
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 9c21288f8645..6599a3099d10 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1740,7 +1740,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
* FULL_REGS(regs) return true. This is necessary to allow
* ptrace to examine the thread immediately after exec.
*/
- regs->trap &= ~1UL;
+ SET_FULL_REGS(regs);
#ifdef CONFIG_PPC32
regs->mq = 0;
--
2.23.0
^ permalink raw reply related
* [PATCH 0/4] powerpc: clean up pt_regs traps handling
From: Nicholas Piggin @ 2020-04-21 2:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Piggin
scv support needs to test trap in some cases to distinguish sc from scv,
so it helps to have a few tidy-up patches to start with. This turned
into a slightly bigger job that we needed to do to clean up the double
restart logic that today zeroes traps which is ugly.
Thanks,
Nick
Nicholas Piggin (4):
powerpc/64s: Always has full regs, so remove remnant checks
powerpc: Use SET_TRAP and avoid open-coding trap masking
powerpc: TRAP_IS_SYSCALL helper to hide syscall trap number
powerpc: Use trap metadata to prevent double restart rather than
zeroing trap
arch/powerpc/include/asm/ptrace.h | 31 +++-
arch/powerpc/include/asm/syscall.h | 5 +-
arch/powerpc/kernel/process.c | 4 +-
arch/powerpc/kernel/ptrace/ptrace-tm.c | 2 +-
arch/powerpc/kernel/ptrace/ptrace-view.c | 2 +-
arch/powerpc/kernel/signal.c | 9 +-
arch/powerpc/kernel/signal_32.c | 2 +-
arch/powerpc/kernel/signal_64.c | 10 +-
arch/powerpc/xmon/xmon.c | 4 +-
.../testing/selftests/powerpc/signal/Makefile | 2 +-
.../powerpc/signal/sig_sc_double_restart.c | 174 ++++++++++++++++++
11 files changed, 220 insertions(+), 25 deletions(-)
create mode 100644 tools/testing/selftests/powerpc/signal/sig_sc_double_restart.c
--
2.23.0
^ permalink raw reply
* Re: [PATCH 01/21] mm: memblock: replace dereferences of memblock_region.nid with API calls
From: Baoquan He @ 2020-04-21 2:06 UTC (permalink / raw)
To: Mike Rapoport
Cc: Rich Felker, linux-ia64, linux-doc, Catalin Marinas,
Heiko Carstens, Michal Hocko, James E.J. Bottomley, Max Filippov,
Guo Ren, linux-csky, linux-parisc, sparclinux, linux-hexagon,
linux-riscv, Greg Ungerer, linux-arch, linux-s390, linux-snps-arc,
linux-c6x-dev, Brian Cain, Jonathan Corbet, linux-sh,
Helge Deller, x86, Russell King, Ley Foon Tan, Mike Rapoport,
Geert Uytterhoeven, linux-arm-kernel, Mark Salter, Matt Turner,
linux-mips, uclinux-h8-devel, linux-xtensa, linux-alpha, linux-um,
linux-m68k, Tony Luck, Greentime Hu, Paul Walmsley,
Stafford Horne, Guan Xuetao, Hoan Tran, Michal Simek,
Thomas Bogendoerfer, Yoshinori Sato, Nick Hu, linux-mm,
Vineet Gupta, linux-kernel, openrisc, Richard Weinberger,
Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <20200412194859.12663-2-rppt@kernel.org>
On 04/12/20 at 10:48pm, Mike Rapoport wrote:
> From: Mike Rapoport <rppt@linux.ibm.com>
>
> There are several places in the code that directly dereference
> memblock_region.nid despite this field being defined only when
> CONFIG_HAVE_MEMBLOCK_NODE_MAP=y.
>
> Replace these with calls to memblock_get_region_nid() to improve code
> robustness and to avoid possible breakage when
> CONFIG_HAVE_MEMBLOCK_NODE_MAP will be removed.
>
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> ---
> arch/arm64/mm/numa.c | 9 ++++++---
> arch/x86/mm/numa.c | 6 ++++--
> mm/memblock.c | 8 +++++---
> mm/page_alloc.c | 4 ++--
> 4 files changed, 17 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
> index 4decf1659700..aafcee3e3f7e 100644
> --- a/arch/arm64/mm/numa.c
> +++ b/arch/arm64/mm/numa.c
> @@ -350,13 +350,16 @@ static int __init numa_register_nodes(void)
> struct memblock_region *mblk;
>
> /* Check that valid nid is set to memblks */
> - for_each_memblock(memory, mblk)
> - if (mblk->nid == NUMA_NO_NODE || mblk->nid >= MAX_NUMNODES) {
> + for_each_memblock(memory, mblk) {
> + int mblk_nid = memblock_get_region_node(mblk);
> +
> + if (mblk_nid == NUMA_NO_NODE || mblk_nid >= MAX_NUMNODES) {
> pr_warn("Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
> - mblk->nid, mblk->base,
> + mblk_nid, mblk->base,
> mblk->base + mblk->size - 1);
> return -EINVAL;
> }
> + }
>
> /* Finally register nodes. */
> for_each_node_mask(nid, numa_nodes_parsed) {
> diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
> index 59ba008504dc..fe024b2ac796 100644
> --- a/arch/x86/mm/numa.c
> +++ b/arch/x86/mm/numa.c
> @@ -517,8 +517,10 @@ static void __init numa_clear_kernel_node_hotplug(void)
> * reserve specific pages for Sandy Bridge graphics. ]
> */
> for_each_memblock(reserved, mb_region) {
> - if (mb_region->nid != MAX_NUMNODES)
> - node_set(mb_region->nid, reserved_nodemask);
> + int nid = memblock_get_region_node(mb_region);
> +
> + if (nid != MAX_NUMNODES)
> + node_set(nid, reserved_nodemask);
> }
>
> /*
> diff --git a/mm/memblock.c b/mm/memblock.c
> index c79ba6f9920c..43e2fd3006c1 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -1207,13 +1207,15 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid,
> {
> struct memblock_type *type = &memblock.memory;
> struct memblock_region *r;
> + int r_nid;
>
> while (++*idx < type->cnt) {
> r = &type->regions[*idx];
> + r_nid = memblock_get_region_node(r);
>
> if (PFN_UP(r->base) >= PFN_DOWN(r->base + r->size))
> continue;
> - if (nid == MAX_NUMNODES || nid == r->nid)
> + if (nid == MAX_NUMNODES || nid == r_nid)
> break;
> }
> if (*idx >= type->cnt) {
> @@ -1226,7 +1228,7 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid,
> if (out_end_pfn)
> *out_end_pfn = PFN_DOWN(r->base + r->size);
> if (out_nid)
> - *out_nid = r->nid;
> + *out_nid = r_nid;
> }
>
> /**
> @@ -1810,7 +1812,7 @@ int __init_memblock memblock_search_pfn_nid(unsigned long pfn,
> *start_pfn = PFN_DOWN(type->regions[mid].base);
> *end_pfn = PFN_DOWN(type->regions[mid].base + type->regions[mid].size);
>
> - return type->regions[mid].nid;
> + return memblock_get_region_node(&type->regions[mid]);
> }
> #endif
>
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 69827d4fa052..0d012eda1694 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -7208,7 +7208,7 @@ static void __init find_zone_movable_pfns_for_nodes(void)
> if (!memblock_is_hotpluggable(r))
> continue;
>
> - nid = r->nid;
> + nid = memblock_get_region_node(r);
>
> usable_startpfn = PFN_DOWN(r->base);
> zone_movable_pfn[nid] = zone_movable_pfn[nid] ?
> @@ -7229,7 +7229,7 @@ static void __init find_zone_movable_pfns_for_nodes(void)
> if (memblock_is_mirror(r))
> continue;
>
> - nid = r->nid;
> + nid = memblock_get_region_node(r);
>
> usable_startpfn = memblock_region_memory_base_pfn(r);
Looks good to me.
Reviewed-by: Baoquan He <bhe@redhat.com>
^ permalink raw reply
* Re: [PATCH 1/2] powerpc: Add base support for ISA v3.1
From: Oliver O'Halloran @ 2020-04-21 1:58 UTC (permalink / raw)
To: Alistair Popple; +Cc: Michael Neuling, linuxppc-dev, Nicholas Piggin
In-Reply-To: <2992996.BaUphQCMZx@townsend>
On Tue, Apr 21, 2020 at 11:53 AM Alistair Popple <alistair@popple.id.au> wrote:
>
> On Tuesday, 21 April 2020 11:30:52 AM AEST Alistair Popple wrote:
> > On Saturday, 4 April 2020 2:32:08 AM AEST Segher Boessenkool wrote:
> > > Hi!
> > >
> > > On Fri, Apr 03, 2020 at 03:10:54PM +1100, Alistair Popple wrote:
> > > > +#define PCR_ARCH_300 0x10 /* Architecture 3.00 */
> > >
> > > It's called 3.0, not 3.00?
> >
> > Thanks. I'll fix that up.
>
> Actually we have already defined it upstream as CPU_FTR_ARCH_300 in arch/
> powerpc/include/asm/cputable.h and PVR_ARCH_300 in arch/powerpc/include/asm/
> reg.h so for consistency we should make it the same here. So either we leave
> this patch as is or we change it to PCR_ARCH_30 along with the existing
> upstream #defines. Thoughts?
I used 300 for consistency with the existing three digit definitions
when I added the CPU_FTR macro. It doesn't really matter since these
are all internal definitions, but I SAY THE BIKESHED SHOULD BE THREE
DIGITS LONG.
Oliver
^ permalink raw reply
* Re: [PATCH 1/2] powerpc: Add base support for ISA v3.1
From: Alistair Popple @ 2020-04-21 1:52 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: mikey, linuxppc-dev, npiggin
In-Reply-To: <2217912.fZQhC0vD34@townsend>
On Tuesday, 21 April 2020 11:30:52 AM AEST Alistair Popple wrote:
> On Saturday, 4 April 2020 2:32:08 AM AEST Segher Boessenkool wrote:
> > Hi!
> >
> > On Fri, Apr 03, 2020 at 03:10:54PM +1100, Alistair Popple wrote:
> > > +#define PCR_ARCH_300 0x10 /* Architecture 3.00 */
> >
> > It's called 3.0, not 3.00?
>
> Thanks. I'll fix that up.
Actually we have already defined it upstream as CPU_FTR_ARCH_300 in arch/
powerpc/include/asm/cputable.h and PVR_ARCH_300 in arch/powerpc/include/asm/
reg.h so for consistency we should make it the same here. So either we leave
this patch as is or we change it to PCR_ARCH_30 along with the existing
upstream #defines. Thoughts?
- Alistair
> - Alistair
>
> > Segher
^ permalink raw reply
* Re: [PATCH 1/2] powerpc: Add base support for ISA v3.1
From: Alistair Popple @ 2020-04-21 1:30 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: mikey, linuxppc-dev, npiggin
In-Reply-To: <20200403153208.GI26902@gate.crashing.org>
On Saturday, 4 April 2020 2:32:08 AM AEST Segher Boessenkool wrote:
> Hi!
>
> On Fri, Apr 03, 2020 at 03:10:54PM +1100, Alistair Popple wrote:
> > +#define PCR_ARCH_300 0x10 /* Architecture 3.00 */
>
> It's called 3.0, not 3.00?
Thanks. I'll fix that up.
- Alistair
>
> Segher
^ permalink raw reply
* Re: [PATCH 4/5] powerpc: Replace _ALIGN() by ALIGN()
From: Joel Stanley @ 2020-04-21 1:11 UTC (permalink / raw)
To: Christophe Leroy
Cc: linux-fbdev, kvm, Linux Kernel Mailing List, dri-devel,
Paul Mackerras, alsa-devel, linuxppc-dev
In-Reply-To: <4006d9c8e69f8eaccee954899f6b5fb76240d00b.1587407777.git.christophe.leroy@c-s.fr>
On Mon, 20 Apr 2020 at 18:39, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> _ALIGN() is specific to powerpc
> ALIGN() is generic and does the same
>
> Replace _ALIGN() by ALIGN()
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: Joel Stanley <joel@jms.id.au>
> ---
> arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +-
> arch/powerpc/include/asm/nohash/32/pgtable.h | 2 +-
> arch/powerpc/kernel/prom_init.c | 8 ++++----
> arch/powerpc/platforms/powermac/bootx_init.c | 4 ++--
> 4 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
> index 53b5c93eaf5d..0d4bccb4b9f2 100644
> --- a/arch/powerpc/include/asm/book3s/32/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
> @@ -188,7 +188,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
> * memory shall not share segments.
> */
> #if defined(CONFIG_STRICT_KERNEL_RWX) && defined(CONFIG_MODULES)
> -#define VMALLOC_START ((_ALIGN((long)high_memory, 256L << 20) + VMALLOC_OFFSET) & \
> +#define VMALLOC_START ((ALIGN((long)high_memory, 256L << 20) + VMALLOC_OFFSET) & \
> ~(VMALLOC_OFFSET - 1))
> #else
> #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
> diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
> index 5b4d4c4297e1..4315d40906a0 100644
> --- a/arch/powerpc/include/asm/nohash/32/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
> @@ -110,7 +110,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
> */
> #define VMALLOC_OFFSET (0x1000000) /* 16M */
> #ifdef PPC_PIN_SIZE
> -#define VMALLOC_START (((_ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
> +#define VMALLOC_START (((ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
Perhaps this once needed to be more flexiable, but now it always
aligns to 256M and then to 16MB.
> #else
> #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
This is an open coded align to VMALLOC_OFFSET.
> #endif
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 3a5a7db4564f..e3a9fde51c4f 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -2426,7 +2426,7 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
> {
> void *ret;
>
> - *mem_start = _ALIGN(*mem_start, align);
> + *mem_start = ALIGN(*mem_start, align);
> while ((*mem_start + needed) > *mem_end) {
> unsigned long room, chunk;
>
> @@ -2562,7 +2562,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
> *lp++ = *p;
> }
> *lp = 0;
> - *mem_start = _ALIGN((unsigned long)lp + 1, 4);
> + *mem_start = ALIGN((unsigned long)lp + 1, 4);
> }
>
> /* get it again for debugging */
> @@ -2608,7 +2608,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
> /* push property content */
> valp = make_room(mem_start, mem_end, l, 4);
> call_prom("getprop", 4, 1, node, pname, valp, l);
> - *mem_start = _ALIGN(*mem_start, 4);
> + *mem_start = ALIGN(*mem_start, 4);
>
> if (!prom_strcmp(pname, "phandle"))
> has_phandle = 1;
> @@ -2667,7 +2667,7 @@ static void __init flatten_device_tree(void)
> prom_panic ("couldn't get device tree root\n");
>
> /* Build header and make room for mem rsv map */
> - mem_start = _ALIGN(mem_start, 4);
> + mem_start = ALIGN(mem_start, 4);
> hdr = make_room(&mem_start, &mem_end,
> sizeof(struct boot_param_header), 4);
> dt_header_start = (unsigned long)hdr;
> diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
> index c3374a90952f..9d4ecd292255 100644
> --- a/arch/powerpc/platforms/powermac/bootx_init.c
> +++ b/arch/powerpc/platforms/powermac/bootx_init.c
> @@ -386,7 +386,7 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
> hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase;
>
> /* Build structure */
> - mem_end = _ALIGN(mem_end, 16);
> + mem_end = ALIGN(mem_end, 16);
> DBG("Building device tree structure at: %x\n", mem_end);
> hdr->off_dt_struct = mem_end - mem_start;
> bootx_scan_dt_build_struct(base, 4, &mem_end);
> @@ -404,7 +404,7 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
> * also bump mem_reserve_cnt to cause further reservations to
> * fail since it's too late.
> */
> - mem_end = _ALIGN(mem_end, PAGE_SIZE);
> + mem_end = ALIGN(mem_end, PAGE_SIZE);
> DBG("End of boot params: %x\n", mem_end);
> rsvmap[0] = mem_start;
> rsvmap[1] = mem_end;
> --
> 2.25.0
>
^ permalink raw reply
* Re: [PATCH 5/5] powerpc: Remove _ALIGN_UP(), _ALIGN_DOWN() and _ALIGN()
From: Joel Stanley @ 2020-04-21 1:04 UTC (permalink / raw)
To: Christophe Leroy
Cc: linux-fbdev, kvm, Linux Kernel Mailing List, dri-devel,
Paul Mackerras, alsa-devel, linuxppc-dev
In-Reply-To: <bb0a6081f7b95ee64ca20f92483e5b9661cbacb2.1587407777.git.christophe.leroy@c-s.fr>
On Mon, 20 Apr 2020 at 18:39, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> These three powerpc macros have been replaced by
> equivalent generic macros and are not used anymore.
>
> Remove them.
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-By: Joel Stanley <joel@jms.id.au>
riscv has a copy of these too that could probably be removed:
arch/riscv/include/asm/page.h:#define _ALIGN_UP(addr, size)
(((addr)+((size)-1))&(~((size)-1)))
arch/riscv/include/asm/page.h:#define _ALIGN(addr, size)
_ALIGN_UP(addr, size)
> ---
> arch/powerpc/include/asm/page.h | 7 -------
> 1 file changed, 7 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
> index 3ee8df0f66e0..a63fe6f3a0ff 100644
> --- a/arch/powerpc/include/asm/page.h
> +++ b/arch/powerpc/include/asm/page.h
> @@ -249,13 +249,6 @@ static inline bool pfn_valid(unsigned long pfn)
> #include <asm/page_32.h>
> #endif
>
> -/* align addr on a size boundary - adjust address up/down if needed */
> -#define _ALIGN_UP(addr, size) __ALIGN_KERNEL(addr, size)
> -#define _ALIGN_DOWN(addr, size) ((addr)&(~((typeof(addr))(size)-1)))
> -
> -/* align addr on a size boundary - adjust address up if needed */
> -#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
> -
> /*
> * Don't compare things with KERNELBASE or PAGE_OFFSET to test for
> * "kernelness", use is_kernel_addr() - it should do what you want.
> --
> 2.25.0
>
^ permalink raw reply
* Re: [PATCH 3/5] powerpc: Replace _ALIGN_UP() by ALIGN()
From: Joel Stanley @ 2020-04-21 1:04 UTC (permalink / raw)
To: Christophe Leroy
Cc: linux-fbdev, kvm, Linux Kernel Mailing List, dri-devel,
Paul Mackerras, alsa-devel, linuxppc-dev
In-Reply-To: <8a6d7e45f7904c73a0af539642d3962e2a3c7268.1587407777.git.christophe.leroy@c-s.fr>
On Mon, 20 Apr 2020 at 18:39, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> _ALIGN_UP() is specific to powerpc
> ALIGN() is generic and does the same
>
> Replace _ALIGN_UP() by ALIGN()
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: Joel Stanley <joel@jms.id.au>
> ---
> arch/powerpc/include/asm/iommu.h | 4 ++--
> arch/powerpc/kernel/head_booke.h | 2 +-
> arch/powerpc/kernel/nvram_64.c | 4 ++--
> arch/powerpc/kernel/pci_64.c | 2 +-
> arch/powerpc/kernel/prom.c | 4 ++--
> arch/powerpc/kernel/prom_init.c | 8 ++++----
> arch/powerpc/kvm/book3s_64_vio_hv.c | 2 +-
> arch/powerpc/mm/book3s64/hash_tlb.c | 2 +-
> arch/powerpc/mm/book3s64/radix_pgtable.c | 2 +-
> arch/powerpc/mm/slice.c | 2 +-
> arch/powerpc/platforms/cell/iommu.c | 6 +++---
> arch/powerpc/platforms/powermac/bootx_init.c | 10 +++++-----
> arch/powerpc/platforms/powernv/pci-ioda.c | 8 ++++----
> arch/powerpc/platforms/ps3/mm.c | 16 ++++++++--------
> arch/powerpc/platforms/ps3/setup.c | 2 +-
> 15 files changed, 37 insertions(+), 37 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
> index 350101e11ddb..5032f1593299 100644
> --- a/arch/powerpc/include/asm/iommu.h
> +++ b/arch/powerpc/include/asm/iommu.h
> @@ -22,11 +22,11 @@
> #define IOMMU_PAGE_SHIFT_4K 12
> #define IOMMU_PAGE_SIZE_4K (ASM_CONST(1) << IOMMU_PAGE_SHIFT_4K)
> #define IOMMU_PAGE_MASK_4K (~((1 << IOMMU_PAGE_SHIFT_4K) - 1))
> -#define IOMMU_PAGE_ALIGN_4K(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE_4K)
> +#define IOMMU_PAGE_ALIGN_4K(addr) ALIGN(addr, IOMMU_PAGE_SIZE_4K)
>
> #define IOMMU_PAGE_SIZE(tblptr) (ASM_CONST(1) << (tblptr)->it_page_shift)
> #define IOMMU_PAGE_MASK(tblptr) (~((1 << (tblptr)->it_page_shift) - 1))
> -#define IOMMU_PAGE_ALIGN(addr, tblptr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE(tblptr))
> +#define IOMMU_PAGE_ALIGN(addr, tblptr) ALIGN(addr, IOMMU_PAGE_SIZE(tblptr))
>
> /* Boot time flags */
> extern int iommu_is_off;
> diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
> index bd2e5ed8dd50..18f87bf9e32b 100644
> --- a/arch/powerpc/kernel/head_booke.h
> +++ b/arch/powerpc/kernel/head_booke.h
> @@ -534,7 +534,7 @@ struct exception_regs {
> };
>
> /* ensure this structure is always sized to a multiple of the stack alignment */
> -#define STACK_EXC_LVL_FRAME_SIZE _ALIGN_UP(sizeof (struct exception_regs), 16)
> +#define STACK_EXC_LVL_FRAME_SIZE ALIGN(sizeof (struct exception_regs), 16)
>
> #endif /* __ASSEMBLY__ */
> #endif /* __HEAD_BOOKE_H__ */
> diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
> index fb4f61096613..314780e8ef78 100644
> --- a/arch/powerpc/kernel/nvram_64.c
> +++ b/arch/powerpc/kernel/nvram_64.c
> @@ -854,8 +854,8 @@ loff_t __init nvram_create_partition(const char *name, int sig,
> BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16);
>
> /* Convert sizes from bytes to blocks */
> - req_size = _ALIGN_UP(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
> - min_size = _ALIGN_UP(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
> + req_size = ALIGN(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
> + min_size = ALIGN(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
>
> /* If no minimum size specified, make it the same as the
> * requested size
> diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
> index e5d05af5a9af..ff8e3fbdf663 100644
> --- a/arch/powerpc/kernel/pci_64.c
> +++ b/arch/powerpc/kernel/pci_64.c
> @@ -131,7 +131,7 @@ static int pcibios_map_phb_io_space(struct pci_controller *hose)
> unsigned long io_virt_offset;
>
> phys_page = ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
> - size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE);
> + size_page = ALIGN(hose->pci_io_size, PAGE_SIZE);
>
> /* Make sure IO area address is clear */
> hose->io_base_alloc = NULL;
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 10b5d5eafd34..1dcf0e214a22 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -97,7 +97,7 @@ static inline int overlaps_initrd(unsigned long start, unsigned long size)
> return 0;
>
> return (start + size) > ALIGN_DOWN(initrd_start, PAGE_SIZE) &&
> - start <= _ALIGN_UP(initrd_end, PAGE_SIZE);
> + start <= ALIGN(initrd_end, PAGE_SIZE);
> #else
> return 0;
> #endif
> @@ -624,7 +624,7 @@ static void __init early_reserve_mem(void)
> /* Then reserve the initrd, if any */
> if (initrd_start && (initrd_end > initrd_start)) {
> memblock_reserve(ALIGN_DOWN(__pa(initrd_start), PAGE_SIZE),
> - _ALIGN_UP(initrd_end, PAGE_SIZE) -
> + ALIGN(initrd_end, PAGE_SIZE) -
> ALIGN_DOWN(initrd_start, PAGE_SIZE));
> }
> #endif /* CONFIG_BLK_DEV_INITRD */
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 4cf5958eebd4..3a5a7db4564f 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -1449,18 +1449,18 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align)
> unsigned long addr = 0;
>
> if (align)
> - base = _ALIGN_UP(base, align);
> + base = ALIGN(base, align);
> prom_debug("%s(%lx, %lx)\n", __func__, size, align);
> if (ram_top == 0)
> prom_panic("alloc_up() called with mem not initialized\n");
>
> if (align)
> - base = _ALIGN_UP(alloc_bottom, align);
> + base = ALIGN(alloc_bottom, align);
> else
> base = alloc_bottom;
>
> for(; (base + size) <= alloc_top;
> - base = _ALIGN_UP(base + 0x100000, align)) {
> + base = ALIGN(base + 0x100000, align)) {
> prom_debug(" trying: 0x%lx\n\r", base);
> addr = (unsigned long)prom_claim(base, size, 0);
> if (addr != PROM_ERROR && addr != 0)
> @@ -1587,7 +1587,7 @@ static void __init reserve_mem(u64 base, u64 size)
> * dumb and just copy this entire array to the boot params
> */
> base = ALIGN_DOWN(base, PAGE_SIZE);
> - top = _ALIGN_UP(top, PAGE_SIZE);
> + top = ALIGN(top, PAGE_SIZE);
> size = top - base;
>
> if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
> index 6fcaf1fa8e02..2d231eb5884a 100644
> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
> @@ -208,7 +208,7 @@ static long kvmppc_rm_ioba_validate(struct kvmppc_spapr_tce_table *stt,
>
> idx = (ioba >> stt->page_shift) - stt->offset;
> sttpage = idx / TCES_PER_PAGE;
> - sttpages = _ALIGN_UP(idx % TCES_PER_PAGE + npages, TCES_PER_PAGE) /
> + sttpages = ALIGN(idx % TCES_PER_PAGE + npages, TCES_PER_PAGE) /
> TCES_PER_PAGE;
> for (i = sttpage; i < sttpage + sttpages; ++i)
> if (!stt->pages[i])
> diff --git a/arch/powerpc/mm/book3s64/hash_tlb.c b/arch/powerpc/mm/book3s64/hash_tlb.c
> index 2242d022b620..081940b85e24 100644
> --- a/arch/powerpc/mm/book3s64/hash_tlb.c
> +++ b/arch/powerpc/mm/book3s64/hash_tlb.c
> @@ -197,7 +197,7 @@ void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
> unsigned long flags;
>
> start = ALIGN_DOWN(start, PAGE_SIZE);
> - end = _ALIGN_UP(end, PAGE_SIZE);
> + end = ALIGN(end, PAGE_SIZE);
>
> BUG_ON(!mm->pgd);
>
> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
> index 8f9edf07063a..4bdfc8dff87d 100644
> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
> @@ -261,7 +261,7 @@ static int __meminit create_physical_mapping(unsigned long start,
> pgprot_t prot;
> int psize;
>
> - start = _ALIGN_UP(start, PAGE_SIZE);
> + start = ALIGN(start, PAGE_SIZE);
> for (addr = start; addr < end; addr += mapping_size) {
> unsigned long gap, previous_size;
> int rc;
> diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
> index dffe1a45b6ed..82b45b1cb973 100644
> --- a/arch/powerpc/mm/slice.c
> +++ b/arch/powerpc/mm/slice.c
> @@ -478,7 +478,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
>
> /* If hint, make sure it matches our alignment restrictions */
> if (!fixed && addr) {
> - addr = _ALIGN_UP(addr, page_size);
> + addr = ALIGN(addr, page_size);
> slice_dbg(" aligned addr=%lx\n", addr);
> /* Ignore hint if it's too large or overlaps a VMA */
> if (addr > high_limit - len || addr < mmap_min_addr ||
> diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
> index ca9ffc1c8685..2124831cf57c 100644
> --- a/arch/powerpc/platforms/cell/iommu.c
> +++ b/arch/powerpc/platforms/cell/iommu.c
> @@ -943,7 +943,7 @@ static int __init cell_iommu_fixed_mapping_init(void)
> fbase = max(fbase, dbase + dsize);
> }
>
> - fbase = _ALIGN_UP(fbase, 1 << IO_SEGMENT_SHIFT);
> + fbase = ALIGN(fbase, 1 << IO_SEGMENT_SHIFT);
> fsize = memblock_phys_mem_size();
>
> if ((fbase + fsize) <= 0x800000000ul)
> @@ -963,8 +963,8 @@ static int __init cell_iommu_fixed_mapping_init(void)
> hend = hbase + htab_size_bytes;
>
> /* The window must start and end on a segment boundary */
> - if ((hbase != _ALIGN_UP(hbase, 1 << IO_SEGMENT_SHIFT)) ||
> - (hend != _ALIGN_UP(hend, 1 << IO_SEGMENT_SHIFT))) {
> + if ((hbase != ALIGN(hbase, 1 << IO_SEGMENT_SHIFT)) ||
> + (hend != ALIGN(hend, 1 << IO_SEGMENT_SHIFT))) {
> pr_debug("iommu: hash window not segment aligned\n");
> return -1;
> }
> diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
> index af309ee99114..c3374a90952f 100644
> --- a/arch/powerpc/platforms/powermac/bootx_init.c
> +++ b/arch/powerpc/platforms/powermac/bootx_init.c
> @@ -108,7 +108,7 @@ static void * __init bootx_early_getprop(unsigned long base,
>
> #define dt_push_token(token, mem) \
> do { \
> - *(mem) = _ALIGN_UP(*(mem),4); \
> + *(mem) = ALIGN(*(mem),4); \
> *((u32 *)*(mem)) = token; \
> *(mem) += 4; \
> } while(0)
> @@ -150,7 +150,7 @@ static void __init bootx_dt_add_prop(char *name, void *data, int size,
> /* push property content */
> if (size && data) {
> memcpy((void *)*mem_end, data, size);
> - *mem_end = _ALIGN_UP(*mem_end + size, 4);
> + *mem_end = ALIGN(*mem_end + size, 4);
> }
> }
>
> @@ -303,7 +303,7 @@ static void __init bootx_scan_dt_build_struct(unsigned long base,
> *lp++ = *p;
> }
> *lp = 0;
> - *mem_end = _ALIGN_UP((unsigned long)lp + 1, 4);
> + *mem_end = ALIGN((unsigned long)lp + 1, 4);
>
> /* get and store all properties */
> while (*ppp) {
> @@ -356,11 +356,11 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
> /* Start using memory after the big blob passed by BootX, get
> * some space for the header
> */
> - mem_start = mem_end = _ALIGN_UP(((unsigned long)bi) + start, 4);
> + mem_start = mem_end = ALIGN(((unsigned long)bi) + start, 4);
> DBG("Boot params header at: %x\n", mem_start);
> hdr = (struct boot_param_header *)mem_start;
> mem_end += sizeof(struct boot_param_header);
> - rsvmap = (u64 *)(_ALIGN_UP(mem_end, 8));
> + rsvmap = (u64 *)(ALIGN(mem_end, 8));
> hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - mem_start;
> mem_end = ((unsigned long)rsvmap) + 8 * sizeof(u64);
>
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index 276b011cd45d..d1a16ebc31bb 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -265,7 +265,7 @@ static void pnv_ioda_reserve_dev_m64_pe(struct pci_dev *pdev,
> continue;
>
> start = ALIGN_DOWN(r->start - base, sgsz);
> - end = _ALIGN_UP(r->end - base, sgsz);
> + end = ALIGN(r->end - base, sgsz);
> for (segno = start / sgsz; segno < end / sgsz; segno++) {
> if (pe_bitmap)
> set_bit(segno, pe_bitmap);
> @@ -361,7 +361,7 @@ static struct pnv_ioda_pe *pnv_ioda_pick_m64_pe(struct pci_bus *bus, bool all)
> return NULL;
>
> /* Allocate bitmap */
> - size = _ALIGN_UP(phb->ioda.total_pe_num / 8, sizeof(unsigned long));
> + size = ALIGN(phb->ioda.total_pe_num / 8, sizeof(unsigned long));
> pe_alloc = kzalloc(size, GFP_KERNEL);
> if (!pe_alloc) {
> pr_warn("%s: Out of memory !\n",
> @@ -2537,7 +2537,7 @@ unsigned long pnv_pci_ioda2_get_table_size(__u32 page_shift,
> direct_table_size = 1UL << table_shift;
>
> for ( ; levels; --levels) {
> - bytes += _ALIGN_UP(tce_table_size, direct_table_size);
> + bytes += ALIGN(tce_table_size, direct_table_size);
>
> tce_table_size /= direct_table_size;
> tce_table_size <<= 3;
> @@ -3863,7 +3863,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
> PNV_IODA1_DMA32_SEGSIZE;
>
> /* Allocate aux data & arrays. We don't have IO ports on PHB3 */
> - size = _ALIGN_UP(max_t(unsigned, phb->ioda.total_pe_num, 8) / 8,
> + size = ALIGN(max_t(unsigned, phb->ioda.total_pe_num, 8) / 8,
> sizeof(unsigned long));
> m64map_off = size;
> size += phb->ioda.total_pe_num * sizeof(phb->ioda.m64_segmap[0]);
> diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
> index 71ed37f7f475..b83f2c851b40 100644
> --- a/arch/powerpc/platforms/ps3/mm.c
> +++ b/arch/powerpc/platforms/ps3/mm.c
> @@ -395,7 +395,7 @@ static struct dma_chunk * dma_find_chunk(struct ps3_dma_region *r,
> {
> struct dma_chunk *c;
> unsigned long aligned_bus = ALIGN_DOWN(bus_addr, 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len+bus_addr-aligned_bus,
> + unsigned long aligned_len = ALIGN(len+bus_addr-aligned_bus,
> 1 << r->page_size);
>
> list_for_each_entry(c, &r->chunk_list.head, link) {
> @@ -424,7 +424,7 @@ static struct dma_chunk *dma_find_chunk_lpar(struct ps3_dma_region *r,
> {
> struct dma_chunk *c;
> unsigned long aligned_lpar = ALIGN_DOWN(lpar_addr, 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len + lpar_addr - aligned_lpar,
> + unsigned long aligned_len = ALIGN(len + lpar_addr - aligned_lpar,
> 1 << r->page_size);
>
> list_for_each_entry(c, &r->chunk_list.head, link) {
> @@ -776,7 +776,7 @@ static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
> unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
> : virt_addr;
> unsigned long aligned_phys = ALIGN_DOWN(phys_addr, 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
> + unsigned long aligned_len = ALIGN(len + phys_addr - aligned_phys,
> 1 << r->page_size);
> *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
>
> @@ -831,7 +831,7 @@ static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
> unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
> : virt_addr;
> unsigned long aligned_phys = ALIGN_DOWN(phys_addr, 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
> + unsigned long aligned_len = ALIGN(len + phys_addr - aligned_phys,
> 1 << r->page_size);
>
> DBG(KERN_ERR "%s: vaddr=%#lx, len=%#lx\n", __func__,
> @@ -891,7 +891,7 @@ static int dma_sb_unmap_area(struct ps3_dma_region *r, dma_addr_t bus_addr,
> if (!c) {
> unsigned long aligned_bus = ALIGN_DOWN(bus_addr,
> 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len + bus_addr
> + unsigned long aligned_len = ALIGN(len + bus_addr
> - aligned_bus, 1 << r->page_size);
> DBG("%s:%d: not found: bus_addr %llxh\n",
> __func__, __LINE__, bus_addr);
> @@ -928,7 +928,7 @@ static int dma_ioc0_unmap_area(struct ps3_dma_region *r,
> if (!c) {
> unsigned long aligned_bus = ALIGN_DOWN(bus_addr,
> 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len + bus_addr
> + unsigned long aligned_len = ALIGN(len + bus_addr
> - aligned_bus,
> 1 << r->page_size);
> DBG("%s:%d: not found: bus_addr %llxh\n",
> @@ -974,7 +974,7 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r)
> pr_info("%s:%d: forcing 16M pages for linear map\n",
> __func__, __LINE__);
> r->page_size = PS3_DMA_16M;
> - r->len = _ALIGN_UP(r->len, 1 << r->page_size);
> + r->len = ALIGN(r->len, 1 << r->page_size);
> }
> }
>
> @@ -1125,7 +1125,7 @@ int ps3_dma_region_init(struct ps3_system_bus_device *dev,
> r->offset = lpar_addr;
> if (r->offset >= map.rm.size)
> r->offset -= map.r1.offset;
> - r->len = len ? len : _ALIGN_UP(map.total, 1 << r->page_size);
> + r->len = len ? len : ALIGN(map.total, 1 << r->page_size);
>
> switch (dev->dev_type) {
> case PS3_DEVICE_TYPE_SB:
> diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
> index b29368931c56..e9ae5dd03593 100644
> --- a/arch/powerpc/platforms/ps3/setup.c
> +++ b/arch/powerpc/platforms/ps3/setup.c
> @@ -138,7 +138,7 @@ static int __init early_parse_ps3fb(char *p)
> if (!p)
> return 1;
>
> - ps3fb_videomemory.size = _ALIGN_UP(memparse(p, &p),
> + ps3fb_videomemory.size = ALIGN(memparse(p, &p),
> ps3fb_videomemory.align);
> return 0;
> }
> --
> 2.25.0
>
^ permalink raw reply
* Re: [PATCH 2/5] powerpc: Replace _ALIGN_DOWN() by ALIGN_DOWN()
From: Joel Stanley @ 2020-04-21 1:04 UTC (permalink / raw)
To: Christophe Leroy
Cc: linux-fbdev, kvm, Linux Kernel Mailing List, dri-devel,
Paul Mackerras, alsa-devel, linuxppc-dev
In-Reply-To: <3911a86d6b5bfa7ad88cd7c82416fbe6bb47e793.1587407777.git.christophe.leroy@c-s.fr>
On Mon, 20 Apr 2020 at 18:38, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> _ALIGN_DOWN() is specific to powerpc
> ALIGN_DOWN() is generic and does the same
>
> Replace _ALIGN_DOWN() by ALIGN_DOWN()
This one is a bit less obvious. It becomes (leaving the typeof's alone
for clarity):
-((addr)&(~((typeof(addr))(size)-1)))
+((((addr) - ((size) - 1)) + ((typeof(addr))(size) - 1)) &
~((typeof(addr))(size)-1))
Which I assume the compiler will sort out?
Reviewed-by: Joel Stanley <joel@jms.id.au>
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
> arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +-
> arch/powerpc/include/asm/nohash/32/pgtable.h | 2 +-
> arch/powerpc/kernel/pci_64.c | 2 +-
> arch/powerpc/kernel/prom.c | 6 +++---
> arch/powerpc/kernel/prom_init.c | 8 ++++----
> arch/powerpc/mm/book3s64/hash_tlb.c | 4 ++--
> arch/powerpc/mm/init_64.c | 4 ++--
> arch/powerpc/platforms/powernv/opal-fadump.c | 2 +-
> arch/powerpc/platforms/powernv/pci-ioda.c | 2 +-
> arch/powerpc/platforms/ps3/mm.c | 14 +++++++-------
> arch/powerpc/platforms/pseries/rtas-fadump.c | 2 +-
> 11 files changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
> index 7549393c4c43..53b5c93eaf5d 100644
> --- a/arch/powerpc/include/asm/book3s/32/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
> @@ -195,7 +195,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
> #endif
>
> #ifdef CONFIG_KASAN_VMALLOC
> -#define VMALLOC_END _ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
> +#define VMALLOC_END ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
> #else
> #define VMALLOC_END ioremap_bot
> #endif
> diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
> index b04ba257fddb..5b4d4c4297e1 100644
> --- a/arch/powerpc/include/asm/nohash/32/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
> @@ -116,7 +116,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
> #endif
>
> #ifdef CONFIG_KASAN_VMALLOC
> -#define VMALLOC_END _ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
> +#define VMALLOC_END ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
> #else
> #define VMALLOC_END ioremap_bot
> #endif
> diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
> index f83d1f69b1dd..e5d05af5a9af 100644
> --- a/arch/powerpc/kernel/pci_64.c
> +++ b/arch/powerpc/kernel/pci_64.c
> @@ -130,7 +130,7 @@ static int pcibios_map_phb_io_space(struct pci_controller *hose)
> unsigned long size_page;
> unsigned long io_virt_offset;
>
> - phys_page = _ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
> + phys_page = ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
> size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE);
>
> /* Make sure IO area address is clear */
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 6620f37abe73..10b5d5eafd34 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -96,7 +96,7 @@ static inline int overlaps_initrd(unsigned long start, unsigned long size)
> if (!initrd_start)
> return 0;
>
> - return (start + size) > _ALIGN_DOWN(initrd_start, PAGE_SIZE) &&
> + return (start + size) > ALIGN_DOWN(initrd_start, PAGE_SIZE) &&
> start <= _ALIGN_UP(initrd_end, PAGE_SIZE);
> #else
> return 0;
> @@ -623,9 +623,9 @@ static void __init early_reserve_mem(void)
> #ifdef CONFIG_BLK_DEV_INITRD
> /* Then reserve the initrd, if any */
> if (initrd_start && (initrd_end > initrd_start)) {
> - memblock_reserve(_ALIGN_DOWN(__pa(initrd_start), PAGE_SIZE),
> + memblock_reserve(ALIGN_DOWN(__pa(initrd_start), PAGE_SIZE),
> _ALIGN_UP(initrd_end, PAGE_SIZE) -
> - _ALIGN_DOWN(initrd_start, PAGE_SIZE));
> + ALIGN_DOWN(initrd_start, PAGE_SIZE));
> }
> #endif /* CONFIG_BLK_DEV_INITRD */
>
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 806be751c336..4cf5958eebd4 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -1500,7 +1500,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align,
>
> if (highmem) {
> /* Carve out storage for the TCE table. */
> - addr = _ALIGN_DOWN(alloc_top_high - size, align);
> + addr = ALIGN_DOWN(alloc_top_high - size, align);
> if (addr <= alloc_bottom)
> return 0;
> /* Will we bump into the RMO ? If yes, check out that we
> @@ -1518,9 +1518,9 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align,
> goto bail;
> }
>
> - base = _ALIGN_DOWN(alloc_top - size, align);
> + base = ALIGN_DOWN(alloc_top - size, align);
> for (; base > alloc_bottom;
> - base = _ALIGN_DOWN(base - 0x100000, align)) {
> + base = ALIGN_DOWN(base - 0x100000, align)) {
> prom_debug(" trying: 0x%lx\n\r", base);
> addr = (unsigned long)prom_claim(base, size, 0);
> if (addr != PROM_ERROR && addr != 0)
> @@ -1586,7 +1586,7 @@ static void __init reserve_mem(u64 base, u64 size)
> * have our terminator with "size" set to 0 since we are
> * dumb and just copy this entire array to the boot params
> */
> - base = _ALIGN_DOWN(base, PAGE_SIZE);
> + base = ALIGN_DOWN(base, PAGE_SIZE);
> top = _ALIGN_UP(top, PAGE_SIZE);
> size = top - base;
>
> diff --git a/arch/powerpc/mm/book3s64/hash_tlb.c b/arch/powerpc/mm/book3s64/hash_tlb.c
> index 4a70d8dd39cd..2242d022b620 100644
> --- a/arch/powerpc/mm/book3s64/hash_tlb.c
> +++ b/arch/powerpc/mm/book3s64/hash_tlb.c
> @@ -196,7 +196,7 @@ void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
> int hugepage_shift;
> unsigned long flags;
>
> - start = _ALIGN_DOWN(start, PAGE_SIZE);
> + start = ALIGN_DOWN(start, PAGE_SIZE);
> end = _ALIGN_UP(end, PAGE_SIZE);
>
> BUG_ON(!mm->pgd);
> @@ -238,7 +238,7 @@ void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd, unsigned long addr)
> pte_t *start_pte;
> unsigned long flags;
>
> - addr = _ALIGN_DOWN(addr, PMD_SIZE);
> + addr = ALIGN_DOWN(addr, PMD_SIZE);
> /*
> * Note: Normally, we should only ever use a batch within a
> * PTE locked section. This violates the rule, but will work
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 4002ced3596f..c7ce4ec5060e 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -203,7 +203,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
> unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
>
> /* Align to the page size of the linear mapping. */
> - start = _ALIGN_DOWN(start, page_size);
> + start = ALIGN_DOWN(start, page_size);
>
> pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node);
>
> @@ -292,7 +292,7 @@ void __ref vmemmap_free(unsigned long start, unsigned long end,
> unsigned long alt_start = ~0, alt_end = ~0;
> unsigned long base_pfn;
>
> - start = _ALIGN_DOWN(start, page_size);
> + start = ALIGN_DOWN(start, page_size);
> if (altmap) {
> alt_start = altmap->base_pfn;
> alt_end = altmap->base_pfn + altmap->reserve +
> diff --git a/arch/powerpc/platforms/powernv/opal-fadump.c b/arch/powerpc/platforms/powernv/opal-fadump.c
> index d361d37d975f..9a360ced663b 100644
> --- a/arch/powerpc/platforms/powernv/opal-fadump.c
> +++ b/arch/powerpc/platforms/powernv/opal-fadump.c
> @@ -671,7 +671,7 @@ void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
> * Firmware supports 32-bit field for size. Align it to PAGE_SIZE
> * and request firmware to copy multiple kernel boot memory regions.
> */
> - fadump_conf->max_copy_size = _ALIGN_DOWN(U32_MAX, PAGE_SIZE);
> + fadump_conf->max_copy_size = ALIGN_DOWN(U32_MAX, PAGE_SIZE);
>
> /*
> * Check if dump has been initiated on last reboot.
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index 57d3a6af1d52..276b011cd45d 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -264,7 +264,7 @@ static void pnv_ioda_reserve_dev_m64_pe(struct pci_dev *pdev,
> if (!r->parent || !pnv_pci_is_m64(phb, r))
> continue;
>
> - start = _ALIGN_DOWN(r->start - base, sgsz);
> + start = ALIGN_DOWN(r->start - base, sgsz);
> end = _ALIGN_UP(r->end - base, sgsz);
> for (segno = start / sgsz; segno < end / sgsz; segno++) {
> if (pe_bitmap)
> diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
> index 423be34f0f5f..71ed37f7f475 100644
> --- a/arch/powerpc/platforms/ps3/mm.c
> +++ b/arch/powerpc/platforms/ps3/mm.c
> @@ -263,7 +263,7 @@ static int ps3_mm_region_create(struct mem_region *r, unsigned long size)
> int result;
> u64 muid;
>
> - r->size = _ALIGN_DOWN(size, 1 << PAGE_SHIFT_16M);
> + r->size = ALIGN_DOWN(size, 1 << PAGE_SHIFT_16M);
>
> DBG("%s:%d requested %lxh\n", __func__, __LINE__, size);
> DBG("%s:%d actual %llxh\n", __func__, __LINE__, r->size);
> @@ -394,7 +394,7 @@ static struct dma_chunk * dma_find_chunk(struct ps3_dma_region *r,
> unsigned long bus_addr, unsigned long len)
> {
> struct dma_chunk *c;
> - unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size);
> + unsigned long aligned_bus = ALIGN_DOWN(bus_addr, 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len+bus_addr-aligned_bus,
> 1 << r->page_size);
>
> @@ -423,7 +423,7 @@ static struct dma_chunk *dma_find_chunk_lpar(struct ps3_dma_region *r,
> unsigned long lpar_addr, unsigned long len)
> {
> struct dma_chunk *c;
> - unsigned long aligned_lpar = _ALIGN_DOWN(lpar_addr, 1 << r->page_size);
> + unsigned long aligned_lpar = ALIGN_DOWN(lpar_addr, 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len + lpar_addr - aligned_lpar,
> 1 << r->page_size);
>
> @@ -775,7 +775,7 @@ static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
> struct dma_chunk *c;
> unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
> : virt_addr;
> - unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
> + unsigned long aligned_phys = ALIGN_DOWN(phys_addr, 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
> 1 << r->page_size);
> *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
> @@ -830,7 +830,7 @@ static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
> struct dma_chunk *c;
> unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
> : virt_addr;
> - unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
> + unsigned long aligned_phys = ALIGN_DOWN(phys_addr, 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
> 1 << r->page_size);
>
> @@ -889,7 +889,7 @@ static int dma_sb_unmap_area(struct ps3_dma_region *r, dma_addr_t bus_addr,
> c = dma_find_chunk(r, bus_addr, len);
>
> if (!c) {
> - unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
> + unsigned long aligned_bus = ALIGN_DOWN(bus_addr,
> 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len + bus_addr
> - aligned_bus, 1 << r->page_size);
> @@ -926,7 +926,7 @@ static int dma_ioc0_unmap_area(struct ps3_dma_region *r,
> c = dma_find_chunk(r, bus_addr, len);
>
> if (!c) {
> - unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
> + unsigned long aligned_bus = ALIGN_DOWN(bus_addr,
> 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len + bus_addr
> - aligned_bus,
> diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.c b/arch/powerpc/platforms/pseries/rtas-fadump.c
> index 70c3013fdd07..81343908ed33 100644
> --- a/arch/powerpc/platforms/pseries/rtas-fadump.c
> +++ b/arch/powerpc/platforms/pseries/rtas-fadump.c
> @@ -506,7 +506,7 @@ void __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
> fadump_conf->fadump_supported = 1;
>
> /* Firmware supports 64-bit value for size, align it to pagesize. */
> - fadump_conf->max_copy_size = _ALIGN_DOWN(U64_MAX, PAGE_SIZE);
> + fadump_conf->max_copy_size = ALIGN_DOWN(U64_MAX, PAGE_SIZE);
>
> /*
> * The 'ibm,kernel-dump' rtas node is present only if there is
> --
> 2.25.0
>
^ permalink raw reply
* Re: [PATCH 1/5] drivers/powerpc: Replace _ALIGN_UP() by ALIGN()
From: Joel Stanley @ 2020-04-21 0:49 UTC (permalink / raw)
To: Christophe Leroy
Cc: alsa-devel, kvm, Linux Kernel Mailing List, dri-devel,
Paul Mackerras, linux-fbdev, linuxppc-dev
In-Reply-To: <a5945463f86c984151962a475a3ee56a2893e85d.1587407777.git.christophe.leroy@c-s.fr>
On Mon, 20 Apr 2020 at 18:37, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> _ALIGN_UP() is specific to powerpc
> ALIGN() is generic and does the same
>
> Replace _ALIGN_UP() by ALIGN()
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
I was curious, so I expanded out the kernel one. Here's the diff:
- (((addr)+((size)-1))&(~((typeof(addr))(size)-1)))
+ (((addr)+((typeof(addr))(size) - 1))&~((typeof(addr))(size)-1))
So it adds a cast, but aside from that it's the same.
Reviewed-by: Joel Stanley <joel@jms.id.au>
> ---
> drivers/ps3/ps3-lpm.c | 6 +++---
> drivers/vfio/pci/vfio_pci_nvlink2.c | 2 +-
> drivers/video/fbdev/ps3fb.c | 4 ++--
> sound/ppc/snd_ps3.c | 2 +-
> 4 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c
> index 83c45659bc9d..064b5884ba13 100644
> --- a/drivers/ps3/ps3-lpm.c
> +++ b/drivers/ps3/ps3-lpm.c
> @@ -1096,8 +1096,8 @@ int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
> lpm_priv->tb_cache_internal = NULL;
> lpm_priv->tb_cache = NULL;
> } else if (tb_cache) {
> - if (tb_cache != (void *)_ALIGN_UP((unsigned long)tb_cache, 128)
> - || tb_cache_size != _ALIGN_UP(tb_cache_size, 128)) {
> + if (tb_cache != (void *)ALIGN((unsigned long)tb_cache, 128)
> + || tb_cache_size != ALIGN(tb_cache_size, 128)) {
> dev_err(sbd_core(), "%s:%u: unaligned tb_cache\n",
> __func__, __LINE__);
> result = -EINVAL;
> @@ -1116,7 +1116,7 @@ int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
> result = -ENOMEM;
> goto fail_malloc;
> }
> - lpm_priv->tb_cache = (void *)_ALIGN_UP(
> + lpm_priv->tb_cache = (void *)ALIGN(
> (unsigned long)lpm_priv->tb_cache_internal, 128);
> }
>
> diff --git a/drivers/vfio/pci/vfio_pci_nvlink2.c b/drivers/vfio/pci/vfio_pci_nvlink2.c
> index ed20d73cc27c..65c61710c0e9 100644
> --- a/drivers/vfio/pci/vfio_pci_nvlink2.c
> +++ b/drivers/vfio/pci/vfio_pci_nvlink2.c
> @@ -67,7 +67,7 @@ static size_t vfio_pci_nvgpu_rw(struct vfio_pci_device *vdev,
> *
> * This is not fast path anyway.
> */
> - sizealigned = _ALIGN_UP(posoff + count, PAGE_SIZE);
> + sizealigned = ALIGN(posoff + count, PAGE_SIZE);
> ptr = ioremap_cache(data->gpu_hpa + posaligned, sizealigned);
> if (!ptr)
> return -EFAULT;
> diff --git a/drivers/video/fbdev/ps3fb.c b/drivers/video/fbdev/ps3fb.c
> index 834f63edf700..9df78fb77267 100644
> --- a/drivers/video/fbdev/ps3fb.c
> +++ b/drivers/video/fbdev/ps3fb.c
> @@ -44,7 +44,7 @@
> #define GPU_CMD_BUF_SIZE (2 * 1024 * 1024)
> #define GPU_FB_START (64 * 1024)
> #define GPU_IOIF (0x0d000000UL)
> -#define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64)
> +#define GPU_ALIGN_UP(x) ALIGN((x), 64)
> #define GPU_MAX_LINE_LENGTH (65536 - 64)
>
> #define GPU_INTR_STATUS_VSYNC_0 0 /* vsync on head A */
> @@ -1015,7 +1015,7 @@ static int ps3fb_probe(struct ps3_system_bus_device *dev)
> }
> #endif
>
> - max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF;
> + max_ps3fb_size = ALIGN(GPU_IOIF, 256*1024*1024) - GPU_IOIF;
> if (ps3fb_videomemory.size > max_ps3fb_size) {
> dev_info(&dev->core, "Limiting ps3fb mem size to %lu bytes\n",
> max_ps3fb_size);
> diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
> index 6d2a33b8faa0..b8161a08f2ca 100644
> --- a/sound/ppc/snd_ps3.c
> +++ b/sound/ppc/snd_ps3.c
> @@ -926,7 +926,7 @@ static int snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
> PAGE_SHIFT, /* use system page size */
> 0, /* dma type; not used */
> NULL,
> - _ALIGN_UP(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE));
> + ALIGN(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE));
> dev->d_region->ioid = PS3_AUDIO_IOID;
>
> ret = ps3_dma_region_create(dev->d_region);
> --
> 2.25.0
>
^ permalink raw reply
* Re: [PATCH v3 02/13] powerpc/40x: Rework 40x PTE access and TLB miss
From: kbuild test robot @ 2020-04-21 0:47 UTC (permalink / raw)
To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
Michael Ellerman, michal.simek, arnd
Cc: linuxppc-dev, kbuild-all, linux-kernel
In-Reply-To: <9988528a455bb8c9962e2ea9e8df06ebca8cded1.1586852082.git.christophe.leroy@c-s.fr>
[-- Attachment #1: Type: text/plain, Size: 7571 bytes --]
Hi Christophe,
I love your patch! Yet something to improve:
[auto build test ERROR on powerpc/next]
[also build test ERROR on robh/for-next char-misc/char-misc-testing tip/locking/core linus/master v5.7-rc2 next-20200420]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Christophe-Leroy/Modernise-powerpc-40x/20200414-185156
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-ppc40x_defconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day GCC_VERSION=9.3.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
arch/powerpc/mm/nohash/40x.c: In function 'mmu_mapin_ram':
>> arch/powerpc/mm/nohash/40x.c:107:3: error: expected ',' or ';' before 'pmdp'
107 | pmdp = pmd_ptr_k(v);
| ^~~~
vim +107 arch/powerpc/mm/nohash/40x.c
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 90
14e609d693ef67 arch/powerpc/mm/40x_mmu.c Christophe Leroy 2019-02-21 91 unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 92 {
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 93 unsigned long v, s, mapped;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 94 phys_addr_t p;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 95
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 96 v = KERNELBASE;
99c62dd773797b arch/powerpc/mm/40x_mmu.c Kumar Gala 2008-04-16 97 p = 0;
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 98 s = total_lowmem;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 99
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 100 if (__map_without_ltlbs)
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 101 return 0;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 102
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 103 while (s >= LARGE_PAGE_SIZE_16M) {
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 104 pmd_t *pmdp;
682f715365c25b arch/powerpc/mm/nohash/40x.c Christophe Leroy 2020-04-14 105 unsigned long val = p | _PMD_SIZE_16M | _PAGE_EXEC | _PAGE_RW
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 106
0b1c524caaae24 arch/powerpc/mm/nohash/40x.c Christophe Leroy 2020-01-09 @107 pmdp = pmd_ptr_k(v);
f281b5d50c87ec arch/powerpc/mm/40x_mmu.c Aneesh Kumar K.V 2015-12-01 108 *pmdp++ = __pmd(val);
f281b5d50c87ec arch/powerpc/mm/40x_mmu.c Aneesh Kumar K.V 2015-12-01 109 *pmdp++ = __pmd(val);
f281b5d50c87ec arch/powerpc/mm/40x_mmu.c Aneesh Kumar K.V 2015-12-01 110 *pmdp++ = __pmd(val);
f281b5d50c87ec arch/powerpc/mm/40x_mmu.c Aneesh Kumar K.V 2015-12-01 111 *pmdp++ = __pmd(val);
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 112
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 113 v += LARGE_PAGE_SIZE_16M;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 114 p += LARGE_PAGE_SIZE_16M;
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 115 s -= LARGE_PAGE_SIZE_16M;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 116 }
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 117
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 118 while (s >= LARGE_PAGE_SIZE_4M) {
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 119 pmd_t *pmdp;
682f715365c25b arch/powerpc/mm/nohash/40x.c Christophe Leroy 2020-04-14 120 unsigned long val = p | _PMD_SIZE_4M | _PAGE_EXEC | _PAGE_RW;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 121
0b1c524caaae24 arch/powerpc/mm/nohash/40x.c Christophe Leroy 2020-01-09 122 pmdp = pmd_ptr_k(v);
f281b5d50c87ec arch/powerpc/mm/40x_mmu.c Aneesh Kumar K.V 2015-12-01 123 *pmdp = __pmd(val);
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 124
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 125 v += LARGE_PAGE_SIZE_4M;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 126 p += LARGE_PAGE_SIZE_4M;
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 127 s -= LARGE_PAGE_SIZE_4M;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 128 }
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 129
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 130 mapped = total_lowmem - s;
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 131
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 132 /* If the size of RAM is not an exact power of two, we may not
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 133 * have covered RAM in its entirety with 16 and 4 MiB
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 134 * pages. Consequently, restrict the top end of RAM currently
95f72d1ed41a66 arch/powerpc/mm/40x_mmu.c Yinghai Lu 2010-07-12 135 * allocable so that calls to the MEMBLOCK to allocate PTEs for "tail"
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 136 * coverage with normal-sized pages (or other reasons) do not
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 137 * attempt to allocate outside the allowed range.
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 138 */
cd3db0c4ca3d23 arch/powerpc/mm/40x_mmu.c Benjamin Herrenschmidt 2010-07-06 139 memblock_set_current_limit(mapped);
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 140
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 141 return mapped;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 142 }
cd3db0c4ca3d23 arch/powerpc/mm/40x_mmu.c Benjamin Herrenschmidt 2010-07-06 143
:::::: The code at line 107 was first introduced by commit
:::::: 0b1c524caaae2428b20e714297243e5551251eb5 powerpc/32: refactor pmd_offset(pud_offset(pgd_offset...
:::::: TO: Christophe Leroy <christophe.leroy@c-s.fr>
:::::: CC: Michael Ellerman <mpe@ellerman.id.au>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 15348 bytes --]
^ permalink raw reply
* Re: [PATCH v3 0/4] Clean up hugetlb boot command line processing
From: Anders Roxell @ 2020-04-20 22:53 UTC (permalink / raw)
To: Mike Kravetz
Cc: linux-doc, Dave Hansen, Heiko Carstens, Peter Xu, Linux-MM,
Paul Mackerras, sparclinux, linux-riscv, Will Deacon,
Mina Almasry, linux-s390, Jonathan Corbet, Christian Borntraeger,
Ingo Molnar, Catalin Marinas, Longpeng, Albert Ou, Vasily Gorbik,
Qian Cai, Paul Walmsley, Thomas Gleixner, Linux ARM,
Nitesh Narayan Lal, Randy Dunlap, LKML, Palmer Dabbelt,
Andrew Morton, linuxppc-dev, David S.Miller
In-Reply-To: <86333853-0648-393f-db96-d581ee114d2b@oracle.com>
On Mon, 20 Apr 2020 at 23:43, Mike Kravetz <mike.kravetz@oracle.com> wrote:
>
> On 4/20/20 1:29 PM, Anders Roxell wrote:
> > On Mon, 20 Apr 2020 at 20:23, Mike Kravetz <mike.kravetz@oracle.com> wrote:
> >> On 4/20/20 8:34 AM, Qian Cai wrote:
> >>>
> >>> Reverted this series fixed many undefined behaviors on arm64 with the config,
> >> While rearranging the code (patch 3 in series), I made the incorrect
> >> assumption that CONT_XXX_SIZE == (1UL << CONT_XXX_SHIFT). However,
> >> this is not the case. Does the following patch fix these issues?
> >>
> >> From b75cb4a0852e208bee8c4eb347dc076fcaa88859 Mon Sep 17 00:00:00 2001
> >> From: Mike Kravetz <mike.kravetz@oracle.com>
> >> Date: Mon, 20 Apr 2020 10:41:18 -0700
> >> Subject: [PATCH] arm64/hugetlb: fix hugetlb initialization
> >>
> >> When calling hugetlb_add_hstate() to initialize a new hugetlb size,
> >> be sure to use correct huge pages size order.
> >>
> >> Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
> >> ---
> >> arch/arm64/mm/hugetlbpage.c | 8 ++++----
> >> 1 file changed, 4 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> >> index 9ca840527296..a02411a1f19a 100644
> >> --- a/arch/arm64/mm/hugetlbpage.c
> >> +++ b/arch/arm64/mm/hugetlbpage.c
> >> @@ -453,11 +453,11 @@ void huge_ptep_clear_flush(struct vm_area_struct *vma,
> >> static int __init hugetlbpage_init(void)
> >> {
> >> #ifdef CONFIG_ARM64_4K_PAGES
> >> - hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
> >> + hugetlb_add_hstate(ilog2(PUD_SIZE) - PAGE_SHIFT);
> >> #endif
> >> - hugetlb_add_hstate(CONT_PMD_SHIFT - PAGE_SHIFT);
> >> - hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
> >> - hugetlb_add_hstate(CONT_PTE_SHIFT - PAGE_SHIFT);
> >> + hugetlb_add_hstate(ilog2(CONT_PMD_SIZE) - PAGE_SHIFT);
> >> + hugetlb_add_hstate(ilog2(PMD_SIZE) - PAGE_SHIFT);
> >> + hugetlb_add_hstate(ilog2(CONT_PTE_SIZE) - PAGE_SHIFT);
> >>
> >> return 0;
> >> }
> >
> > I build this for an arm64 kernel and ran it in qemu and it worked.
>
> Thanks for testing Anders!
>
> Will, here is an updated version of the patch based on your suggestion.
> I added the () for emphasis but that may just be noise for some. Also,
> the naming differences and values for CONT_PTE may make some people
> look twice. Not sure if being consistent here helps?
>
> I have only built this. No testing.
>
> From daf833ab6b806ecc0816d84d45dcbacc052a7eec Mon Sep 17 00:00:00 2001
> From: Mike Kravetz <mike.kravetz@oracle.com>
> Date: Mon, 20 Apr 2020 13:56:15 -0700
> Subject: [PATCH] arm64/hugetlb: fix hugetlb initialization
>
> When calling hugetlb_add_hstate() to initialize a new hugetlb size,
> be sure to use correct huge pages size order.
>
> Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
Tested-by: Anders Roxell <anders.roxell@linaro.org>
I tested this patch on qemu-aarch64.
Cheers,
Anders
> ---
> arch/arm64/mm/hugetlbpage.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 9ca840527296..bed6dc7c4276 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -455,9 +455,9 @@ static int __init hugetlbpage_init(void)
> #ifdef CONFIG_ARM64_4K_PAGES
> hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
> #endif
> - hugetlb_add_hstate(CONT_PMD_SHIFT - PAGE_SHIFT);
> + hugetlb_add_hstate((CONT_PMD_SHIFT + PMD_SHIFT) - PAGE_SHIFT);
> hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
> - hugetlb_add_hstate(CONT_PTE_SHIFT - PAGE_SHIFT);
> + hugetlb_add_hstate((CONT_PTE_SHIFT + PAGE_SHIFT) - PAGE_SHIFT);
>
> return 0;
> }
> --
> 2.25.2
>
^ permalink raw reply
* Re: [PATCH v5 0/5] Track and expose idle PURR and SPURR ticks
From: Tyrel Datwyler @ 2020-04-20 22:46 UTC (permalink / raw)
To: Gautham R. Shenoy, Nathan Lynch, Michael Ellerman,
Vaidyanathan Srinivasan, Kamalesh Babulal, Naveen N. Rao
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1586249263-14048-1-git-send-email-ego@linux.vnet.ibm.com>
On 4/7/20 1:47 AM, Gautham R. Shenoy wrote:
> From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
>
> Hi,
>
> This is the fifth version of the patches to track and expose idle PURR
> and SPURR ticks. These patches are required by tools such as lparstat
> to compute system utilization for capacity planning purposes.
>
> The previous versions can be found here:
> v4: https://lkml.org/lkml/2020/3/27/323
> v3: https://lkml.org/lkml/2020/3/11/331
> v2: https://lkml.org/lkml/2020/2/21/21
> v1: https://lore.kernel.org/patchwork/cover/1159341/
>
> They changes from v4 are:
>
> - As suggested by Naveen, moved the functions read_this_idle_purr()
> and read_this_idle_spurr() from Patch 2 and Patch 3 respectively
> to Patch 4 where it is invoked.
>
> - Dropped Patch 6 which cached the values of purr, spurr,
> idle_purr, idle_spurr in order to minimize the number of IPIs
> sent.
>
> - Updated the dates for the idle_purr, idle_spurr in the
> Documentation Patch 5.
>
> Motivation:
> ===========
> On PSeries LPARs, the data centers planners desire a more accurate
> view of system utilization per resource such as CPU to plan the system
> capacity requirements better. Such accuracy can be obtained by reading
> PURR/SPURR registers for CPU resource utilization.
>
> Tools such as lparstat which are used to compute the utilization need
> to know [S]PURR ticks when the cpu was busy or idle. The [S]PURR
> counters are already exposed through sysfs. We already account for
> PURR ticks when we go to idle so that we can update the VPA area. This
> patchset extends support to account for SPURR ticks when idle, and
> expose both via per-cpu sysfs files.
>
> These patches are required for enhancement to the lparstat utility
> that compute the CPU utilization based on PURR and SPURR which can be
> found here :
> https://groups.google.com/forum/#!topic/powerpc-utils-devel/fYRo69xO9r4
>
>
> With the patches, when lparstat is run on a LPAR running CPU-Hogs,
> =========================================================================
> sudo ./src/lparstat -E 1 3
>
> System Configuration
> type=Dedicated mode=Capped smt=8 lcpu=2 mem=4834112 kB cpus=0 ent=2.00
>
> ---Actual--- -Normalized-
> %busy %idle Frequency %busy %idle
> ------ ------ ------------- ------ ------
> 1 99.99 0.00 3.35GHz[111%] 110.99 0.00
> 2 100.00 0.00 3.35GHz[111%] 111.01 0.00
> 3 100.00 0.00 3.35GHz[111%] 111.00 0.00
>
> With patches, when lparstat is run on and idle LPAR
> =========================================================================
> System Configuration
> type=Dedicated mode=Capped smt=8 lcpu=2 mem=4834112 kB cpus=0 ent=2.00
> ---Actual--- -Normalized-
> %busy %idle Frequency %busy %idle
> ------ ------ ------------- ------ ------
> 1 0.15 99.84 2.17GHz[ 72%] 0.11 71.89
> 2 0.24 99.76 2.11GHz[ 70%] 0.18 69.82
> 3 0.24 99.75 2.11GHz[ 70%] 0.18 69.81
>
> Gautham R. Shenoy (5):
> powerpc: Move idle_loop_prolog()/epilog() functions to header file
> powerpc/idle: Store PURR snapshot in a per-cpu global variable
> powerpc/pseries: Account for SPURR ticks on idle CPUs
> powerpc/sysfs: Show idle_purr and idle_spurr for every CPU
> Documentation: Document sysfs interfaces purr, spurr, idle_purr,
> idle_spurr
>
> Documentation/ABI/testing/sysfs-devices-system-cpu | 39 +++++++++
> arch/powerpc/include/asm/idle.h | 93 ++++++++++++++++++++++
> arch/powerpc/kernel/sysfs.c | 82 ++++++++++++++++++-
> arch/powerpc/platforms/pseries/setup.c | 8 +-
> drivers/cpuidle/cpuidle-pseries.c | 39 ++-------
> 5 files changed, 224 insertions(+), 37 deletions(-)
> create mode 100644 arch/powerpc/include/asm/idle.h
>
Reviewed-by: Tyrel Datwyler <tyreld@linux.ibm.com>
Any chance this is going to be merged in the near future? There is a patchset to
update lparstat in the powerpc-utils package to calculate PURR/SPURR cpu
utilization that I would like to merge, but have been holding off to make sure
we are synced with this proposed patchset.
^ permalink raw reply
* [PATCH v2 2/2] PCI/DPC: Allow Native DPC Host Bridges to use DPC
From: Jon Derrick @ 2020-04-20 21:37 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Kuppuswamy Sathyanarayanan, Rajat Jain, Rafael J. Wysocki,
Frederick Lawler, Sam Bobroff, linux-pci, Olof Johansson,
linuxppc-dev, linux-kernel, Bjorn Helgaas, Alex Williamson,
Patel, Mayurkumar, Oliver O'Halloran, Keith Busch,
Andy Shevchenko, Mika Westerberg, Jon Derrick
In-Reply-To: <1587418630-13562-1-git-send-email-jonathan.derrick@intel.com>
The existing portdrv model prevents DPC services without either OS
control (_OSC) granted to AER services, a Host Bridge requesting Native
AER, or using one of the 'pcie_ports=' parameters of 'native' or
'dpc-native'.
The DPC port service driver itself will also fail to probe if the kernel
assumes the port is using Firmware-First AER. It's a reasonable
expectation that a port using Firmware-First AER will also be using
Firmware-First DPC, however if a Host Bridge requests Native DPC, the
DPC driver should allow it and not fail to bind due to AER capability
settings.
Host Bridges which request Native DPC port services will also likely
request Native AER, however it shouldn't be a requirement. This patch
allows ports on those Host Bridges to have DPC port services.
This will avoid the unlikely situation where the port is Firmware-First
AER and Native DPC, and a BIOS or switch firmware preconfiguration of
the DPC trigger could result in unhandled DPC events.
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
---
drivers/pci/pcie/dpc.c | 3 ++-
drivers/pci/pcie/portdrv_core.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 7621704..3f3106f 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -284,7 +284,8 @@ static int dpc_probe(struct pcie_device *dev)
int status;
u16 ctl, cap;
- if (pcie_aer_get_firmware_first(pdev) && !pcie_ports_dpc_native)
+ if (pcie_aer_get_firmware_first(pdev) && !pcie_ports_dpc_native &&
+ !pci_find_host_bridge(pdev->bus)->native_dpc)
return -ENOTSUPP;
status = devm_request_threaded_irq(device, dev->irq, dpc_irq,
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 50a9522..f2139a1 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -256,7 +256,8 @@ static int get_port_device_capability(struct pci_dev *dev)
*/
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC) &&
pci_aer_available() &&
- (pcie_ports_dpc_native || (services & PCIE_PORT_SERVICE_AER)))
+ (pcie_ports_dpc_native || host->native_dpc ||
+ (services & PCIE_PORT_SERVICE_AER)))
services |= PCIE_PORT_SERVICE_DPC;
if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM ||
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 1/2] PCI/AER: Allow Native AER Host Bridges to use AER
From: Jon Derrick @ 2020-04-20 21:37 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Kuppuswamy Sathyanarayanan, Rajat Jain, Rafael J. Wysocki,
Frederick Lawler, Sam Bobroff, linux-pci, Olof Johansson,
linuxppc-dev, linux-kernel, Bjorn Helgaas, Alex Williamson,
Patel, Mayurkumar, Oliver O'Halloran, Keith Busch,
Andy Shevchenko, Mika Westerberg, Jon Derrick
In-Reply-To: <1587418630-13562-1-git-send-email-jonathan.derrick@intel.com>
Some platforms have a mix of ports whose capabilities can be negotiated
by _OSC, and some ports which are not described by ACPI and instead
managed by Native drivers. The existing Firmware-First HEST model can
incorrectly tag these Native, Non-ACPI ports as Firmware-First managed
ports by advertising the HEST Global Flag and matching the type and
class of the port (aer_hest_parse).
If the port requests Native AER through the Host Bridge's capability
settings, the AER driver should honor those settings and allow the port
to bind. This patch changes the definition of Firmware-First to exclude
ports whose Host Bridges request Native AER.
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
---
drivers/pci/pcie/aer.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index f4274d3..30fbd1f 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -314,6 +314,9 @@ int pcie_aer_get_firmware_first(struct pci_dev *dev)
if (pcie_ports_native)
return 0;
+ if (pci_find_host_bridge(dev->bus)->native_aer)
+ return 0;
+
if (!dev->__aer_firmware_first_valid)
aer_set_firmware_first(dev);
return dev->__aer_firmware_first;
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 0/2] Honoring Native AER/DPC Host Bridges
From: Jon Derrick @ 2020-04-20 21:37 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Kuppuswamy Sathyanarayanan, Rajat Jain, Rafael J. Wysocki,
Frederick Lawler, Sam Bobroff, linux-pci, Olof Johansson,
linuxppc-dev, linux-kernel, Bjorn Helgaas, Alex Williamson,
Patel, Mayurkumar, Oliver O'Halloran, Keith Busch,
Andy Shevchenko, Mika Westerberg, Jon Derrick
The two patches here force AER and DPC to honor the Host Bridge's Native
AER/DPC settings. This is under the assumption that when these bits are set,
that Firmware-First AER/DPC should not be in use for these ports. This
assumption seems to be true in ACPI, which explicitly clears these capability
settings in the host bridge if the service cannot be negotiated with _OSC.
This also fixes an issue I've seen in a few platforms whose BIOS and/or switch
firmware leaves DPC preconfigured. In these cases, the kernel DPC driver cannot
bind a handler to the interrupt and could result in unmanaged DPC link down
events.
Jon Derrick (2):
PCI/AER: Allow Native AER Host Bridges to use AER
PCI/DPC: Allow Native DPC Host Bridges to use DPC
drivers/pci/pcie/aer.c | 3 +++
drivers/pci/pcie/dpc.c | 3 ++-
drivers/pci/pcie/portdrv_core.c | 3 ++-
3 files changed, 7 insertions(+), 2 deletions(-)
--
1.8.3.1
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox