LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] powerpc/Makefile: Add ppc32/ppc64_randconfig targets
From: Michael Ellerman @ 2021-04-28 13:27 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: masahiroy, rdunlap

Make it easier to generate a 32 or 64-bit specific randconfig.

Requested-by: Randy Dunlap <rdunlap@infradead.org>
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/Makefile              | 10 ++++++++++
 arch/powerpc/configs/32-bit.config |  1 +
 arch/powerpc/configs/64-bit.config |  1 +
 3 files changed, 12 insertions(+)
 create mode 100644 arch/powerpc/configs/32-bit.config
 create mode 100644 arch/powerpc/configs/64-bit.config

diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 3212d076ac6a..712c5e8768ce 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -376,6 +376,16 @@ PHONY += ppc64_book3e_allmodconfig
 	$(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/85xx-64bit.config \
 		-f $(srctree)/Makefile allmodconfig
 
+PHONY += ppc32_randconfig
+ppc32_randconfig:
+	$(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/32-bit.config \
+		-f $(srctree)/Makefile randconfig
+
+PHONY += ppc64_randconfig
+ppc64_randconfig:
+	$(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/64-bit.config \
+		-f $(srctree)/Makefile randconfig
+
 define archhelp
   @echo '* zImage          - Build default images selected by kernel config'
   @echo '  zImage.*        - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)'
diff --git a/arch/powerpc/configs/32-bit.config b/arch/powerpc/configs/32-bit.config
new file mode 100644
index 000000000000..ad6546850c68
--- /dev/null
+++ b/arch/powerpc/configs/32-bit.config
@@ -0,0 +1 @@
+# CONFIG_PPC64 is not set
diff --git a/arch/powerpc/configs/64-bit.config b/arch/powerpc/configs/64-bit.config
new file mode 100644
index 000000000000..0fe6406929e2
--- /dev/null
+++ b/arch/powerpc/configs/64-bit.config
@@ -0,0 +1 @@
+CONFIG_PPC64=y
-- 
2.25.1


^ permalink raw reply related

* Re: PPC476 hangs during tlb flush after calling /init in crash kernel with linux 5.4+
From: Eddie James @ 2021-04-28 13:56 UTC (permalink / raw)
  To: Christophe Leroy, linuxppc-dev; +Cc: miltonm, linux-kernel, npiggin, paulus
In-Reply-To: <711a9a60-264b-9b86-6772-6585622a5bd4@csgroup.eu>

On Wed, 2021-04-28 at 08:08 +0200, Christophe Leroy wrote:
> 
> Le 28/04/2021 à 00:42, Eddie James a écrit :
> > On Tue, 2021-04-27 at 19:26 +0200, Christophe Leroy wrote:
> > > Hi Eddies,
> > > 
> > > Le 27/04/2021 à 19:03, Eddie James a écrit :
> > > > Hi all,
> > > > 
> > > > I'm having a problem in simulation and hardware where my PPC476
> > > > processor stops executing instructions after callling /init. In
> > > > my
> > > > case
> > > > this is a bash script. The code descends to flush the TLB, and
> > > > somewhere in the loop in _tlbil_pid, the PC goes to
> > > > InstructionTLBError47x but does not go any further. This only
> > > > occurs in
> > > > the crash kernel environment, which is using the same kernel,
> > > > initramfs, and init script as the main kernel, which executed
> > > > fine.
> > > > I
> > > > do not see this problem with linux 4.19 or 3.10. I do see it
> > > > with
> > > > 5.4
> > > > and 5.10. I see a fair amount of refactoring in the PPC memory
> > > > management area between 4.19 and 5.4. Can anyone point me in a
> > > > direction to debug this further? My stack trace is below as I
> > > > can
> > > > run
> > > > gdb in simulation.
> > > 
> > > Can you bisect to pin point the culprit commit ?
> > 
> > Hi, thanks for your prompt reply.
> > 
> > Good idea! I have bisected to:
> > 
> > commit 9e849f231c3c72d4c3c1b07c9cd19ae789da0420 (b8-bad,
> > refs/bisect/bad)
> > Author: Christophe Leroy <christophe.leroy@c-s.fr>
> > Date:   Thu Feb 21 19:08:40 2019 +0000
> > 
> >      powerpc/mm/32s: use generic mmu_mapin_ram() for all blocks.
> >      
> >      Now that mmu_mapin_ram() is able to handle other blocks
> >      than the one starting at 0, the WII can use it for all
> >      its blocks.
> >      
> >      Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> >      Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> > 
> > I also confirmed that reverting this commit resolves the issue in
> > 5.4+.
> > 
> > Now, I don't understand why this is problematic or what is really
> > happening... Reverting is probably not the desired solution.
> > 
> 
> Can you provide the 'dmesg' or a dump of the logs printed by the
> kernel at boottime ?

Yes:

[    0.000000] Linux version 5.4.85-a19ab63.ppcnf-fsp2 (oe-user@oe-host
) (gcc ve
rsion 8.3.0 (GCC)) #1 Tue Mar 30 15:32:31 UTC 2021
[    0.000000] Found initrd at 0xcf6a7000:0xcfffb09f
[    0.000000] Using FSP-2 machine description
[    0.000000] Found legacy serial port 0 for /plb4/opb/serial@b0020000
[    0.000000]   mem=10b0020000, taddr=10b0020000, irq=0, clk=20833333,
speed=11
5200
[    0.000000] -----------------------------------------------------
[    0.000000] phys_mem_size     = 0x4000000
[    0.000000] dcache_bsize      = 0x80
[    0.000000] icache_bsize      = 0x20
[    0.000000] cpu_features      = 0x0000000040800120
[    0.000000]   possible        = 0x0000000040800120
[    0.000000]   always          = 0x0000000000000020
[    0.000000] cpu_user_features = 0x8c008000 0x00000000
[    0.000000] mmu_features      = 0x00140020
[    0.000000] physical_start    = 0xc000000
[    0.000000] -----------------------------------------------------
[    0.000000] Top of RAM: 0x10000000, Total RAM: 0x4000000
[    0.000000] Memory hole size: 192MB
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x000000000c000000-0x000000000fffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x000000000c000000-0x000000000fffffff]
[    0.000000] Initmem setup node 0 [mem 0x000000000c000000-
0x000000000fffffff]
[    0.000000] On node 0 totalpages: 16384
[    0.000000]   Normal zone: 160 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 16384 pages, LIFO batch:3
[    0.000000] MMU: Allocated 278528 bytes of context maps for 65535
contexts
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages:
16224
[    0.000000] Kernel command line: console=ttyS0,115200 loglevel=9
rootwait roo
t=/dev/mmcblk0p2 elfcorehdr=209456K maxcpus=1
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768
bytes, lin
ear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384
bytes, line
ar)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 42028K/65536K available (7136K kernel code, 620K
rwdata, 
1916K rodata, 2080K init, 233K bss, 23508K reserved, 0K cma-reserved)
[    0.000000] Kernel virtual memory layout:
[    0.000000]   * 0xfffdf000..0xfffff000  : fixmap
[    0.000000]   * 0xd1000000..0xfffdf000  : vmalloc & ioremap
[    0.000000] SLUB: HWalign=128, Order=0-3, MinObjects=0, CPUs=1,
Nodes=1
[    0.000000] NR_IRQS: 512, nr_irqs: 512, preallocated irqs: 16
[    0.000000] UIC0 (32 IRQ sources) at DCR 0x2c0
[    0.000000] UIC1 (32 IRQ sources) at DCR 0x2c8
[    0.000000] UIC2 (32 IRQ sources) at DCR 0x350
[    0.000000] UIC3 (32 IRQ sources) at DCR 0x358
[    0.000000] UIC4 (32 IRQ sources) at DCR 0x360
[    0.000000] UIC5 (32 IRQ sources) at DCR 0x368
[    0.000000] UIC6 (32 IRQ sources) at DCR 0x370
[    0.000000] UIC7 (32 IRQ sources) at DCR 0x2d0
[    0.000000] UIC8 (32 IRQ sources) at DCR 0x2d8
[    0.000000] UIC17 (32 IRQ sources) at DCR 0x320
[    0.000000] UIC18 (32 IRQ sources) at DCR 0x328
[    0.000000] UIC19 (32 IRQ sources) at DCR 0x330
[    0.000000] UIC20 (32 IRQ sources) at DCR 0x338
[    0.000000] UIC21 (32 IRQ sources) at DCR 0x340
[    0.000000] UIC22 (32 IRQ sources) at DCR 0x348
[    0.000000] UIC9 (32 IRQ sources) at DCR 0x2e0
[    0.000000] UIC10 (32 IRQ sources) at DCR 0x2e8
[    0.000000] UIC11 (32 IRQ sources) at DCR 0x2f0
[    0.000000] UIC12 (32 IRQ sources) at DCR 0x2f8
[    0.000000] UIC13 (32 IRQ sources) at DCR 0x300
[    0.000000] UIC14 (32 IRQ sources) at DCR 0x308
[    0.000000] UIC15 (32 IRQ sources) at DCR 0x310
[    0.000000] UIC16 (32 IRQ sources) at DCR 0x318
[    0.000000] random: get_random_u32 called from
start_kernel+0x32c/0x500 with 
crng_init=0
[    0.000000] time_init: decrementer frequency = 166.666667 MHz
[    0.000000] time_init: processor frequency   = 1333.333333 MHz
[    0.000004] clocksource: timebase: mask: 0xffffffffffffffff
max_cycles: 0x267
03d839d, max_idle_ns: 440795207088 ns
[    0.000007] clocksource: timebase mult[6000000] shift[24] registered
[    0.000011] clockevent: decrementer mult[2aaaaaac] shift[32] cpu[0]
[    0.000071] pid_max: default: 32768 minimum: 301
[    0.000107] Mount-cache hash table entries: 1024 (order: 0, 4096
bytes, linea
r)
[    0.000111] Mountpoint-cache hash table entries: 1024 (order: 0,
4096 bytes, 
linear)
[    0.000580] devtmpfs: initialized
[    0.002029] clocksource: jiffies: mask: 0xffffffff max_cycles:
0xffffffff, ma
x_idle_ns: 7645041785100000 ns
[    0.002034] futex hash table entries: 256 (order: -1, 3072 bytes,
linear)
[    0.002146] NET: Registered protocol family 16
[    0.004958] SCSI subsystem initialized
[    0.004973] libata version 3.00 loaded.
[    0.005003] usbcore: registered new interface driver usbfs
[    0.005019] usbcore: registered new interface driver hub
[    0.005031] usbcore: registered new device driver usb
[    0.005043] pps_core: LinuxPPS API ver. 1 registered
[    0.005045] pps_core: Software ver. 5.3.6 - Copyright 2005-2007
Rodolfo Giome
tti <giometti@linux.it>
[    0.005052] PTP clock support registered
[    0.005257] clocksource: Switched to clocksource timebase
[    0.311619] thermal_sys: Registered thermal governor 'step_wise'
[    0.311665] NET: Registered protocol family 2
[    0.311834] tcp_listen_portaddr_hash hash table entries: 512 (order:
0, 4096 
bytes, linear)
[    0.311844] TCP established hash table entries: 1024 (order: 0, 4096
bytes, l
inear)
[    0.311855] TCP bind hash table entries: 1024 (order: 0, 4096 bytes,
linear)
[    0.311864] TCP: Hash tables configured (established 1024 bind 1024)
[    0.311877] UDP hash table entries: 256 (order: 0, 4096 bytes,
linear)
[    0.311885] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes,
linear)
[    0.311918] NET: Registered protocol family 1
[    0.311994] RPC: Registered named UNIX socket transport module.
[    0.311996] RPC: Registered udp transport module.
[    0.311999] RPC: Registered tcp transport module.
[    0.312001] RPC: Registered tcp NFSv4.1 backchannel transport
module.
[    0.312043] Trying to unpack rootfs image as initramfs...
[    0.632637] Freeing initrd memory: 9552K
[    0.634361] shadow_disr_to_uic15: 0x00000020 to uic15_pr
[    0.635621] workingset: timestamp_bits=30 max_order=14
bucket_order=0
[    0.638710] NFS: Registering the id_resolver key type
[    0.638717] Key type id_resolver registered
[    0.638720] Key type id_legacy registered
[    0.638730] jffs2: version 2.2. (NAND) (SUMMARY)  © 2001-2006 Red
Hat, Inc.
[    0.638858] fuse: init (API version 7.31)
[    0.664372] io scheduler mq-deadline registered
[    0.664375] io scheduler kyber registered
[    0.664573] Serial: 8250/16550 driver, 32 ports, IRQ sharing enabled
[    0.665728] printk: console [ttyS0] disabled
[    0.685664] serial8250.0: ttyS0 at MMIO 0x10b0020000 (irq = 47,
base_baud = 1
302083) is a 16550A
[    0.693859] printk: console [ttyS0] enabled
[    0.694150] printk: console [ttyS0] disabled
[    0.694212] 10b0020000.serial: ttyS0 at MMIO 0x10b0020000 (irq = 47,
base_bau
d = 1302083) is a 16550
[    0.702632] printk: console [ttyS0] enabled
[    0.704642] brd: module loaded
[    0.704730] slram: not enough parameters.
[    0.704792] PPP generic driver version 2.4.2
[    0.704875] PPP Deflate Compression module registered
[    0.704941] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI)
Driver
[    0.705052] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    0.705148] usbcore: registered new interface driver usb-storage
[    0.705248] usbcore: registered new interface driver
usbserial_generic
[    0.705341] usbserial: USB Serial support registered for generic
[    0.705428] usbcore: registered new interface driver pl2303
[    0.705508] usbserial: USB Serial support registered for pl2303
[    0.705592] booke_wdt: powerpc book-e watchdog driver loaded
[    0.705769] sdhci: Secure Digital Host Controller Interface driver
[    0.705849] sdhci: Copyright(c) Pierre Ossman
[    0.705906] sdhci-pltfm: SDHCI platform and OF driver helper
[    0.706033] mmc0: Invalid maximum block size, assuming 512 bytes
[    0.706112] mmc0 bounce up to 128 segments into one, max segment
size 65536 b
ytes
[    0.731266] mmc0: SDHCI controller on 10020c0000.emmc
[10020c0000.emmc] using
 DMA
[    0.731422] oprofile: using timer interrupt.
[    0.731546] Initializing XFRM netlink socket
[    0.731789] NET: Registered protocol family 10
[    0.732013] Segment Routing with IPv6
[    0.732096] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    0.732331] NET: Registered protocol family 17
[    0.732414] sctp: Hash tables configured (bind 1024/1024)
[    0.732591] Key type dns_resolver registered
[    0.732698] drmem: No dynamic reconfiguration memory found
[    0.732888] hctosys: unable to open rtc device (rtc0)
[    0.734057] Freeing unused kernel memory: 2080K
[    0.734116] This architecture does not have kernel memory
protection.
[    0.734199] Run /init as init process

> 
> The difference with this commit is that if there are several
> memblocks, all get mapped. Maybe your 
> target doesn't like it.
> 
> You are talking about simulation, are you using QEMU ? If yes can you
> provide details so that I can 
> try and reproduce the issue ?

No, we use Windriver simics for this system. I'm not sure if QEMU has a
model for the PPC476... and I suspect it won't recreate with a more
generic 32 bit ppc machine, though I can try and find out.

Thanks,
Eddie

> 
> Thanks
> Christophe


^ permalink raw reply

* Re: PPC476 hangs during tlb flush after calling /init in crash kernel with linux 5.4+
From: Eddie James @ 2021-04-28 14:18 UTC (permalink / raw)
  To: Christophe Leroy, linuxppc-dev; +Cc: miltonm, linux-kernel, npiggin, paulus
In-Reply-To: <711a9a60-264b-9b86-6772-6585622a5bd4@csgroup.eu>

On Wed, 2021-04-28 at 08:08 +0200, Christophe Leroy wrote:
> 
> Le 28/04/2021 à 00:42, Eddie James a écrit :
> > On Tue, 2021-04-27 at 19:26 +0200, Christophe Leroy wrote:
> > > Hi Eddies,
> > > 
> > > Le 27/04/2021 à 19:03, Eddie James a écrit :
> > > > Hi all,
> > > > 
> > > > I'm having a problem in simulation and hardware where my PPC476
> > > > processor stops executing instructions after callling /init. In
> > > > my
> > > > case
> > > > this is a bash script. The code descends to flush the TLB, and
> > > > somewhere in the loop in _tlbil_pid, the PC goes to
> > > > InstructionTLBError47x but does not go any further. This only
> > > > occurs in
> > > > the crash kernel environment, which is using the same kernel,
> > > > initramfs, and init script as the main kernel, which executed
> > > > fine.
> > > > I
> > > > do not see this problem with linux 4.19 or 3.10. I do see it
> > > > with
> > > > 5.4
> > > > and 5.10. I see a fair amount of refactoring in the PPC memory
> > > > management area between 4.19 and 5.4. Can anyone point me in a
> > > > direction to debug this further? My stack trace is below as I
> > > > can
> > > > run
> > > > gdb in simulation.
> > > 
> > > Can you bisect to pin point the culprit commit ?
> > 
> > Hi, thanks for your prompt reply.
> > 
> > Good idea! I have bisected to:
> > 
> > commit 9e849f231c3c72d4c3c1b07c9cd19ae789da0420 (b8-bad,
> > refs/bisect/bad)
> > Author: Christophe Leroy <christophe.leroy@c-s.fr>
> > Date:   Thu Feb 21 19:08:40 2019 +0000
> > 
> >      powerpc/mm/32s: use generic mmu_mapin_ram() for all blocks.
> >      
> >      Now that mmu_mapin_ram() is able to handle other blocks
> >      than the one starting at 0, the WII can use it for all
> >      its blocks.
> >      
> >      Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> >      Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> > 
> > I also confirmed that reverting this commit resolves the issue in
> > 5.4+.
> > 
> > Now, I don't understand why this is problematic or what is really
> > happening... Reverting is probably not the desired solution.
> > 
> 
> Can you provide the 'dmesg' or a dump of the logs printed by the
> kernel at boottime ?
> 
> The difference with this commit is that if there are several
> memblocks, all get mapped. Maybe your 
> target doesn't like it.
> 
> You are talking about simulation, are you using QEMU ? If yes can you
> provide details so that I can 
> try and reproduce the issue ?

Milton mentioned the kexec debug output might be useful:

lzma_decompress_file: read on uImage of 65536 
bytes failed
kernel: 0xb75b3010 kernel_size: 0x4f1231
0000000000000000-0000000040000000 : 0
get base memory ranges:1
usable memory rgns size:1 base:0 size:10000000
exclude_range sorted exclude_range[0] start:0, end:bb7000
setup_memory_ranges memory_range[0] start:bb7001, end:30000000
CRASH MEMORY RANGES
0000000000000000-0000000000010000
0000000000010000-000000000c000000
0000000010000000-000000002d600000
get_crash_notes_per_cpu: crash_notes addr = 2ce84e00, size = 300
Elf header: p_type = 4, p_offset = 0x2ce84e00 p_paddr = 0x2ce84e00
p_vaddr = 0x0
 p_filesz = 0x12c p_memsz = 0x12c
vmcoreinfo header: p_type = 4, p_offset = 0x2c8d4000 p_paddr =
0x2c8d4000 p_vadd
r = 0x0 p_filesz = 0x1024 p_memsz = 0x1024
Elf header: p_type = 1, p_offset = 0xcc7e000 p_paddr = 0x0 p_vaddr =
0xc0000000 
p_filesz = 0x10000 p_memsz = 0x10000
Elf header: p_type = 1, p_offset = 0x10000 p_paddr = 0x10000 p_vaddr =
0xc001000
0 p_filesz = 0xbff0000 p_memsz = 0xbff0000
Elf header: p_type = 1, p_offset = 0x10000000 p_paddr = 0x10000000
p_vaddr = 0xd
0000000 p_filesz = 0x1d600000 p_memsz = 0x1d600000
Command line after adding elfcorehdr:  elfcorehdr=209464K
sym:      .data info: 03 other: 00 shndx: 7 value: 0 size: 0
sym: .data value: ffffbf0 addr: fffc032
sym:      .data info: 03 other: 00 shndx: 7 value: 0 size: 0
sym: .data value: ffffbf0 addr: fffc03a
sym: sha256_starts info: 12 other: 00 shndx: 2 value: 92c size: 70
sym: sha256_starts value: fffc950 addr: fffc044
sym: sha256_update info: 12 other: 00 shndx: 2 value: 36c4 size: c
sym: sha256_update value: ffff6e8 addr: fffc058
sym: sha256_finish info: 12 other: 00 shndx: 2 value: 36d0 size: 1a4
sym: sha256_finish value: ffff6f4 addr: fffc070
sym:     memcmp info: 12 other: 00 shndx: 2 value: 5fc size: 38
sym: memcmp value: fffc620 addr: fffc080
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff898 addr: fffc08e
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8c8 addr: fffc092
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff898 addr: fffc096
sym:     printf info: 12 other: 00 shndx: 2 value: 524 size: 68
sym: printf value: fffc548 addr: fffc09c
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8b8 addr: fffc0a2
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8b8 addr: fffc0a6
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8c8 addr: fffc0aa
sym:     printf info: 12 other: 00 shndx: 2 value: 524 size: 68
sym: printf value: fffc548 addr: fffc0ac
sym:     printf info: 12 other: 00 shndx: 2 value: 524 size: 68
sym: printf value: fffc548 addr: fffc0b8
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8ce addr: fffc0ca
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8ce addr: fffc0d2
sym:     printf info: 12 other: 00 shndx: 2 value: 524 size: 68
sym: printf value: fffc548 addr: fffc0d8
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8d0 addr: fffc0de
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8d0 addr: fffc0e2
sym:     printf info: 12 other: 00 shndx: 2 value: 524 size: 68
sym: printf value: fffc548 addr: fffc0e4
sym:     printf info: 12 other: 00 shndx: 2 value: 524 size: 68
sym: printf value: fffc548 addr: fffc0f0
sym:     printf info: 12 other: 00 shndx: 2 value: 524 size: 68
sym: printf value: fffc548 addr: fffc104
sym: _restgpr_28_x info: 12 other: 00 shndx: 2 value: 888 size: 0
sym: _restgpr_28_x value: fffc8ac addr: fffc110
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8e0 addr: fffc11a
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8e0 addr: fffc122
sym:     printf info: 12 other: 00 shndx: 2 value: 524 size: 68
sym: printf value: fffc548 addr: fffc128
sym: setup_arch info: 12 other: 00 shndx: 2 value: 91c size: 4
sym: setup_arch value: fffc940 addr: fffc12c
sym: skip_checks info: 11 other: 00 shndx: 8 value: 0 size: 4
sym: skip_checks value: ffffd50 addr: fffc132
sym: skip_checks info: 11 other: 00 shndx: 8 value: 0 size: 4
sym: skip_checks value: ffffd50 addr: fffc136
sym: verify_sha256_digest info: 12 other: 00 shndx: 2 value: 0 size: f0
sym: verify_sha256_digest value: fffc024 addr: fffc140
sym: post_verification_setup_arch info: 12 other: 00 shndx: 2 value:
920 size: 4
sym: post_verification_setup_arch value: fffc944 addr: fffc15c
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8f2 addr: fffc16e
sym: .rodata.str1.1 info: 03 other: 00 shndx: 4 value: 0 size: 0
sym: .rodata.str1.1 value: ffff8f2 addr: fffc18a
sym: _restgpr_20_x info: 12 other: 00 shndx: 2 value: 868 size: 0
sym: _restgpr_20_x value: fffc88c addr: fffc1a8
sym:    putchar info: 12 other: 00 shndx: 2 value: 928 size: 4
sym: putchar value: fffc94c addr: fffc1cc
sym:    putchar info: 12 other: 00 shndx: 2 value: 928 size: 4
sym: putchar value: fffc94c addr: fffc244
sym:  __lshrdi3 info: 10 other: 00 shndx: 2 value: 8f8 size: 0
sym: __lshrdi3 value: fffc91c addr: fffc2c4
sym:    putchar info: 12 other: 00 shndx: 2 value: 928 size: 4
sym: putchar value: fffc94c addr: fffc4e4
sym:   vsprintf info: 12 other: 00 shndx: 2 value: 13c size: 38c
sym: vsprintf value: fffc160 addr: fffc534
sym:   vsprintf info: 12 other: 00 shndx: 2 value: 13c size: 38c
sym: vsprintf value: fffc160 addr: fffc59c
sym: my_thread_ptr info: 11 other: 00 shndx: 8 value: 8 size: 4
sym: my_thread_ptr value: ffffd58 addr: fffc76a
sym: my_thread_ptr info: 11 other: 00 shndx: 8 value: 8 size: 4
sym: my_thread_ptr value: ffffd58 addr: fffc76e
sym:      stack info: 11 other: 00 shndx: 8 value: 10 size: 4
sym: stack value: ffffd60 addr: fffc776
sym:      stack info: 11 other: 00 shndx: 8 value: 10 size: 4
sym: stack value: ffffd60 addr: fffc77a
sym:  purgatory info: 12 other: 00 shndx: 2 value: f0 size: 4c
sym: purgatory value: fffc114 addr: fffc784
sym:  dt_offset info: 11 other: 00 shndx: 8 value: c size: 4
sym: dt_offset value: ffffd5c addr: fffc79e
sym:  dt_offset info: 11 other: 00 shndx: 8 value: c size: 4
sym: dt_offset value: ffffd5c addr: fffc7a2
sym:     kernel info: 11 other: 00 shndx: 8 value: 4 size: 4
sym: kernel value: ffffd54 addr: fffc7ba
sym:     kernel info: 11 other: 00 shndx: 8 value: 4 size: 4
sym: kernel value: ffffd54 addr: fffc7be
sym:     memcpy info: 12 other: 00 shndx: 2 value: 5d8 size: 24
sym: memcpy value: fffc5fc addr: ffff648
sym:     memcpy info: 12 other: 00 shndx: 2 value: 5d8 size: 24
sym: memcpy value: fffc5fc addr: ffff65c
sym: sha256_process info: 12 other: 00 shndx: 2 value: 99c size: 2be0
sym: sha256_process value: fffc9c0 addr: ffff66c
sym: sha256_process info: 12 other: 00 shndx: 2 value: 99c size: 2be0
sym: sha256_process value: fffc9c0 addr: ffff6a8
sym:      .data info: 03 other: 00 shndx: 7 value: 0 size: 0
sym: .data value: ffffd10 addr: ffff742
sym:      .data info: 03 other: 00 shndx: 7 value: 0 size: 0
sym: .data value: ffffd10 addr: ffff74a
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc024 addr: ffff920
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc114 addr: ffff94c
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc160 addr: ffff980
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc4ec addr: ffff9c8
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc548 addr: ffff9e8
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc5b0 addr: ffffa1c
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc5dc addr: ffffa30
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc5fc addr: ffffa44
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc620 addr: ffffa58
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc940 addr: ffffa80
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc944 addr: ffffa94
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc948 addr: ffffaa8
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc94c addr: ffffad0
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc950 addr: ffffaf8
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: fffc9c0 addr: ffffb0c
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: ffff5a0 addr: ffffb68
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: ffff6e8 addr: ffffbbc
sym:      .text info: 03 other: 00 shndx: 2 value: 0 size: 0
sym: .text value: ffff6f4 addr: ffffbd0
Modified cmdline:console=ttyS0,115200 loglevel=9 rootwait
root=/dev/mmcblk0p2 el
fcorehdr=209464K maxcpus=1 
reserve regions: 4
0: offset: e3fc000, size: 4000
1: offset: c000000, size: c8f000
2: offset: fffc000, size: 4000
3: offset: f6a7000, size: 955000
debug.dtb written
kexec_load: entry = 0xfffc658 flags = 0x1
nr_segments = 6
segment[0].buf   = 0xb5cb1010
segment[0].bufsz = 0xb7d568
segment[0].mem   = 0xc000000
segment[0].memsz = 0xc7e000
segment[1].buf   = 0x100997b0
segment[1].bufsz = 0x10000
segment[1].mem   = 0xcc7e000
segment[1].memsz = 0x10000
segment[2].buf   = 0x100a97f0
segment[2].bufsz = 0x400
segment[2].mem   = 0xcc8e000
segment[2].memsz = 0x1000
segment[3].buf   = 0x100ae670
segment[3].bufsz = 0x3c5f
segment[3].mem   = 0xe3fc000
segment[3].memsz = 0x4000
segment[4].buf   = 0xb6c5e050
segment[4].bufsz = 0x95409f
segment[4].mem   = 0xf6a7000
segment[4].memsz = 0x955000
segment[5].buf   = 0x100aa8a0
segment[5].bufsz = 0x3d6c
segment[5].mem   = 0xfffc000
segment[5].memsz = 0x4000

> 
> Thanks
> Christophe


^ permalink raw reply

* [RFC PATCH v1 1/4] mm/ioremap: Fix iomap_max_page_shift
From: Christophe Leroy @ 2021-04-28 16:46 UTC (permalink / raw)
  To: Andrew Morton, Nicholas Piggin, Mike Kravetz, Mike Rapoport
  Cc: linux-arch, linux-kernel, linux-mm, sparclinux, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <cover.1619628001.git.christophe.leroy@csgroup.eu>

iomap_max_page_shift is expected to contain a page shift,
so it can't be a 'bool', has to be an 'unsigned int'

And fix the default values: P4D_SHIFT is when huge iomap is allowed.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 mm/ioremap.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mm/ioremap.c b/mm/ioremap.c
index d1dcc7e744ac..2f7193c6a99e 100644
--- a/mm/ioremap.c
+++ b/mm/ioremap.c
@@ -16,16 +16,16 @@
 #include "pgalloc-track.h"
 
 #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
-static bool __ro_after_init iomap_max_page_shift = PAGE_SHIFT;
+static unsigned int __ro_after_init iomap_max_page_shift = P4D_SHIFT;
 
 static int __init set_nohugeiomap(char *str)
 {
-	iomap_max_page_shift = P4D_SHIFT;
+	iomap_max_page_shift = PAGE_SHIFT;
 	return 0;
 }
 early_param("nohugeiomap", set_nohugeiomap);
 #else /* CONFIG_HAVE_ARCH_HUGE_VMAP */
-static const bool iomap_max_page_shift = PAGE_SHIFT;
+static const unsigned int iomap_max_page_shift = PAGE_SHIFT;
 #endif	/* CONFIG_HAVE_ARCH_HUGE_VMAP */
 
 int ioremap_page_range(unsigned long addr,
-- 
2.25.0


^ permalink raw reply related

* [RFC PATCH v1 2/4] mm/hugetlb: Change parameters of arch_make_huge_pte()
From: Christophe Leroy @ 2021-04-28 16:46 UTC (permalink / raw)
  To: Andrew Morton, Nicholas Piggin, Mike Kravetz, Mike Rapoport
  Cc: linux-arch, linux-kernel, linux-mm, sparclinux, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <cover.1619628001.git.christophe.leroy@csgroup.eu>

At the time being, arch_make_huge_pte() has the following prototype:

	pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
				 struct page *page, int writable);

vma is used to get the pages shift or size.
vma is also used on Sparc to get vm_flags.
page is not used.
writable is not used.

In order to use this function without a vma, and replace vma by shift
and flags. Also remove the used parameters.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/arm64/include/asm/hugetlb.h                 | 3 +--
 arch/arm64/mm/hugetlbpage.c                      | 5 ++---
 arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 5 ++---
 arch/sparc/include/asm/pgtable_64.h              | 3 +--
 arch/sparc/mm/hugetlbpage.c                      | 6 ++----
 include/linux/hugetlb.h                          | 4 ++--
 mm/hugetlb.c                                     | 6 ++++--
 mm/migrate.c                                     | 4 +++-
 8 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h
index 5abf91e3494c..1242f71937f8 100644
--- a/arch/arm64/include/asm/hugetlb.h
+++ b/arch/arm64/include/asm/hugetlb.h
@@ -23,8 +23,7 @@ static inline void arch_clear_hugepage_flags(struct page *page)
 }
 #define arch_clear_hugepage_flags arch_clear_hugepage_flags
 
-extern pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
-				struct page *page, int writable);
+pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags);
 #define arch_make_huge_pte arch_make_huge_pte
 #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
 extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 58987a98e179..23505fc35324 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -339,10 +339,9 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
 	return NULL;
 }
 
-pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
-			 struct page *page, int writable)
+pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
 {
-	size_t pagesize = huge_page_size(hstate_vma(vma));
+	size_t pagesize = 1UL << shift;
 
 	if (pagesize == CONT_PTE_SIZE) {
 		entry = pte_mkcont(entry);
diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
index 39be9aea86db..64b6c608eca4 100644
--- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
@@ -66,10 +66,9 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 }
 
 #ifdef CONFIG_PPC_4K_PAGES
-static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
-				       struct page *page, int writable)
+static inline pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
 {
-	size_t size = huge_page_size(hstate_vma(vma));
+	size_t size = 1UL << shift;
 
 	if (size == SZ_16K)
 		return __pte(pte_val(entry) & ~_PAGE_HUGE);
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 550d3904de65..2cd80a0a9795 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -377,8 +377,7 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
 #define pgprot_noncached pgprot_noncached
 
 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
-extern pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
-				struct page *page, int writable);
+pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags);
 #define arch_make_huge_pte arch_make_huge_pte
 static inline unsigned long __pte_default_huge_mask(void)
 {
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index 04d8790f6c32..0f49fada2093 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -177,10 +177,8 @@ static pte_t hugepage_shift_to_tte(pte_t entry, unsigned int shift)
 		return sun4u_hugepage_shift_to_tte(entry, shift);
 }
 
-pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
-			 struct page *page, int writeable)
+pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
 {
-	unsigned int shift = huge_page_shift(hstate_vma(vma));
 	pte_t pte;
 
 	pte = hugepage_shift_to_tte(entry, shift);
@@ -188,7 +186,7 @@ pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
 #ifdef CONFIG_SPARC64
 	/* If this vma has ADI enabled on it, turn on TTE.mcd
 	 */
-	if (vma->vm_flags & VM_SPARC_ADI)
+	if (flags & VM_SPARC_ADI)
 		return pte_mkmcd(pte);
 	else
 		return pte_mknotmcd(pte);
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index b92f25ccef58..24f47981c166 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -710,8 +710,8 @@ static inline void arch_clear_hugepage_flags(struct page *page) { }
 #endif
 
 #ifndef arch_make_huge_pte
-static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
-				       struct page *page, int writable)
+static inline pte_t arch_make_huge_pte(pte_t entry, unsigned int shift,
+				       vm_flags_t flags)
 {
 	return entry;
 }
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 3db405dea3dc..396285b16dd8 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -3856,6 +3856,7 @@ static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page,
 				int writable)
 {
 	pte_t entry;
+	unsigned int shift = huge_page_shift(hstate_vma(vma));
 
 	if (writable) {
 		entry = huge_pte_mkwrite(huge_pte_mkdirty(mk_huge_pte(page,
@@ -3866,7 +3867,7 @@ static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page,
 	}
 	entry = pte_mkyoung(entry);
 	entry = pte_mkhuge(entry);
-	entry = arch_make_huge_pte(entry, vma, page, writable);
+	entry = arch_make_huge_pte(entry, shift, vma->vm_flags);
 
 	return entry;
 }
@@ -5250,10 +5251,11 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
 		}
 		if (!huge_pte_none(pte)) {
 			pte_t old_pte;
+			unsigned int shift = huge_page_shift(hstate_vma(vma));
 
 			old_pte = huge_ptep_modify_prot_start(vma, address, ptep);
 			pte = pte_mkhuge(huge_pte_modify(old_pte, newprot));
-			pte = arch_make_huge_pte(pte, vma, NULL, 0);
+			pte = arch_make_huge_pte(pte, shift, vma->vm_flags);
 			huge_ptep_modify_prot_commit(vma, address, ptep, old_pte, pte);
 			pages++;
 		}
diff --git a/mm/migrate.c b/mm/migrate.c
index b234c3f3acb7..49ee64cd2ff3 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -226,8 +226,10 @@ static bool remove_migration_pte(struct page *page, struct vm_area_struct *vma,
 
 #ifdef CONFIG_HUGETLB_PAGE
 		if (PageHuge(new)) {
+			unsigned int shift = huge_page_shift(hstate_vma(vma));
+
 			pte = pte_mkhuge(pte);
-			pte = arch_make_huge_pte(pte, vma, new, 0);
+			pte = arch_make_huge_pte(pte, shift, vma->vm_flags);
 			set_huge_pte_at(vma->vm_mm, pvmw.address, pvmw.pte, pte);
 			if (PageAnon(new))
 				hugepage_add_anon_rmap(new, vma, pvmw.address);
-- 
2.25.0


^ permalink raw reply related

* [RFC PATCH v1 0/4] Implement huge VMAP and VMALLOC on powerpc 8xx
From: Christophe Leroy @ 2021-04-28 16:46 UTC (permalink / raw)
  To: Andrew Morton, Nicholas Piggin, Mike Kravetz, Mike Rapoport
  Cc: linux-arch, linux-kernel, linux-mm, sparclinux, linuxppc-dev,
	linux-arm-kernel

This series is a first tentative to implement huge VMAP and VMALLOC
on powerpc 8xx. This series applies on Linux next.
For the time being the 8xx specificities are plugged directly into
generic mm functions. I have no real idea on how to make it a nice
beautiful generic implementation for the time being, hence this RFC
in order to get suggestions.

powerpc 8xx has 4 page sizes:
- 4k
- 16k
- 512k
- 8M

At the time being, vmalloc and vmap only support huge pages which are
leaf at PMD level.

Here the PMD level is 4M, it doesn't correspond to any supported
page size.

For the time being, implement use of 16k and 512k pages which is done
at PTE level.

Support of 8M pages will be implemented later, it requires use of
hugepd tables.

Christophe Leroy (4):
  mm/ioremap: Fix iomap_max_page_shift
  mm/hugetlb: Change parameters of arch_make_huge_pte()
  mm/pgtable: Add stubs for {pmd/pub}_{set/clear}_huge
  mm/vmalloc: Add support for huge pages on VMAP and VMALLOC for powerpc
    8xx

 arch/arm64/include/asm/hugetlb.h              |  3 +-
 arch/arm64/mm/hugetlbpage.c                   |  5 +-
 arch/powerpc/Kconfig                          |  3 +-
 .../include/asm/nohash/32/hugetlb-8xx.h       |  5 +-
 arch/sparc/include/asm/pgtable_64.h           |  3 +-
 arch/sparc/mm/hugetlbpage.c                   |  6 +-
 include/linux/hugetlb.h                       |  4 +-
 include/linux/pgtable.h                       | 26 ++++++-
 mm/hugetlb.c                                  |  6 +-
 mm/ioremap.c                                  |  6 +-
 mm/migrate.c                                  |  4 +-
 mm/vmalloc.c                                  | 74 ++++++++++++++++---
 12 files changed, 111 insertions(+), 34 deletions(-)

-- 
2.25.0


^ permalink raw reply

* [RFC PATCH v1 3/4] mm/pgtable: Add stubs for {pmd/pub}_{set/clear}_huge
From: Christophe Leroy @ 2021-04-28 16:46 UTC (permalink / raw)
  To: Andrew Morton, Nicholas Piggin, Mike Kravetz, Mike Rapoport
  Cc: linux-arch, linux-kernel, linux-mm, sparclinux, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <cover.1619628001.git.christophe.leroy@csgroup.eu>

For architectures with no PMD and/or no PUD, add stubs
similar to what we have for architectures without P4D.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 include/linux/pgtable.h | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 46b13780c2c8..d41474a2d255 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -1371,10 +1371,34 @@ static inline int p4d_clear_huge(p4d_t *p4d)
 }
 #endif /* !__PAGETABLE_P4D_FOLDED */
 
+#ifndef __PAGETABLE_PUD_FOLDED
 int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot);
-int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot);
 int pud_clear_huge(pud_t *pud);
+#else
+static inline int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot)
+{
+	return 0;
+}
+static inline int pud_clear_huge(pud_t *pud)
+{
+	return 0;
+}
+#endif /* !__PAGETABLE_PUD_FOLDED */
+
+#ifndef __PAGETABLE_PMD_FOLDED
+int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot);
 int pmd_clear_huge(pmd_t *pmd);
+#else
+static inline int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot)
+{
+	return 0;
+}
+static inline int pmd_clear_huge(pmd_t *pmd)
+{
+	return 0;
+}
+#endif /* !__PAGETABLE_PMD_FOLDED */
+
 int p4d_free_pud_page(p4d_t *p4d, unsigned long addr);
 int pud_free_pmd_page(pud_t *pud, unsigned long addr);
 int pmd_free_pte_page(pmd_t *pmd, unsigned long addr);
-- 
2.25.0


^ permalink raw reply related

* [RFC PATCH v1 4/4] mm/vmalloc: Add support for huge pages on VMAP and VMALLOC for powerpc 8xx
From: Christophe Leroy @ 2021-04-28 16:46 UTC (permalink / raw)
  To: Andrew Morton, Nicholas Piggin, Mike Kravetz, Mike Rapoport
  Cc: linux-arch, linux-kernel, linux-mm, sparclinux, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <cover.1619628001.git.christophe.leroy@csgroup.eu>

powerpc 8xx has 4 page sizes:
- 4k
- 16k
- 512k
- 8M

At the time being, vmalloc and vmap only support huge pages which are
leaf at PMD level.

Here the PMD level is 4M, it doesn't correspond to any supported
page size.

For the time being, implement use of 16k and 512k pages which is done
at PTE level.

Support of 8M pages will be implemented later, it requires use of
hugepd tables.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/Kconfig |  3 +-
 mm/vmalloc.c         | 74 ++++++++++++++++++++++++++++++++++++++------
 2 files changed, 66 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 27e88c38fdf7..b443716f7413 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -188,7 +188,8 @@ config PPC
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_VDSO_TIME_NS
 	select HAVE_ARCH_AUDITSYSCALL
-	select HAVE_ARCH_HUGE_VMAP		if PPC_BOOK3S_64 && PPC_RADIX_MMU
+	select HAVE_ARCH_HUGE_VMAP		if (PPC_BOOK3S_64 && PPC_RADIX_MMU) || PPC_8xx
+	select HAVE_ARCH_HUGE_VMALLOC		if PPC_8xx
 	select HAVE_ARCH_JUMP_LABEL
 	select HAVE_ARCH_JUMP_LABEL_RELATIVE
 	select HAVE_ARCH_KASAN			if PPC32 && PPC_PAGE_SHIFT <= 14
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 5d96fee17226..1f9f9be8ec01 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -36,6 +36,7 @@
 #include <linux/overflow.h>
 #include <linux/pgtable.h>
 #include <linux/uaccess.h>
+#include <linux/hugetlb.h>
 #include <asm/tlbflush.h>
 #include <asm/shmparam.h>
 
@@ -81,12 +82,55 @@ static void free_work(struct work_struct *w)
 }
 
 /*** Page table manipulation functions ***/
+static int vmap_try_huge_pte(pte_t *ptep, unsigned long addr, unsigned long end,
+			     u64 pfn, pgprot_t prot, unsigned int max_page_shift)
+{
+	unsigned long size = end - addr;
+	pte_t pte;
+
+	if (!IS_ENABLED(CONFIG_PPC_8xx))
+		return 0;
+
+	if (PAGE_SIZE == SZ_16K && size < SZ_512K)
+		return 0;
+
+	if (size < SZ_16K)
+		return 0;
+
+	if (max_page_shift < 14)
+		return 0;
+
+	if (size > SZ_512K)
+		size = SZ_512K;
+
+	if (max_page_shift < 19 && size > SZ_16K)
+		size = SZ_16K;
+
+	if (!IS_ALIGNED(addr, size))
+		return 0;
+
+	if (!IS_ALIGNED(PFN_PHYS(pfn), size))
+		return 0;
+
+	if (pte_present(*ptep))
+		return 0;
+
+	pte = pfn_pte(pfn, prot);
+	pte = pte_mkhuge(pte);
+	pte = arch_make_huge_pte(pte, ilog2(size), 0);
+
+	set_huge_pte_at(&init_mm, addr, ptep, pte);
+
+	return PFN_DOWN(size);
+}
+
 static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 			phys_addr_t phys_addr, pgprot_t prot,
-			pgtbl_mod_mask *mask)
+			unsigned int max_page_shift, pgtbl_mod_mask *mask)
 {
 	pte_t *pte;
 	u64 pfn;
+	int npages;
 
 	pfn = phys_addr >> PAGE_SHIFT;
 	pte = pte_alloc_kernel_track(pmd, addr, mask);
@@ -94,9 +138,14 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 		return -ENOMEM;
 	do {
 		BUG_ON(!pte_none(*pte));
-		set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot));
-		pfn++;
-	} while (pte++, addr += PAGE_SIZE, addr != end);
+
+		npages = vmap_try_huge_pte(pte, addr, end, pfn, prot, max_page_shift);
+		if (!npages) {
+			set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot));
+			npages = 1;
+		}
+		pfn += npages;
+	} while (pte += npages, addr += PAGE_SIZE * npages, addr != end);
 	*mask |= PGTBL_PTE_MODIFIED;
 	return 0;
 }
@@ -145,7 +194,7 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
 			continue;
 		}
 
-		if (vmap_pte_range(pmd, addr, next, phys_addr, prot, mask))
+		if (vmap_pte_range(pmd, addr, next, phys_addr, prot, max_page_shift, mask))
 			return -ENOMEM;
 	} while (pmd++, phys_addr += (next - addr), addr = next, addr != end);
 	return 0;
@@ -2881,8 +2930,7 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 		return NULL;
 	}
 
-	if (vmap_allow_huge && !(vm_flags & VM_NO_HUGE_VMAP) &&
-			arch_vmap_pmd_supported(prot)) {
+	if (vmap_allow_huge && !(vm_flags & VM_NO_HUGE_VMAP)) {
 		unsigned long size_per_node;
 
 		/*
@@ -2895,11 +2943,17 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 		size_per_node = size;
 		if (node == NUMA_NO_NODE)
 			size_per_node /= num_online_nodes();
-		if (size_per_node >= PMD_SIZE) {
+		if (arch_vmap_pmd_supported(prot) && size_per_node >= PMD_SIZE) {
 			shift = PMD_SHIFT;
-			align = max(real_align, 1UL << shift);
-			size = ALIGN(real_size, 1UL << shift);
+		} else if (IS_ENABLED(CONFIG_PPC_8xx)) {
+			if (size_per_node >= SZ_512K) {
+				shift = 19;
+			} else if (size_per_node >= SZ_16K) {
+				shift = 14;
+			}
 		}
+		align = max(real_align, 1UL << shift);
+		size = ALIGN(real_size, 1UL << shift);
 	}
 
 again:
-- 
2.25.0


^ permalink raw reply related

* Re: PPC32: Boot regression on Nintendo Wii, after create_branch rework in 5.8
From: Jonathan Neuschäfer @ 2021-04-28 18:14 UTC (permalink / raw)
  To: Jordan Niethe
  Cc: Emmanuel Gil Peyrot, linuxppc-dev, Jonathan Neuschäfer,
	Alistair Popple
In-Reply-To: <CACzsE9qOj2Fp4A9dYopQddw1oc7w--BCe_2_3xJfEo=d9WoC1Q@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2355 bytes --]

Hi,

On Wed, Apr 28, 2021 at 11:33:24AM +1000, Jordan Niethe wrote:
> On Mon, Apr 26, 2021 at 1:40 AM Jonathan Neuschäfer
> <j.neuschaefer@gmx.net> wrote:
> >
> > Hi,
> >
> > I recently booted my Wii again, and I noticed a regression at boot time.
> > Output stops after the "Finalizing device tree... flat tree at 0xXXXXXX"
> > message. I bisected it to this commit in the 5.8 development cycle:
> >
> > commit 7c95d8893fb55869882c9f68f4c94840dc43f18f
> > Author: Jordan Niethe <jniethe5@gmail.com>
> > Date:   Wed May 6 13:40:25 2020 +1000
> >
> >     powerpc: Change calling convention for create_branch() et. al.
[...]
> > Do you have any hints on how to debug and/or fix this issue?
> Thanks for bisecting and reporting.
> The "Finalizing device tree... flat tree at 0xXXXXXX" message comes
> from the bootwrapper so if that is the last output it must be crashing
> pretty early.
> Commit 7c95d8893fb5 ("powerpc: Change calling convention for
> create_branch() et. al.") made a change to machine_init() in
> setup_32.c which seems like it might be a likely culprit for causing
> early crashing.
> The branch that is created and patched is just for optimization, so to
> see if that is in fact the problem it might be worth trying to boot
> with a patch like below
> 
> diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
> --- a/arch/powerpc/kernel/setup_32.c
> +++ b/arch/powerpc/kernel/setup_32.c
> @@ -87,9 +87,6 @@ notrace void __init machine_init(u64 dt_ptr)
> 
>         patch_instruction_site(&patch__memcpy_nocache, ppc_inst(PPC_INST_NOP));
> 
> -       create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
> -       patch_instruction(addr, insn);  /* replace b by bne cr0 */
> -
>         /* Do some early initialization based on the flat device tree */
>         early_init_devtree(__va(dt_ptr));

This brings no improvement, unfortunately. The output is still:

top of MEM2 @ 13F00000

zImage starting: loaded at 0x00b00000 (sp: 0x01145f90)
Allocating 0xae3970 bytes for kernel...
Decompressing (0x00000000 <- 0x00b11000:0x01143576)...
Done! Decompressed 0xa65fdc bytes

Linux/PowerPC load: root=/dev/mmcblk0p2 rootwait console=usbgecko1
Finalizing device tree... flat tree at 0x11467a0


I'll probably dig deeper next weekend.



Jonathan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH 04/17] rtc: cmos: remove cmos_rtc_ops_no_alarm
From: youling257 @ 2021-04-28 18:49 UTC (permalink / raw)
  To: alexandre.belloni
  Cc: linux-rtc, a.zummo, linux-kernel, hdegoede, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <20210110231752.1418816-5-alexandre.belloni@bootlin.com>

this patch cause suspend failed on my Bay trail z3735f tablet.

[  162.038713] PM: dpm_run_callback(): platform_pm_suspend+0x0/0x40 returns -22
[  162.038760] alarmtimer alarmtimer.0.auto: PM: failed to suspend: error -22

^ permalink raw reply

* Re: [PATCH 04/17] rtc: cmos: remove cmos_rtc_ops_no_alarm
From: Alexandre Belloni @ 2021-04-28 20:20 UTC (permalink / raw)
  To: youling257
  Cc: linux-rtc, a.zummo, linux-kernel, hdegoede, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <20210428184946.23999-1-youling257@gmail.com>

Hello,

On 29/04/2021 02:49:46+0800, youling257 wrote:
> this patch cause suspend failed on my Bay trail z3735f tablet.
> 
> [  162.038713] PM: dpm_run_callback(): platform_pm_suspend+0x0/0x40 returns -22
> [  162.038760] alarmtimer alarmtimer.0.auto: PM: failed to suspend: error -22

I think I know what is happening, there is one patch I wanted to send
this cycle but didn't, can you test it?

https://github.com/alexandrebelloni/linux/commit/50641a5a19cedf7561410d7db614da46c228bacc

Thanks for the report!

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* Re: [PATCH 04/17] rtc: cmos: remove cmos_rtc_ops_no_alarm
From: youling 257 @ 2021-04-28 21:07 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: linux-rtc, a.zummo, linux-kernel, hdegoede, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <YInDdgd2r1SDdv4k@piout.net>

test this patch can fix my problem.

2021-04-29 4:20 GMT+08:00, Alexandre Belloni <alexandre.belloni@bootlin.com>:
> Hello,
>
> On 29/04/2021 02:49:46+0800, youling257 wrote:
>> this patch cause suspend failed on my Bay trail z3735f tablet.
>>
>> [  162.038713] PM: dpm_run_callback(): platform_pm_suspend+0x0/0x40
>> returns -22
>> [  162.038760] alarmtimer alarmtimer.0.auto: PM: failed to suspend: error
>> -22
>
> I think I know what is happening, there is one patch I wanted to send
> this cycle but didn't, can you test it?
>
> https://github.com/alexandrebelloni/linux/commit/50641a5a19cedf7561410d7db614da46c228bacc
>
> Thanks for the report!
>
> --
> Alexandre Belloni, co-owner and COO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
>

^ permalink raw reply

* Re: [PATCH] powerpc: Avoid clang uninitialized warning in __get_user_size_allowed
From: Nathan Chancellor @ 2021-04-28 21:41 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Nick Desaulniers, linux-kernel, clang-built-linux, Paul Mackerras,
	linuxppc-dev
In-Reply-To: <32a0f305-031b-e4da-345d-0f03b2b42189@csgroup.eu>

On Tue, Apr 27, 2021 at 07:05:12AM +0200, Christophe Leroy wrote:
> 
> 
> Le 26/04/2021 à 22:35, Nathan Chancellor a écrit :
> > Commit 9975f852ce1b ("powerpc/uaccess: Remove calls to __get_user_bad()
> > and __put_user_bad()") switch to BUILD_BUG() in the default case, which
> > leaves x uninitialized. This will not be an issue because the build will
> > be broken in that case but clang does static analysis before it realizes
> > the default case will be done so it warns about x being uninitialized
> > (trimmed for brevity):
> > 
> >   In file included from mm/mprotect.c:13:
> >   In file included from ./include/linux/hugetlb.h:28:
> >   In file included from ./include/linux/mempolicy.h:16:
> >   ./include/linux/pagemap.h:772:16: warning: variable '__gu_val' is used
> >   uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
> >                   if (unlikely(__get_user(c, uaddr) != 0))
> >                                ^~~~~~~~~~~~~~~~~~~~
> >   ./arch/powerpc/include/asm/uaccess.h:266:2: note: expanded from macro '__get_user'
> >           __get_user_size_allowed(__gu_val, __gu_addr, __gu_size, __gu_err);      \
> >           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >   ./arch/powerpc/include/asm/uaccess.h:235:2: note: expanded from macro
> >   '__get_user_size_allowed'
> >          default: BUILD_BUG();                                   \
> >          ^~~~~~~
> > 
> > Commit 5cd29b1fd3e8 ("powerpc/uaccess: Use asm goto for get_user when
> > compiler supports it") added an initialization for x because of the same
> > reason. Do the same thing here so there is no warning across all
> > versions of clang.
> 
> Ah yes, I tested with Clang 11 which has CONFIG_CC_HAS_ASM_GOTO_OUTPUT,
> that's the reason why I hit that warning only in the
> CONFIG_CC_HAS_ASM_GOTO_OUTPUT branch.
> 
> But regardless, is that normal that Clang warns that on a never taken branch ? That's puzzling.

It seems to be related to the fact that the value of sizeof is assigned
to a variable. At this point in the pipeline, clang does not realize
that the default branch is never taken because __gu_size has not
actually been evaluated. If you stuck a numeric constant in there, it
would not fire.

A simple example: https://godbolt.org/z/jbrqEbh1j

It is possible that could be improved in clang but I am not sure.

> > 
> > Link: https://github.com/ClangBuiltLinux/linux/issues/1359
> > Signed-off-by: Nathan Chancellor <nathan@kernel.org>
> 
> Acked-by: Christophe Leroy <christophe.leroy@csgroup.eu>

Thanks for taking a look!

Cheers,
Nathan

> > ---
> >   arch/powerpc/include/asm/uaccess.h | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
> > index a4e791bcd3fe..a09e4240c5b1 100644
> > --- a/arch/powerpc/include/asm/uaccess.h
> > +++ b/arch/powerpc/include/asm/uaccess.h
> > @@ -232,7 +232,7 @@ do {								\
> >   	case 2: __get_user_asm(x, (u16 __user *)ptr, retval, "lhz"); break;	\
> >   	case 4: __get_user_asm(x, (u32 __user *)ptr, retval, "lwz"); break;	\
> >   	case 8: __get_user_asm2(x, (u64 __user *)ptr, retval);  break;	\
> > -	default: BUILD_BUG();					\
> > +	default: x = 0; BUILD_BUG();				\
> >   	}							\
> >   } while (0)
> > 
> > base-commit: ee6b25fa7c037e42cc5f3b5c024b2a779edab6dd
> > 

^ permalink raw reply

* [PATCH] Add blank line after declarations
From: Sanjana Srinidhi @ 2021-04-28 19:52 UTC (permalink / raw)
  To: geoff, mpe, benh, paulus; +Cc: linuxppc-dev, linux-kernel

Blank line is added after declarations to maintain code uniformity.

Signed-off-by: Sanjana Srinidhi <sanjanasrinidhi1810@gmail.com>
---
 drivers/ps3/ps3av.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 9d66257e1da5..c4ea494ce464 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -175,6 +175,7 @@ static int ps3av_vuart_write(struct ps3_system_bus_device *dev,
 			     const void *buf, unsigned long size)
 {
 	int error;
+
 	dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
 	error = ps3_vuart_write(dev, buf, size);
 	dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
-- 
2.25.1


^ permalink raw reply related

* [PATCH] powerpc: mpc52xx: fix some pr_debug() issues
From: Randy Dunlap @ 2021-04-29  0:53 UTC (permalink / raw)
  To: linux-kernel; +Cc: Randy Dunlap, linuxppc-dev, Anatolij Gustschin

Fix some pr_debug() issues in mpc52xx_pci.c:

- use __func__ to print function names
- use "%pr" to print struct resource entries
- use "%pa" to print a resource_size_t (phys_addr_t)

The latter two fix several build warnings:

../arch/powerpc/platforms/52xx/mpc52xx_pci.c: In function 'mpc52xx_pci_setup':
../include/linux/kern_levels.h:5:18: warning: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'resource_size_t' {aka 'long long unsigned int'} [-Wformat=]
../arch/powerpc/platforms/52xx/mpc52xx_pci.c:277:40: note: format string is defined here
  277 |   pr_debug("mem_resource[1] = {.start=%x, .end=%x, .flags=%lx}\n",
      |                                       ~^
      |                                        |
      |                                        unsigned int
      |                                       %llx
../include/linux/kern_levels.h:5:18: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'resource_size_t' {aka 'long long unsigned int'} [-Wformat=]
../arch/powerpc/platforms/52xx/mpc52xx_pci.c:277:49: note: format string is defined here
  277 |   pr_debug("mem_resource[1] = {.start=%x, .end=%x, .flags=%lx}\n",
      |                                                ~^
      |                                                 |
      |                                                 unsigned int
      |                                                %llx

../arch/powerpc/platforms/52xx/mpc52xx_pci.c:299:36: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  299 |    (unsigned long long)res->flags, (void*)hose->io_base_phys);
      |                                    ^
../arch/powerpc/platforms/52xx/mpc52xx_pci.c:295:2: note: in expansion of macro 'pr_debug'
  295 |  pr_debug(".io_resource={.start=%llx,.end=%llx,.flags=%llx} "
      |  ^~~~~~~~

The change to print mem_resource[0] is for consistency within this
source file and to use the kernel API -- there were no warnings here.

Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Cc: Anatolij Gustschin <agust@denx.de>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/platforms/52xx/mpc52xx_pci.c |   22 ++++++--------------
 1 file changed, 7 insertions(+), 15 deletions(-)

--- linux-next-20210427.orig/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ linux-next-20210427/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -242,7 +242,7 @@ mpc52xx_pci_setup(struct pci_controller
 	u32 tmp;
 	int iwcr0 = 0, iwcr1 = 0, iwcr2 = 0;
 
-	pr_debug("mpc52xx_pci_setup(hose=%p, pci_regs=%p)\n", hose, pci_regs);
+	pr_debug("%s(hose=%p, pci_regs=%p)\n", __func__, hose, pci_regs);
 
 	/* pci_process_bridge_OF_ranges() found all our addresses for us;
 	 * now store them in the right places */
@@ -257,11 +257,7 @@ mpc52xx_pci_setup(struct pci_controller
 	/* Memory windows */
 	res = &hose->mem_resources[0];
 	if (res->flags) {
-		pr_debug("mem_resource[0] = "
-		         "{.start=%llx, .end=%llx, .flags=%llx}\n",
-		         (unsigned long long)res->start,
-			 (unsigned long long)res->end,
-			 (unsigned long long)res->flags);
+		pr_debug("mem_resource[0] = %pr\n", res);
 		out_be32(&pci_regs->iw0btar,
 		         MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
 							resource_size(res)));
@@ -274,8 +270,7 @@ mpc52xx_pci_setup(struct pci_controller
 
 	res = &hose->mem_resources[1];
 	if (res->flags) {
-		pr_debug("mem_resource[1] = {.start=%x, .end=%x, .flags=%lx}\n",
-		         res->start, res->end, res->flags);
+		pr_debug("mem_resource[1] = %pr\n", res);
 		out_be32(&pci_regs->iw1btar,
 		         MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
 							resource_size(res)));
@@ -292,11 +287,8 @@ mpc52xx_pci_setup(struct pci_controller
 		printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__);
 		return;
 	}
-	pr_debug(".io_resource={.start=%llx,.end=%llx,.flags=%llx} "
-	         ".io_base_phys=0x%p\n",
-	         (unsigned long long)res->start,
-		 (unsigned long long)res->end,
-		 (unsigned long long)res->flags, (void*)hose->io_base_phys);
+	pr_debug(".io_resource = %pr .io_base_phys=0x%pa\n",
+			res, &hose->io_base_phys);
 	out_be32(&pci_regs->iw2btar,
 	         MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
 	                                        res->start,
@@ -336,8 +328,8 @@ mpc52xx_pci_fixup_resources(struct pci_d
 {
 	int i;
 
-	pr_debug("mpc52xx_pci_fixup_resources() %.4x:%.4x\n",
-	         dev->vendor, dev->device);
+	pr_debug("%s() %.4x:%.4x\n",
+	         __func__, dev->vendor, dev->device);
 
 	/* We don't rely on boot loader for PCI and resets all
 	   devices */

^ permalink raw reply

* [PATCH v11 1/9] powerpc/mm: Implement set_memory() routines
From: Jordan Niethe @ 2021-04-29  3:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: ajd, cmr, npiggin, aneesh.kumar, naveen.n.rao, Jordan Niethe, dja
In-Reply-To: <20210429031602.2606654-1-jniethe5@gmail.com>

From: Russell Currey <ruscur@russell.cc>

The set_memory_{ro/rw/nx/x}() functions are required for
STRICT_MODULE_RWX, and are generally useful primitives to have.  This
implementation is designed to be generic across powerpc's many MMUs.
It's possible that this could be optimised to be faster for specific
MMUs.

This implementation does not handle cases where the caller is attempting
to change the mapping of the page it is executing from, or if another
CPU is concurrently using the page being altered.  These cases likely
shouldn't happen, but a more complex implementation with MMU-specific code
could safely handle them.

On hash, the linear mapping is not kept in the linux pagetable, so this
will not change the protection if used on that range. Currently these
functions are not used on the linear map so just WARN for now.

Reviewed-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Russell Currey <ruscur@russell.cc>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
[jpn: - Allow set memory functions to be used without Strict RWX
      - Hash: Disallow certain regions
      - Have change_page_attr() take function pointers to manipulate ptes
      - Radix: Add ptesync after set_pte_at()]
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v10: WARN if trying to change the hash linear map
v11: - Update copywrite dates
     - Allow set memory functions to be used without Strict RWX
     - Hash: Disallow certain regions and add comment explaining why
     - Have change_page_attr() take function pointers to manipulate ptes
     - Clarify change_page_attr()'s comment
     - Radix: Add ptesync after set_pte_at()
---
 arch/powerpc/Kconfig                  |   1 +
 arch/powerpc/include/asm/set_memory.h |  10 +++
 arch/powerpc/mm/Makefile              |   2 +-
 arch/powerpc/mm/pageattr.c            | 105 ++++++++++++++++++++++++++
 4 files changed, 117 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/include/asm/set_memory.h
 create mode 100644 arch/powerpc/mm/pageattr.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index cb2d44ee4e38..94c34932a74b 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -138,6 +138,7 @@ config PPC
 	select ARCH_HAS_MEMBARRIER_CALLBACKS
 	select ARCH_HAS_MEMBARRIER_SYNC_CORE
 	select ARCH_HAS_SCALED_CPUTIME		if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64
+	select ARCH_HAS_SET_MEMORY
 	select ARCH_HAS_STRICT_KERNEL_RWX	if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION)
 	select ARCH_HAS_TICK_BROADCAST		if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAS_UACCESS_FLUSHCACHE
diff --git a/arch/powerpc/include/asm/set_memory.h b/arch/powerpc/include/asm/set_memory.h
new file mode 100644
index 000000000000..d1cd69b1a43a
--- /dev/null
+++ b/arch/powerpc/include/asm/set_memory.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_POWERPC_SET_MEMORY_H
+#define _ASM_POWERPC_SET_MEMORY_H
+
+int set_memory_ro(unsigned long addr, int numpages);
+int set_memory_rw(unsigned long addr, int numpages);
+int set_memory_nx(unsigned long addr, int numpages);
+int set_memory_x(unsigned long addr, int numpages);
+
+#endif
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index c3df3a8501d4..9142cf1fb0d5 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -5,7 +5,7 @@
 
 ccflags-$(CONFIG_PPC64)	:= $(NO_MINIMAL_TOC)
 
-obj-y				:= fault.o mem.o pgtable.o mmap.o maccess.o \
+obj-y				:= fault.o mem.o pgtable.o mmap.o maccess.o pageattr.o \
 				   init_$(BITS).o pgtable_$(BITS).o \
 				   pgtable-frag.o ioremap.o ioremap_$(BITS).o \
 				   init-common.o mmu_context.o drmem.o \
diff --git a/arch/powerpc/mm/pageattr.c b/arch/powerpc/mm/pageattr.c
new file mode 100644
index 000000000000..3b4aa72e555e
--- /dev/null
+++ b/arch/powerpc/mm/pageattr.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * MMU-generic set_memory implementation for powerpc
+ *
+ * Copyright 2019-2021, IBM Corporation.
+ */
+
+#include <linux/mm.h>
+#include <linux/set_memory.h>
+
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+
+/*
+ * Updates the attributes of a page in three steps:
+ *
+ * 1. invalidate the page table entry
+ * 2. flush the TLB
+ * 3. install the new entry with the updated attributes
+ *
+ * Invalidating the pte means there are situations where this will not work
+ * when in theory it should.
+ * For example:
+ * - removing write from page whilst it is being executed
+ * - setting a page read-only whilst it is being read by another CPU
+ *
+ */
+static int change_page_attr(pte_t *ptep, unsigned long addr, void *data)
+{
+	pte_t (*fn)(pte_t) = data;
+	pte_t pte;
+
+	spin_lock(&init_mm.page_table_lock);
+
+	/* invalidate the PTE so it's safe to modify */
+	pte = ptep_get_and_clear(&init_mm, addr, ptep);
+	flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+
+	/* modify the PTE bits as desired, then apply */
+	pte = fn(pte);
+
+	set_pte_at(&init_mm, addr, ptep, pte);
+
+	/* See ptesync comment in radix__set_pte_at() */
+	if (radix_enabled())
+		asm volatile("ptesync": : :"memory");
+	spin_unlock(&init_mm.page_table_lock);
+
+	return 0;
+}
+
+static int change_memory_attr(unsigned long addr, int numpages, pte_t (*fn)(pte_t))
+{
+	unsigned long start = ALIGN_DOWN(addr, PAGE_SIZE);
+	unsigned long size = numpages * PAGE_SIZE;
+
+	if (!numpages)
+		return 0;
+
+#ifdef CONFIG_PPC_BOOK3S_64
+	/*
+	 * On hash, the linear mapping is not in the Linux page table so
+	 * apply_to_existing_page_range() will have no effect. If in the future
+	 * the set_memory_* functions are used on the linear map this will need
+	 * to be updated.
+	 */
+	if (!radix_enabled()) {
+		int region = get_region_id(addr);
+
+		if (WARN_ON_ONCE(region != VMALLOC_REGION_ID && region != IO_REGION_ID))
+			return -EINVAL;
+	}
+#endif
+
+	return apply_to_existing_page_range(&init_mm, start, size,
+					    change_page_attr, fn);
+}
+
+int set_memory_ro(unsigned long addr, int numpages)
+{
+	return change_memory_attr(addr, numpages, pte_wrprotect);
+}
+
+static pte_t pte_mkdirtywrite(pte_t pte)
+{
+	return pte_mkwrite(pte_mkdirty(pte));
+}
+
+int set_memory_rw(unsigned long addr, int numpages)
+{
+	return change_memory_attr(addr, numpages, pte_mkdirtywrite);
+}
+
+int set_memory_nx(unsigned long addr, int numpages)
+{
+	return change_memory_attr(addr, numpages, pte_exprotect);
+}
+
+int set_memory_x(unsigned long addr, int numpages)
+{
+	return change_memory_attr(addr, numpages, pte_mkexec);
+}
-- 
2.25.1


^ permalink raw reply related

* [PATCH v11 0/9] powerpc: Further Strict RWX support
From: Jordan Niethe @ 2021-04-29  3:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: ajd, cmr, npiggin, aneesh.kumar, naveen.n.rao, Jordan Niethe, dja

Adding more Strict RWX support on powerpc, in particular Strict Module RWX.
Thanks for all of the feedback everyone.
It is now rebased on linux-next.

For reference the previous revision is available here: 
https://lore.kernel.org/linuxppc-dev/20210330045132.722243-1-jniethe5@gmail.com/

The changes in v11 for each patch:

Christophe Leroy (2):
  powerpc/mm: implement set_memory_attr()
  powerpc/32: use set_memory_attr()

Jordan Niethe (4):
  powerpc/lib/code-patching: Set up Strict RWX patching earlier
  powerpc: Always define MODULES_{VADDR,END}
    v11: - Consider more places MODULES_VADDR was being used
  powerpc/bpf: Remove bpf_jit_free()
    v11: - New to series
  powerpc/bpf: Write protect JIT code
    v11: - Remove CONFIG_STRICT_MODULE_RWX conditional

Russell Currey (3):
  powerpc/mm: Implement set_memory() routines
    v11: - Update copywrite dates
         - Allow set memory functions to be used without Strict RW
         - Hash: Disallow certain regions and add comment explaining why
         - Have change_page_attr() take function pointers to manipulate ptes
         - Clarify change_page_attr()'s comment
         - Radix: Add ptesync after set_pte_at()
  powerpc/kprobes: Mark newly allocated probes as ROX
    v11: Neaten up
  powerpc: Set ARCH_HAS_STRICT_MODULE_RWX
    v11: Neaten up

Some patches were dropped from this revision:
  powerpc/mm/ptdump: debugfs handler for W+X checks at runtime
    - Will use Christophe's generic ptdump series
  powerpc/configs: Enable STRICT_MODULE_RWX in skiroot_defconfig
    - Will enable STRICT_MODULE_RWX by default later


 arch/powerpc/Kconfig                  |   2 +
 arch/powerpc/include/asm/pgtable.h    |  11 ++
 arch/powerpc/include/asm/set_memory.h |  12 +++
 arch/powerpc/kernel/kprobes.c         |  11 ++
 arch/powerpc/kernel/module.c          |  14 +--
 arch/powerpc/lib/code-patching.c      |  12 +--
 arch/powerpc/mm/Makefile              |   2 +-
 arch/powerpc/mm/kasan/kasan_init_32.c |  10 +-
 arch/powerpc/mm/pageattr.c            | 138 ++++++++++++++++++++++++++
 arch/powerpc/mm/pgtable_32.c          |  60 ++---------
 arch/powerpc/mm/ptdump/ptdump.c       |   4 +-
 arch/powerpc/net/bpf_jit_comp.c       |  13 +--
 12 files changed, 204 insertions(+), 85 deletions(-)
 create mode 100644 arch/powerpc/include/asm/set_memory.h
 create mode 100644 arch/powerpc/mm/pageattr.c

-- 
2.25.1


^ permalink raw reply

* [PATCH v11 2/9] powerpc/lib/code-patching: Set up Strict RWX patching earlier
From: Jordan Niethe @ 2021-04-29  3:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: ajd, cmr, npiggin, aneesh.kumar, naveen.n.rao, Jordan Niethe, dja
In-Reply-To: <20210429031602.2606654-1-jniethe5@gmail.com>

setup_text_poke_area() is a late init call so it runs before
mark_rodata_ro() and after the init calls. This lets all the init code
patching simply write to their locations. In the future, kprobes is
going to allocate its instruction pages RO which means they will need
setup_text__poke_area() to have been already called for their code
patching. However, init_kprobes() (which allocates and patches some
instruction pages) is an early init call so it happens before
setup_text__poke_area().

start_kernel() calls poking_init() before any of the init calls. On
powerpc, poking_init() is currently a nop. setup_text_poke_area() relies
on kernel virtual memory, cpu hotplug and per_cpu_areas being setup.
setup_per_cpu_areas(), boot_cpu_hotplug_init() and mm_init() are called
before poking_init().

Turn setup_text_poke_area() into poking_init().

Reviewed-by: Russell Currey <ruscur@russell.cc>
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v9: New to series
---
 arch/powerpc/lib/code-patching.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 870b30d9be2f..15296207e1ba 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -70,14 +70,11 @@ static int text_area_cpu_down(unsigned int cpu)
 }
 
 /*
- * Run as a late init call. This allows all the boot time patching to be done
- * simply by patching the code, and then we're called here prior to
- * mark_rodata_ro(), which happens after all init calls are run. Although
- * BUG_ON() is rude, in this case it should only happen if ENOMEM, and we judge
- * it as being preferable to a kernel that will crash later when someone tries
- * to use patch_instruction().
+ * Although BUG_ON() is rude, in this case it should only happen if ENOMEM, and
+ * we judge it as being preferable to a kernel that will crash later when
+ * someone tries to use patch_instruction().
  */
-static int __init setup_text_poke_area(void)
+int __init poking_init(void)
 {
 	BUG_ON(!cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
 		"powerpc/text_poke:online", text_area_cpu_up,
@@ -85,7 +82,6 @@ static int __init setup_text_poke_area(void)
 
 	return 0;
 }
-late_initcall(setup_text_poke_area);
 
 /*
  * This can be called for kernel text or a module.
-- 
2.25.1


^ permalink raw reply related

* [PATCH v11 3/9] powerpc: Always define MODULES_{VADDR,END}
From: Jordan Niethe @ 2021-04-29  3:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: ajd, cmr, npiggin, aneesh.kumar, naveen.n.rao, Jordan Niethe, dja
In-Reply-To: <20210429031602.2606654-1-jniethe5@gmail.com>

If MODULES_{VADDR,END} are not defined set them to VMALLOC_START and
VMALLOC_END respectively. This reduces the need for special cases. For
example, powerpc's module_alloc() was previously predicated on
MODULES_VADDR being defined but now is unconditionally defined.

This will be useful reducing conditional code in other places that need
to allocate from the module region (i.e., kprobes).

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v10: New to series
v11: - Consider more places MODULES_VADDR was being used
---
 arch/powerpc/include/asm/pgtable.h    | 11 +++++++++++
 arch/powerpc/kernel/module.c          |  5 +----
 arch/powerpc/mm/kasan/kasan_init_32.c | 10 +++++-----
 arch/powerpc/mm/ptdump/ptdump.c       |  4 ++--
 4 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index c6a676714f04..882fda779648 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -39,6 +39,17 @@ struct mm_struct;
 #define __S110	PAGE_SHARED_X
 #define __S111	PAGE_SHARED_X
 
+#ifndef MODULES_VADDR
+#define MODULES_VADDR VMALLOC_START
+#define MODULES_END VMALLOC_END
+#endif
+
+#if defined(CONFIG_PPC_BOOK3S_32) && defined(CONFIG_STRICT_KERNEL_RWX)
+#if TASK_SIZE > MODULES_VADDR
+#error TASK_SIZE > MODULES_VADDR
+#endif
+#endif
+
 #ifndef __ASSEMBLY__
 
 /* Keep these as a macros to avoid include dependency mess */
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index fab84024650c..c60c7457ff47 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -15,6 +15,7 @@
 #include <linux/sort.h>
 #include <asm/setup.h>
 #include <asm/sections.h>
+#include <linux/mm.h>
 
 static LIST_HEAD(module_bug_list);
 
@@ -88,7 +89,6 @@ int module_finalize(const Elf_Ehdr *hdr,
 	return 0;
 }
 
-#ifdef MODULES_VADDR
 static __always_inline void *
 __module_alloc(unsigned long size, unsigned long start, unsigned long end)
 {
@@ -102,8 +102,6 @@ void *module_alloc(unsigned long size)
 	unsigned long limit = (unsigned long)_etext - SZ_32M;
 	void *ptr = NULL;
 
-	BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
-
 	/* First try within 32M limit from _etext to avoid branch trampolines */
 	if (MODULES_VADDR < PAGE_OFFSET && MODULES_END > limit)
 		ptr = __module_alloc(size, limit, MODULES_END);
@@ -113,4 +111,3 @@ void *module_alloc(unsigned long size)
 
 	return ptr;
 }
-#endif
diff --git a/arch/powerpc/mm/kasan/kasan_init_32.c b/arch/powerpc/mm/kasan/kasan_init_32.c
index cf8770b1a692..42c057366ac7 100644
--- a/arch/powerpc/mm/kasan/kasan_init_32.c
+++ b/arch/powerpc/mm/kasan/kasan_init_32.c
@@ -116,11 +116,11 @@ static void __init kasan_unmap_early_shadow_vmalloc(void)
 
 	kasan_update_early_region(k_start, k_end, __pte(0));
 
-#ifdef MODULES_VADDR
-	k_start = (unsigned long)kasan_mem_to_shadow((void *)MODULES_VADDR);
-	k_end = (unsigned long)kasan_mem_to_shadow((void *)MODULES_END);
-	kasan_update_early_region(k_start, k_end, __pte(0));
-#endif
+	if (MODULES_VADDR != VMALLOC_START && MODULES_END != VMALLOC_END) {
+		k_start = (unsigned long)kasan_mem_to_shadow((void *)MODULES_VADDR);
+		k_end = (unsigned long)kasan_mem_to_shadow((void *)MODULES_END);
+		kasan_update_early_region(k_start, k_end, __pte(0));
+	}
 }
 
 void __init kasan_mmu_init(void)
diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c
index aca354fb670b..0431457f668f 100644
--- a/arch/powerpc/mm/ptdump/ptdump.c
+++ b/arch/powerpc/mm/ptdump/ptdump.c
@@ -73,7 +73,7 @@ struct addr_marker {
 
 static struct addr_marker address_markers[] = {
 	{ 0,	"Start of kernel VM" },
-#ifdef MODULES_VADDR
+#if defined(CONFIG_BOOK32_32) && defined(CONFIG_STRICT_KERNEL_RWX)
 	{ 0,	"modules start" },
 	{ 0,	"modules end" },
 #endif
@@ -359,7 +359,7 @@ static void populate_markers(void)
 #else
 	address_markers[i++].start_address = TASK_SIZE;
 #endif
-#ifdef MODULES_VADDR
+#if defined(CONFIG_BOOK32_32) && defined(CONFIG_STRICT_KERNEL_RWX)
 	address_markers[i++].start_address = MODULES_VADDR;
 	address_markers[i++].start_address = MODULES_END;
 #endif
-- 
2.25.1


^ permalink raw reply related

* [PATCH v11 4/9] powerpc/kprobes: Mark newly allocated probes as ROX
From: Jordan Niethe @ 2021-04-29  3:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: ajd, cmr, npiggin, aneesh.kumar, naveen.n.rao, Jordan Niethe, dja
In-Reply-To: <20210429031602.2606654-1-jniethe5@gmail.com>

From: Russell Currey <ruscur@russell.cc>

Add the arch specific insn page allocator for powerpc. This allocates
ROX pages if STRICT_KERNEL_RWX is enabled. These pages are only written
to with patch_instruction() which is able to write RO pages.

Reviewed-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Russell Currey <ruscur@russell.cc>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
[jpn: Reword commit message, switch to __vmalloc_node_range()]
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v9: - vmalloc_exec() no longer exists
    - Set the page to RW before freeing it
v10: - use __vmalloc_node_range()
v11: - Neaten up
---
 arch/powerpc/kernel/kprobes.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 01ab2163659e..5670b43e254f 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -25,6 +25,7 @@
 #include <asm/sections.h>
 #include <asm/inst.h>
 #include <linux/uaccess.h>
+#include <linux/vmalloc.h>
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
@@ -103,6 +104,16 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
 	return addr;
 }
 
+void *alloc_insn_page(void)
+{
+	pgprot_t prot = IS_ENABLED(CONFIG_STRICT_KERNEL_RWX) ? PAGE_KERNEL_ROX :
+							       PAGE_KERNEL_EXEC;
+
+	return __vmalloc_node_range(PAGE_SIZE, 1, MODULES_VADDR, MODULES_END,
+			GFP_KERNEL, prot, VM_FLUSH_RESET_PERMS,
+			NUMA_NO_NODE, __builtin_return_address(0));
+}
+
 int arch_prepare_kprobe(struct kprobe *p)
 {
 	int ret = 0;
-- 
2.25.1


^ permalink raw reply related

* [PATCH v11 5/9] powerpc/bpf: Remove bpf_jit_free()
From: Jordan Niethe @ 2021-04-29  3:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: ajd, cmr, npiggin, aneesh.kumar, naveen.n.rao, Jordan Niethe, dja
In-Reply-To: <20210429031602.2606654-1-jniethe5@gmail.com>

Commit 74451e66d516 ("bpf: make jited programs visible in traces") added
a default bpf_jit_free() implementation. Powerpc did not use the default
bpf_jit_free() as powerpc did not set the images read-only. The default
bpf_jit_free() called bpf_jit_binary_unlock_ro() is why it could not be
used for powerpc.

Commit d53d2f78cead ("bpf: Use vmalloc special flag") moved keeping
track of read-only memory to vmalloc. This included removing
bpf_jit_binary_unlock_ro(). Therefore there is no reason powerpc needs
its own bpf_jit_free(). Remove it.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v11: New to series
---
 arch/powerpc/net/bpf_jit_comp.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 798ac4350a82..6c8c268e4fe8 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -257,15 +257,3 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
 
 	return fp;
 }
-
-/* Overriding bpf_jit_free() as we don't set images read-only. */
-void bpf_jit_free(struct bpf_prog *fp)
-{
-	unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK;
-	struct bpf_binary_header *bpf_hdr = (void *)addr;
-
-	if (fp->jited)
-		bpf_jit_binary_free(bpf_hdr);
-
-	bpf_prog_unlock_free(fp);
-}
-- 
2.25.1


^ permalink raw reply related

* [PATCH v11 6/9] powerpc/bpf: Write protect JIT code
From: Jordan Niethe @ 2021-04-29  3:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: ajd, cmr, npiggin, aneesh.kumar, naveen.n.rao, Jordan Niethe, dja
In-Reply-To: <20210429031602.2606654-1-jniethe5@gmail.com>

Add the necessary call to bpf_jit_binary_lock_ro() to remove write and
add exec permissions to the JIT image after it has finished being
written.

Without CONFIG_STRICT_MODULE_RWX the image will be writable and
executable until the call to bpf_jit_binary_lock_ro().

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v10: New to series
v11: Remove CONFIG_STRICT_MODULE_RWX conditional
---
 arch/powerpc/net/bpf_jit_comp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 6c8c268e4fe8..53aefee3fe70 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -237,6 +237,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
 	fp->jited_len = alloclen;
 
 	bpf_flush_icache(bpf_hdr, (u8 *)bpf_hdr + (bpf_hdr->pages * PAGE_SIZE));
+	bpf_jit_binary_lock_ro(bpf_hdr);
 	if (!fp->is_func || extra_pass) {
 		bpf_prog_fill_jited_linfo(fp, addrs);
 out_addrs:
-- 
2.25.1


^ permalink raw reply related

* [PATCH v11 7/9] powerpc: Set ARCH_HAS_STRICT_MODULE_RWX
From: Jordan Niethe @ 2021-04-29  3:16 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: ajd, cmr, npiggin, aneesh.kumar, naveen.n.rao, Jordan Niethe, dja
In-Reply-To: <20210429031602.2606654-1-jniethe5@gmail.com>

From: Russell Currey <ruscur@russell.cc>

To enable strict module RWX on powerpc, set:

    CONFIG_STRICT_MODULE_RWX=y

You should also have CONFIG_STRICT_KERNEL_RWX=y set to have any real
security benefit.

ARCH_HAS_STRICT_MODULE_RWX is set to require ARCH_HAS_STRICT_KERNEL_RWX.
This is due to a quirk in arch/Kconfig and arch/powerpc/Kconfig that
makes STRICT_MODULE_RWX *on by default* in configurations where
STRICT_KERNEL_RWX is *unavailable*.

Since this doesn't make much sense, and module RWX without kernel RWX
doesn't make much sense, having the same dependencies as kernel RWX
works around this problem.

With STRICT_MODULE_RWX, now make module_alloc() allocate pages with
KERNEL_PAGE protection rather than KERNEL_PAGE_EXEC.

Book32s/32 processors with a hash mmu (i.e. 604 core) can not set memory
protection on a page by page basis so do not enable.

Signed-off-by: Russell Currey <ruscur@russell.cc>
[jpn: - predicate on !PPC_BOOK3S_604
      - make module_alloc() use PAGE_KERNEL protection]
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v10: - Predicate on !PPC_BOOK3S_604
     - Make module_alloc() use PAGE_KERNEL protection
v11: - Neaten up
---
 arch/powerpc/Kconfig         | 1 +
 arch/powerpc/kernel/module.c | 9 ++++++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 94c34932a74b..9e264309fd99 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -140,6 +140,7 @@ config PPC
 	select ARCH_HAS_SCALED_CPUTIME		if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64
 	select ARCH_HAS_SET_MEMORY
 	select ARCH_HAS_STRICT_KERNEL_RWX	if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION)
+	select ARCH_HAS_STRICT_MODULE_RWX	if ARCH_HAS_STRICT_KERNEL_RWX && !PPC_BOOK3S_604
 	select ARCH_HAS_TICK_BROADCAST		if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAS_UACCESS_FLUSHCACHE
 	select ARCH_HAS_COPY_MC			if PPC64
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index c60c7457ff47..9eabaf1fadbe 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -92,9 +92,12 @@ int module_finalize(const Elf_Ehdr *hdr,
 static __always_inline void *
 __module_alloc(unsigned long size, unsigned long start, unsigned long end)
 {
-	return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL,
-				    PAGE_KERNEL_EXEC, VM_FLUSH_RESET_PERMS, NUMA_NO_NODE,
-				    __builtin_return_address(0));
+	pgprot_t prot = IS_ENABLED(CONFIG_STRICT_MODULE_RWX) ? PAGE_KERNEL :
+							       PAGE_KERNEL_EXEC;
+
+	return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+			GFP_KERNEL, prot, VM_FLUSH_RESET_PERMS,
+			NUMA_NO_NODE, __builtin_return_address(0));
 }
 
 void *module_alloc(unsigned long size)
-- 
2.25.1


^ permalink raw reply related

* [PATCH v11 8/9] powerpc/mm: implement set_memory_attr()
From: Jordan Niethe @ 2021-04-29  3:16 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: ajd, cmr, kbuild test robot, npiggin, aneesh.kumar, naveen.n.rao,
	Jordan Niethe, dja
In-Reply-To: <20210429031602.2606654-1-jniethe5@gmail.com>

From: Christophe Leroy <christophe.leroy@csgroup.eu>

In addition to the set_memory_xx() functions which allows to change
the memory attributes of not (yet) used memory regions, implement a
set_memory_attr() function to:
- set the final memory protection after init on currently used
kernel regions.
- enable/disable kernel memory regions in the scope of DEBUG_PAGEALLOC.

Unlike the set_memory_xx() which can act in three step as the regions
are unused, this function must modify 'on the fly' as the kernel is
executing from them. At the moment only PPC32 will use it and changing
page attributes on the fly is not an issue.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Reported-by: kbuild test robot <lkp@intel.com>
[ruscur: cast "data" to unsigned long instead of int]
Signed-off-by: Russell Currey <ruscur@russell.cc>
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/include/asm/set_memory.h |  2 ++
 arch/powerpc/mm/pageattr.c            | 33 +++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/arch/powerpc/include/asm/set_memory.h b/arch/powerpc/include/asm/set_memory.h
index d1cd69b1a43a..a738e86f34bd 100644
--- a/arch/powerpc/include/asm/set_memory.h
+++ b/arch/powerpc/include/asm/set_memory.h
@@ -7,4 +7,6 @@ int set_memory_rw(unsigned long addr, int numpages);
 int set_memory_nx(unsigned long addr, int numpages);
 int set_memory_x(unsigned long addr, int numpages);
 
+int set_memory_attr(unsigned long addr, int numpages, pgprot_t prot);
+
 #endif
diff --git a/arch/powerpc/mm/pageattr.c b/arch/powerpc/mm/pageattr.c
index 3b4aa72e555e..9098066bc113 100644
--- a/arch/powerpc/mm/pageattr.c
+++ b/arch/powerpc/mm/pageattr.c
@@ -103,3 +103,36 @@ int set_memory_x(unsigned long addr, int numpages)
 {
 	return change_memory_attr(addr, numpages, pte_mkexec);
 }
+
+/*
+ * Set the attributes of a page:
+ *
+ * This function is used by PPC32 at the end of init to set final kernel memory
+ * protection. It includes changing the maping of the page it is executing from
+ * and data pages it is using.
+ */
+static int set_page_attr(pte_t *ptep, unsigned long addr, void *data)
+{
+	pgprot_t prot = __pgprot((unsigned long)data);
+
+	spin_lock(&init_mm.page_table_lock);
+
+	set_pte_at(&init_mm, addr, ptep, pte_modify(*ptep, prot));
+	flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+
+	spin_unlock(&init_mm.page_table_lock);
+
+	return 0;
+}
+
+int set_memory_attr(unsigned long addr, int numpages, pgprot_t prot)
+{
+	unsigned long start = ALIGN_DOWN(addr, PAGE_SIZE);
+	unsigned long sz = numpages * PAGE_SIZE;
+
+	if (numpages <= 0)
+		return 0;
+
+	return apply_to_existing_page_range(&init_mm, start, sz, set_page_attr,
+					    (void *)pgprot_val(prot));
+}
-- 
2.25.1


^ permalink raw reply related

* [PATCH v11 9/9] powerpc/32: use set_memory_attr()
From: Jordan Niethe @ 2021-04-29  3:16 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: ajd, cmr, npiggin, aneesh.kumar, naveen.n.rao, Jordan Niethe, dja
In-Reply-To: <20210429031602.2606654-1-jniethe5@gmail.com>

From: Christophe Leroy <christophe.leroy@csgroup.eu>

Use set_memory_attr() instead of the PPC32 specific change_page_attr()

change_page_attr() was checking that the address was not mapped by
blocks and was handling highmem, but that's unneeded because the
affected pages can't be in highmem and block mapping verification
is already done by the callers.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
[ruscur: rebase on powerpc/merge with Christophe's new patches]
Signed-off-by: Russell Currey <ruscur@russell.cc>
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/mm/pgtable_32.c | 60 ++++++------------------------------
 1 file changed, 10 insertions(+), 50 deletions(-)

diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index e0ec67a16887..dcf5ecca19d9 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -23,6 +23,7 @@
 #include <linux/highmem.h>
 #include <linux/memblock.h>
 #include <linux/slab.h>
+#include <linux/set_memory.h>
 
 #include <asm/pgalloc.h>
 #include <asm/fixmap.h>
@@ -132,64 +133,20 @@ void __init mapin_ram(void)
 	}
 }
 
-static int __change_page_attr_noflush(struct page *page, pgprot_t prot)
-{
-	pte_t *kpte;
-	unsigned long address;
-
-	BUG_ON(PageHighMem(page));
-	address = (unsigned long)page_address(page);
-
-	if (v_block_mapped(address))
-		return 0;
-	kpte = virt_to_kpte(address);
-	if (!kpte)
-		return -EINVAL;
-	__set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0);
-
-	return 0;
-}
-
-/*
- * Change the page attributes of an page in the linear mapping.
- *
- * THIS DOES NOTHING WITH BAT MAPPINGS, DEBUG USE ONLY
- */
-static int change_page_attr(struct page *page, int numpages, pgprot_t prot)
-{
-	int i, err = 0;
-	unsigned long flags;
-	struct page *start = page;
-
-	local_irq_save(flags);
-	for (i = 0; i < numpages; i++, page++) {
-		err = __change_page_attr_noflush(page, prot);
-		if (err)
-			break;
-	}
-	wmb();
-	local_irq_restore(flags);
-	flush_tlb_kernel_range((unsigned long)page_address(start),
-			       (unsigned long)page_address(page));
-	return err;
-}
-
 void mark_initmem_nx(void)
 {
-	struct page *page = virt_to_page(_sinittext);
 	unsigned long numpages = PFN_UP((unsigned long)_einittext) -
 				 PFN_DOWN((unsigned long)_sinittext);
 
 	if (v_block_mapped((unsigned long)_sinittext))
 		mmu_mark_initmem_nx();
 	else
-		change_page_attr(page, numpages, PAGE_KERNEL);
+		set_memory_attr((unsigned long)_sinittext, numpages, PAGE_KERNEL);
 }
 
 #ifdef CONFIG_STRICT_KERNEL_RWX
 void mark_rodata_ro(void)
 {
-	struct page *page;
 	unsigned long numpages;
 
 	if (v_block_mapped((unsigned long)_stext + 1)) {
@@ -198,20 +155,18 @@ void mark_rodata_ro(void)
 		return;
 	}
 
-	page = virt_to_page(_stext);
 	numpages = PFN_UP((unsigned long)_etext) -
 		   PFN_DOWN((unsigned long)_stext);
 
-	change_page_attr(page, numpages, PAGE_KERNEL_ROX);
+	set_memory_attr((unsigned long)_stext, numpages, PAGE_KERNEL_ROX);
 	/*
 	 * mark .rodata as read only. Use __init_begin rather than __end_rodata
 	 * to cover NOTES and EXCEPTION_TABLE.
 	 */
-	page = virt_to_page(__start_rodata);
 	numpages = PFN_UP((unsigned long)__init_begin) -
 		   PFN_DOWN((unsigned long)__start_rodata);
 
-	change_page_attr(page, numpages, PAGE_KERNEL_RO);
+	set_memory_attr((unsigned long)__start_rodata, numpages, PAGE_KERNEL_RO);
 
 	// mark_initmem_nx() should have already run by now
 	ptdump_check_wx();
@@ -221,9 +176,14 @@ void mark_rodata_ro(void)
 #ifdef CONFIG_DEBUG_PAGEALLOC
 void __kernel_map_pages(struct page *page, int numpages, int enable)
 {
+	unsigned long addr = (unsigned long)page_address(page);
+
 	if (PageHighMem(page))
 		return;
 
-	change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0));
+	if (enable)
+		set_memory_attr(addr, numpages, PAGE_KERNEL);
+	else
+		set_memory_attr(addr, numpages, __pgprot(0));
 }
 #endif /* CONFIG_DEBUG_PAGEALLOC */
-- 
2.25.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox