powerpc updates for 5.16

- Enable STRICT_KERNEL_RWX for Freescale 85xx platforms.
 
  - Activate CONFIG_STRICT_KERNEL_RWX by default, while still allowing it to be disabled.
 
  - Add support for out-of-line static calls on 32-bit.
 
  - Fix oopses doing bpf-to-bpf calls when STRICT_KERNEL_RWX is enabled.
 
  - Fix boot hangs on e5500 due to stale value in ESR passed to do_page_fault().
 
  - Fix several bugs on pseries in handling of device tree cache information for hotplugged
    CPUs, and/or during partition migration.
 
  - Various other small features and fixes.
 
 Thanks to: Alexey Kardashevskiy, Alistair Popple, Anatolij Gustschin, Andrew Donnellan,
 Athira Rajeev, Bixuan Cui, Bjorn Helgaas, Cédric Le Goater, Christophe Leroy, Daniel
 Axtens, Daniel Henrique Barboza, Denis Kirjanov, Fabiano Rosas, Frederic Barrat, Gustavo
 A. R. Silva, Hari Bathini, Jacques de Laval, Joel Stanley, Kai Song, Kajol Jain, Laurent
 Vivier, Leonardo Bras, Madhavan Srinivasan, Nathan Chancellor, Nathan Lynch, Naveen N.
 Rao, Nicholas Piggin, Nick Desaulniers, Niklas Schnelle, Oliver O'Halloran, Rob Herring,
 Russell Currey, Srikar Dronamraju, Stan Johnson, Tyrel Datwyler, Uwe Kleine-König, Vasant
 Hegde, Wan Jiabing, Xiaoming Ni,
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCAAxFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAmGFDPoTHG1wZUBlbGxl
 cm1hbi5pZC5hdQAKCRBR6+o8yOGlgNbsEACVczMVwMBEny5a7W1tqq1bnY9RFVw3
 K+/rE7/FpSLX+RrwgoMkmqfPvfyc9WISVLlIQDKz4XhkBjaXv0+Y4OMsymuDCbxL
 Qk7F1ff22UfLmPjjJk39gHJ8QZQqZk3wmFu2QzTO4yBZbz2SqqXFLxwyoLpZ0LJ8
 pdGl51+bIsTkDJzrdkhX9X4AKS/fYyjbQxq5u7FS89ZCCs+KvzjLcDRo0GZYaOK/
 hgDBa60DCCszL/9yjbh0ANZxmM2Z3+6AXkvAAXrtXzIGk4JzenZfiV+VEzmq8Tt0
 UpWSsUEe7VgykMR3MTrL9G8op70PpKX6OMUPegJq4iRQ24h4mpFCK4oV9OMKJqpF
 ifN9NO2ZZKOz1ke4l7Xe8SEHLX7rq5U/P7INh3AsKYNYwo6HkJhSPxiCBWUTlnZ3
 OYoZ7czyO4gMPHWP92z4CoSiTYVBFuyhYexRcnQskg60TIwbr+lMXziRyPRGI8b6
 taf2rD8eAiyUJnvkFUsyAHtYHpkSkuMeiVqY2CDQdh2SdtIFgwKzB2RjFL0gzaBZ
 XP9RWD+HernGQAJSlIk7cVthont3JHklcKk+ohhDbsWzPeUJcz6t4ChtgRq0x4q4
 Hpes1lsVfXpyxj5ouBK/E/t+diwPvBLM0dCcarQJE6ExgMzBC/C7Br7jCSgyVJA2
 VhtcZaCYh+vRlQ==
 =f7HE
 -----END PGP SIGNATURE-----

Merge tag 'powerpc-5.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc updates from Michael Ellerman:

 - Enable STRICT_KERNEL_RWX for Freescale 85xx platforms.

 - Activate CONFIG_STRICT_KERNEL_RWX by default, while still allowing it
   to be disabled.

 - Add support for out-of-line static calls on 32-bit.

 - Fix oopses doing bpf-to-bpf calls when STRICT_KERNEL_RWX is enabled.

 - Fix boot hangs on e5500 due to stale value in ESR passed to
   do_page_fault().

 - Fix several bugs on pseries in handling of device tree cache
   information for hotplugged CPUs, and/or during partition migration.

 - Various other small features and fixes.

Thanks to Alexey Kardashevskiy, Alistair Popple, Anatolij Gustschin,
Andrew Donnellan, Athira Rajeev, Bixuan Cui, Bjorn Helgaas, Cédric Le
Goater, Christophe Leroy, Daniel Axtens, Daniel Henrique Barboza, Denis
Kirjanov, Fabiano Rosas, Frederic Barrat, Gustavo A.  R.  Silva, Hari
Bathini, Jacques de Laval, Joel Stanley, Kai Song, Kajol Jain, Laurent
Vivier, Leonardo Bras, Madhavan Srinivasan, Nathan Chancellor, Nathan
Lynch, Naveen N.  Rao, Nicholas Piggin, Nick Desaulniers, Niklas
Schnelle, Oliver O'Halloran, Rob Herring, Russell Currey, Srikar
Dronamraju, Stan Johnson, Tyrel Datwyler, Uwe Kleine-König, Vasant
Hegde, Wan Jiabing, and Xiaoming Ni,

* tag 'powerpc-5.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (73 commits)
  powerpc/8xx: Fix Oops with STRICT_KERNEL_RWX without DEBUG_RODATA_TEST
  powerpc/32e: Ignore ESR in instruction storage interrupt handler
  powerpc/powernv/prd: Unregister OPAL_MSG_PRD2 notifier during module unload
  powerpc: Don't provide __kernel_map_pages() without ARCH_SUPPORTS_DEBUG_PAGEALLOC
  MAINTAINERS: Update powerpc KVM entry
  powerpc/xmon: fix task state output
  powerpc/44x/fsp2: add missing of_node_put
  powerpc/dcr: Use cmplwi instead of 3-argument cmpli
  KVM: PPC: Tick accounting should defer vtime accounting 'til after IRQ handling
  powerpc/security: Use a mutex for interrupt exit code patching
  powerpc/83xx/mpc8349emitx: Make mcu_gpiochip_remove() return void
  powerpc/fsl_booke: Fix setting of exec flag when setting TLBCAMs
  powerpc/book3e: Fix set_memory_x() and set_memory_nx()
  powerpc/nohash: Fix __ptep_set_access_flags() and ptep_set_wrprotect()
  powerpc/bpf: Fix write protecting JIT code
  selftests/powerpc: Use date instead of EPOCHSECONDS in mitigation-patching.sh
  powerpc/64s/interrupt: Fix check_return_regs_valid() false positive
  powerpc/boot: Set LC_ALL=C in wrapper script
  powerpc/64s: Default to 64K pages for 64 bit book3s
  Revert "powerpc/audit: Convert powerpc to AUDIT_ARCH_COMPAT_GENERIC"
  ...
This commit is contained in:
Linus Torvalds 2021-11-05 08:15:46 -07:00
commit 5c0b0c676a
112 changed files with 837 additions and 582 deletions

View File

@ -10388,11 +10388,8 @@ F: arch/mips/include/uapi/asm/kvm*
F: arch/mips/kvm/
KERNEL VIRTUAL MACHINE FOR POWERPC (KVM/powerpc)
M: Paul Mackerras <paulus@ozlabs.org>
L: kvm-ppc@vger.kernel.org
S: Supported
W: http://www.linux-kvm.org/
T: git git://github.com/agraf/linux-2.6.git
L: linuxppc-dev@lists.ozlabs.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git topic/ppc-kvm
F: arch/powerpc/include/asm/kvm*
F: arch/powerpc/include/uapi/asm/kvm*
F: arch/powerpc/kernel/kvm*

View File

@ -138,7 +138,8 @@ config PPC
select ARCH_HAS_PTE_SPECIAL
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_KERNEL_RWX if (PPC_BOOK3S || PPC_8xx || 40x) && !HIBERNATION
select ARCH_HAS_STRICT_KERNEL_RWX if FSL_BOOKE && !HIBERNATION && !RANDOMIZE_BASE
select ARCH_HAS_STRICT_MODULE_RWX if ARCH_HAS_STRICT_KERNEL_RWX && !PPC_BOOK3S_32
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_UACCESS_FLUSHCACHE
@ -148,9 +149,10 @@ config PPC
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT
select ARCH_STACKWALK
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC32 || PPC_BOOK3S_64
select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC_BOOK3S || PPC_8xx || 40x
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_CMPXCHG_LOCKREF if PPC64
select ARCH_USE_MEMTEST
@ -190,7 +192,7 @@ config PPC
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KASAN if PPC32 && PPC_PAGE_SHIFT <= 14
select HAVE_ARCH_KASAN_VMALLOC if PPC32 && PPC_PAGE_SHIFT <= 14
select HAVE_ARCH_KFENCE if PPC32
select HAVE_ARCH_KFENCE if PPC_BOOK3S_32 || PPC_8xx || 40x
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
@ -241,6 +243,7 @@ config PPC
select HAVE_SOFTIRQ_ON_OWN_STACK
select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2)
select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13)
select HAVE_STATIC_CALL if PPC32
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_VIRT_CPU_ACCOUNTING
select HUGETLB_PAGE_SIZE_VARIABLE if PPC_BOOK3S_64 && HUGETLB_PAGE
@ -707,6 +710,7 @@ config ARCH_MEMORY_PROBE
choice
prompt "Page size"
default PPC_64K_PAGES if PPC_BOOK3S_64
default PPC_4K_PAGES
help
Select the kernel logical page size. Increasing the page size
@ -778,7 +782,8 @@ config DATA_SHIFT_BOOL
bool "Set custom data alignment"
depends on ADVANCED_OPTIONS
depends on STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE
depends on PPC_BOOK3S_32 || (PPC_8xx && !PIN_TLB_DATA && !STRICT_KERNEL_RWX)
depends on PPC_BOOK3S_32 || (PPC_8xx && !PIN_TLB_DATA && !STRICT_KERNEL_RWX) || \
FSL_BOOKE
help
This option allows you to set the kernel data alignment. When
RAM is mapped by blocks, the alignment needs to fit the size and
@ -791,11 +796,13 @@ config DATA_SHIFT
default 24 if STRICT_KERNEL_RWX && PPC64
range 17 28 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_BOOK3S_32
range 19 23 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_8xx
range 20 24 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_FSL_BOOKE
default 22 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
default 18 if (DEBUG_PAGEALLOC || KFENCE) && PPC_BOOK3S_32
default 23 if STRICT_KERNEL_RWX && PPC_8xx
default 23 if (DEBUG_PAGEALLOC || KFENCE) && PPC_8xx && PIN_TLB_DATA
default 19 if (DEBUG_PAGEALLOC || KFENCE) && PPC_8xx
default 24 if STRICT_KERNEL_RWX && FSL_BOOKE
default PPC_PAGE_SHIFT
help
On Book3S 32 (603+), DBATs are used to map kernel text and rodata RO.
@ -1123,7 +1130,10 @@ config LOWMEM_CAM_NUM_BOOL
config LOWMEM_CAM_NUM
depends on FSL_BOOKE
int "Number of CAMs to use to map low memory" if LOWMEM_CAM_NUM_BOOL
default 3
default 3 if !STRICT_KERNEL_RWX
default 9 if DATA_SHIFT >= 24
default 12 if DATA_SHIFT >= 22
default 15
config DYNAMIC_MEMSTART
bool "Enable page aligned dynamic load address for kernel"

View File

@ -123,7 +123,7 @@ src-wlib-y := string.S crt0.S stdio.c decompress.c main.c \
oflib.c ofconsole.c cuboot.c
src-wlib-$(CONFIG_PPC_MPC52xx) += mpc52xx-psc.c
src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) += opal-calls.S opal.c
src-wlib-$(CONFIG_PPC_POWERNV) += opal-calls.S opal.c
ifndef CONFIG_PPC64_BOOT_WRAPPER
src-wlib-y += crtsavres.S
endif

View File

@ -140,8 +140,8 @@
clock-frequency = <0>; /* From boot loader */
interrupts = <2 8 0 2 9 0 2 10 0>;
bus-range = <0 0>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
0x02000000 0 0x90000000 0x90000000 0 0x10000000
0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000>,
<0x02000000 0 0x90000000 0x90000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
};
};

View File

@ -35,7 +35,7 @@
};
};
memory {
memory@0 {
device_type = "memory";
reg = <0x00000000 0x08000000>; // 128MB
};
@ -225,8 +225,8 @@
clock-frequency = <0>; // From boot loader
interrupts = <2 8 0 2 9 0 2 10 0>;
bus-range = <0 0>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
0x02000000 0 0x90000000 0x90000000 0 0x10000000
0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000>,
<0x02000000 0 0x90000000 0x90000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
};
};

View File

@ -16,7 +16,7 @@
model = "intercontrol,digsy-mtc";
compatible = "intercontrol,digsy-mtc";
memory {
memory@0 {
reg = <0x00000000 0x02000000>; // 32MB
};
@ -98,9 +98,9 @@
clock-frequency = <0>; // From boot loader
interrupts = <2 8 0 2 9 0 2 10 0>;
bus-range = <0 0>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
0x02000000 0 0x90000000 0x90000000 0 0x10000000
0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000>,
<0x02000000 0 0x90000000 0x90000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
};
localbus {

View File

@ -32,7 +32,7 @@
};
};
memory {
memory@0 {
device_type = "memory";
reg = <0x00000000 0x04000000>; // 64MB
};
@ -283,9 +283,9 @@
clock-frequency = <0>; // From boot loader
interrupts = <2 8 0 2 9 0 2 10 0>;
bus-range = <0 0>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000>,
<0x02000000 0 0xa0000000 0xa0000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
};
localbus {

View File

@ -31,7 +31,7 @@
led4 { gpios = <&gpio_simple 2 1>; };
};
memory {
memory@0 {
reg = <0x00000000 0x10000000>; // 256MB
};
@ -116,9 +116,9 @@
clock-frequency = <0>; // From boot loader
interrupts = <2 8 0 2 9 0 2 10 0>;
bus-range = <0 0>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000>,
<0x02000000 0 0xa0000000 0xa0000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
};
localbus {

View File

@ -32,7 +32,7 @@
};
};
memory {
memory@0 {
reg = <0x00000000 0x08000000>; // 128MB RAM
};
@ -96,9 +96,9 @@
0xe000 0 0 1 &media5200_fpga 0 5 // CoralIP
>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000>,
<0x02000000 0 0xa0000000 0xa0000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
interrupt-parent = <&mpc5200_pic>;
};

View File

@ -33,7 +33,7 @@
};
};
memory: memory {
memory: memory@0 {
device_type = "memory";
reg = <0x00000000 0x04000000>; // 64MB
};
@ -276,7 +276,9 @@
clock-frequency = <0>; // From boot loader
interrupts = <2 8 0 2 9 0 2 10 0>;
bus-range = <0 0>;
// ranges = need to add
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000>,
<0x02000000 0 0x90000000 0x90000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
};
localbus: localbus {

View File

@ -106,9 +106,9 @@
0x8000 0 0 3 &mpc5200_pic 0 2 3
0x8000 0 0 4 &mpc5200_pic 0 1 3
>;
ranges = <0x42000000 0 0x60000000 0x60000000 0 0x10000000
0x02000000 0 0x90000000 0x90000000 0 0x10000000
0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
ranges = <0x42000000 0 0x60000000 0x60000000 0 0x10000000>,
<0x02000000 0 0x90000000 0x90000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
};
localbus {

View File

@ -12,7 +12,7 @@
model = "ifm,o2d";
compatible = "ifm,o2d";
memory {
memory@0 {
reg = <0x00000000 0x08000000>; // 128MB
};

View File

@ -19,7 +19,7 @@
model = "ifm,o2d";
compatible = "ifm,o2d";
memory {
memory@0 {
reg = <0x00000000 0x04000000>; // 64MB
};

View File

@ -12,7 +12,7 @@
model = "ifm,o2dnt2";
compatible = "ifm,o2d";
memory {
memory@0 {
reg = <0x00000000 0x08000000>; // 128MB
};

View File

@ -12,7 +12,7 @@
model = "ifm,o3dnt";
compatible = "ifm,o2d";
memory {
memory@0 {
reg = <0x00000000 0x04000000>; // 64MB
};

View File

@ -90,9 +90,9 @@
0xc800 0 0 2 &mpc5200_pic 1 2 3
0xc800 0 0 3 &mpc5200_pic 1 3 3
0xc800 0 0 4 &mpc5200_pic 0 0 3>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000>,
<0x02000000 0 0xa0000000 0xa0000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
};
localbus {

View File

@ -20,7 +20,7 @@
model = "phytec,pcm032";
compatible = "phytec,pcm032";
memory {
memory@0 {
reg = <0x00000000 0x08000000>; // 128MB
};
@ -87,9 +87,9 @@
0xc800 0 0 2 &mpc5200_pic 1 2 3
0xc800 0 0 3 &mpc5200_pic 1 3 3
0xc800 0 0 4 &mpc5200_pic 0 0 3>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000>,
<0x02000000 0 0xa0000000 0xa0000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
};
localbus {

View File

@ -32,7 +32,7 @@
};
};
memory {
memory@0 {
device_type = "memory";
reg = <0x00000000 0x04000000>; // 64MB
};
@ -200,8 +200,8 @@
clock-frequency = <0>; // From boot loader
interrupts = <2 8 0 2 9 0 2 10 0>;
bus-range = <0 0>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
0x02000000 0 0x90000000 0x90000000 0 0x10000000
0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000>,
<0x02000000 0 0x90000000 0x90000000 0 0x10000000>,
<0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
};
};

View File

@ -132,7 +132,7 @@ int serial_console_init(void)
else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart"))
rc = mpc5200_psc_console_init(devp, &serial_cd);
#endif
#ifdef CONFIG_PPC64_BOOT_WRAPPER
#ifdef CONFIG_PPC_POWERNV
else if (dt_is_compatible(devp, "ibm,opal-console-raw"))
rc = opal_console_init(devp, &serial_cd);
#endif

View File

@ -26,6 +26,8 @@
# Stop execution if any command fails
set -e
export LC_ALL=C
# Allow for verbose output
if [ "$V" = 1 ]; then
set -x

View File

@ -36,7 +36,6 @@ CONFIG_GEN_RTC=y
CONFIG_BINFMT_MISC=m
CONFIG_IRQ_ALL_CPUS=y
CONFIG_NUMA=y
CONFIG_PPC_64K_PAGES=y
CONFIG_SCHED_SMT=y
CONFIG_PCIEPORTBUS=y
CONFIG_NET=y

View File

@ -26,6 +26,7 @@ CONFIG_CPU_FREQ_PMAC64=y
CONFIG_GEN_RTC=y
CONFIG_KEXEC=y
CONFIG_IRQ_ALL_CPUS=y
CONFIG_PPC_4K_PAGES=y
CONFIG_PCI_MSI=y
CONFIG_NET=y
CONFIG_PACKET=y

View File

@ -25,6 +25,7 @@ CONFIG_UDBG_RTAS_CONSOLE=y
CONFIG_GEN_RTC=y
CONFIG_KEXEC=y
CONFIG_IRQ_ALL_CPUS=y
CONFIG_PPC_4K_PAGES=y
CONFIG_PCI_MSI=y
CONFIG_NET=y
CONFIG_PACKET=y

View File

@ -26,6 +26,7 @@ CONFIG_PPC_MICROWATT=y
# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
CONFIG_CPU_FREQ=y
CONFIG_HZ_100=y
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_MEM_KEYS is not set
# CONFIG_SECCOMP is not set
# CONFIG_MQ_IOSCHED_KYBER is not set

View File

@ -22,7 +22,6 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_HZ_1000=y
CONFIG_PPC_64K_PAGES=y
# CONFIG_SECCOMP is not set
CONFIG_PCI_MSI=y
CONFIG_PCCARD=y

View File

@ -62,7 +62,6 @@ CONFIG_MEMORY_FAILURE=y
CONFIG_HWPOISON_INJECT=m
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
CONFIG_PPC_64K_PAGES=y
CONFIG_SCHED_SMT=y
CONFIG_PM=y
CONFIG_HOTPLUG_PCI=y

View File

@ -52,7 +52,6 @@ CONFIG_KEXEC_FILE=y
CONFIG_CRASH_DUMP=y
CONFIG_FA_DUMP=y
CONFIG_IRQ_ALL_CPUS=y
CONFIG_PPC_64K_PAGES=y
CONFIG_SCHED_SMT=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_RPA=m

View File

@ -30,6 +30,7 @@ CONFIG_PS3_LPM=m
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=y
CONFIG_KEXEC=y
CONFIG_PPC_4K_PAGES=y
# CONFIG_SPARSEMEM_VMEMMAP is not set
# CONFIG_COMPACTION is not set
CONFIG_SCHED_SMT=y

View File

@ -56,7 +56,6 @@ CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_KSM=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_PPC_64K_PAGES=y
CONFIG_SCHED_SMT=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_RPA=m

View File

@ -43,7 +43,6 @@ CONFIG_KEXEC_FILE=y
CONFIG_PRESERVE_FA_DUMP=y
CONFIG_IRQ_ALL_CPUS=y
CONFIG_NUMA=y
CONFIG_PPC_64K_PAGES=y
CONFIG_SCHED_SMT=y
CONFIG_CMDLINE="console=tty0 console=hvc0 ipr.fast_reboot=1 quiet"
# CONFIG_SECCOMP is not set

View File

@ -12,6 +12,4 @@
# define ASM_CONST(x) __ASM_CONST(x)
#endif
#define UPD_CONSTR "<>"
#endif /* _ASM_POWERPC_ASM_CONST_H */

View File

@ -27,14 +27,14 @@ static __inline__ int arch_atomic_read(const atomic_t *v)
{
int t;
__asm__ __volatile__("lwz%U1%X1 %0,%1" : "=r"(t) : "m"UPD_CONSTR(v->counter));
__asm__ __volatile__("lwz%U1%X1 %0,%1" : "=r"(t) : "m<>"(v->counter));
return t;
}
static __inline__ void arch_atomic_set(atomic_t *v, int i)
{
__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"UPD_CONSTR(v->counter) : "r"(i));
__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m<>"(v->counter) : "r"(i));
}
#define ATOMIC_OP(op, asm_op) \
@ -320,14 +320,14 @@ static __inline__ s64 arch_atomic64_read(const atomic64_t *v)
{
s64 t;
__asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : "m"UPD_CONSTR(v->counter));
__asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : "m<>"(v->counter));
return t;
}
static __inline__ void arch_atomic64_set(atomic64_t *v, s64 i)
{
__asm__ __volatile__("std%U0%X0 %1,%0" : "=m"UPD_CONSTR(v->counter) : "r"(i));
__asm__ __volatile__("std%U0%X0 %1,%0" : "=m<>"(v->counter) : "r"(i));
}
#define ATOMIC64_OP(op, asm_op) \

View File

@ -255,6 +255,8 @@ int hash__create_section_mapping(unsigned long start, unsigned long end,
int nid, pgprot_t prot);
int hash__remove_section_mapping(unsigned long start, unsigned long end);
void hash__kernel_map_pages(struct page *page, int numpages, int enable);
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_BOOK3S_64_HASH_H */

View File

@ -1101,6 +1101,16 @@ static inline void vmemmap_remove_mapping(unsigned long start,
}
#endif
#ifdef CONFIG_DEBUG_PAGEALLOC
static inline void __kernel_map_pages(struct page *page, int numpages, int enable)
{
if (radix_enabled())
radix__kernel_map_pages(page, numpages, enable);
else
hash__kernel_map_pages(page, numpages, enable);
}
#endif
static inline pte_t pmd_pte(pmd_t pmd)
{
return __pte_raw(pmd_raw(pmd));

View File

@ -316,5 +316,8 @@ int radix__create_section_mapping(unsigned long start, unsigned long end,
int nid, pgprot_t prot);
int radix__remove_section_mapping(unsigned long start, unsigned long end);
#endif /* CONFIG_MEMORY_HOTPLUG */
void radix__kernel_map_pages(struct page *page, int numpages, int enable);
#endif /* __ASSEMBLY__ */
#endif

View File

@ -122,7 +122,7 @@ static inline u##size name(const volatile u##size __iomem *addr) \
{ \
u##size ret; \
__asm__ __volatile__("sync;"#insn"%U1%X1 %0,%1;twi 0,%0,0;isync"\
: "=r" (ret) : "m"UPD_CONSTR (*addr) : "memory"); \
: "=r" (ret) : "m<>" (*addr) : "memory"); \
return ret; \
}
@ -130,7 +130,7 @@ static inline u##size name(const volatile u##size __iomem *addr) \
static inline void name(volatile u##size __iomem *addr, u##size val) \
{ \
__asm__ __volatile__("sync;"#insn"%U0%X0 %1,%0" \
: "=m"UPD_CONSTR (*addr) : "r" (val) : "memory"); \
: "=m<>" (*addr) : "r" (val) : "memory"); \
mmiowb_set_pending(); \
}

View File

@ -280,12 +280,6 @@ extern void iommu_init_early_dart(struct pci_controller_ops *controller_ops);
extern void iommu_init_early_pasemi(void);
#if defined(CONFIG_PPC64) && defined(CONFIG_PM)
static inline void iommu_save(void)
{
if (ppc_md.iommu_save)
ppc_md.iommu_save();
}
static inline void iommu_restore(void)
{
if (ppc_md.iommu_restore)

View File

@ -79,7 +79,6 @@ extern int crash_wake_offline;
struct kimage;
struct pt_regs;
extern void default_machine_kexec(struct kimage *image);
extern int default_machine_kexec_prepare(struct kimage *image);
extern void default_machine_crash_shutdown(struct pt_regs *regs);
extern int crash_shutdown_register(crash_shutdown_t handler);
extern int crash_shutdown_unregister(crash_shutdown_t handler);

View File

@ -378,6 +378,10 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
rb |= 1; /* L field */
rb |= r & 0xff000 & ((1ul << a_pgshift) - 1); /* LP field */
}
/*
* This sets both bits of the B field in the PTE. 0b1x values are
* reserved, but those will have been filtered by kvmppc_do_h_enter.
*/
rb |= (v >> HPTE_V_SSIZE_SHIFT) << 8; /* B field */
return rb;
}

View File

@ -29,7 +29,6 @@ struct machdep_calls {
char *name;
#ifdef CONFIG_PPC64
#ifdef CONFIG_PM
void (*iommu_save)(void);
void (*iommu_restore)(void);
#endif
#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
@ -43,7 +42,6 @@ struct machdep_calls {
void (*setup_arch)(void); /* Optional, may be NULL */
/* Optional, may be NULL. */
void (*show_cpuinfo)(struct seq_file *m);
void (*show_percpuinfo)(struct seq_file *m, int i);
/* Returns the current operating frequency of "cpu" in Hz */
unsigned long (*get_proc_freq)(unsigned int cpu);
@ -74,8 +72,6 @@ struct machdep_calls {
int (*set_rtc_time)(struct rtc_time *);
void (*get_rtc_time)(struct rtc_time *);
time64_t (*get_boot_time)(void);
unsigned char (*rtc_read_val)(int addr);
void (*rtc_write_val)(int addr, unsigned char val);
void (*calibrate_decr)(void);
@ -141,8 +137,6 @@ struct machdep_calls {
May be NULL. */
void (*init)(void);
void (*kgdb_map_scc)(void);
/*
* optional PCI "hooks"
*/
@ -187,13 +181,6 @@ struct machdep_calls {
#ifdef CONFIG_KEXEC_CORE
void (*kexec_cpu_down)(int crash_shutdown, int secondary);
/* Called to do what every setup is needed on image and the
* reboot code buffer. Returns 0 on success.
* Provide your own (maybe dummy) implementation if your platform
* claims to support kexec.
*/
int (*machine_kexec_prepare)(struct kimage *image);
/* Called to perform the _real_ kexec.
* Do NOT allocate memory or fail here. We are past the point of
* no return.

View File

@ -193,10 +193,12 @@ static inline pte_t pte_wrprotect(pte_t pte)
}
#endif
#ifndef pte_mkexec
static inline pte_t pte_mkexec(pte_t pte)
{
return __pte(pte_val(pte) | _PAGE_EXEC);
}
#endif
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD)
@ -245,7 +247,7 @@ static int number_of_cells_per_pte(pmd_t *pmd, pte_basic_t val, int huge)
static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p,
unsigned long clr, unsigned long set, int huge)
{
pte_basic_t *entry = &p->pte;
pte_basic_t *entry = (pte_basic_t *)p;
pte_basic_t old = pte_val(*p);
pte_basic_t new = (old & ~(pte_basic_t)clr) | set;
int num, i;
@ -306,30 +308,29 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
}
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
#ifndef ptep_set_wrprotect
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
unsigned long clr = ~pte_val(pte_wrprotect(__pte(~0)));
unsigned long set = pte_val(pte_wrprotect(__pte(0)));
pte_update(mm, addr, ptep, clr, set, 0);
pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
}
#endif
#ifndef __ptep_set_access_flags
static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
pte_t *ptep, pte_t entry,
unsigned long address,
int psize)
{
pte_t pte_set = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(0)))));
pte_t pte_clr = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(~0)))));
unsigned long set = pte_val(entry) & pte_val(pte_set);
unsigned long clr = ~pte_val(entry) & ~pte_val(pte_clr);
unsigned long set = pte_val(entry) &
(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
int huge = psize > mmu_virtual_psize ? 1 : 0;
pte_update(vma->vm_mm, address, ptep, clr, set, huge);
pte_update(vma->vm_mm, address, ptep, 0, set, huge);
flush_tlb_page(vma, address);
}
#endif
static inline int pte_young(pte_t pte)
{

View File

@ -136,6 +136,28 @@ static inline pte_t pte_mkhuge(pte_t pte)
#define pte_mkhuge pte_mkhuge
static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p,
unsigned long clr, unsigned long set, int huge);
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
pte_update(mm, addr, ptep, 0, _PAGE_RO, 0);
}
#define ptep_set_wrprotect ptep_set_wrprotect
static inline void __ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep,
pte_t entry, unsigned long address, int psize)
{
unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_EXEC);
unsigned long clr = ~pte_val(entry) & _PAGE_RO;
int huge = psize > mmu_virtual_psize ? 1 : 0;
pte_update(vma->vm_mm, address, ptep, clr, set, huge);
flush_tlb_page(vma, address);
}
#define __ptep_set_access_flags __ptep_set_access_flags
static inline unsigned long pgd_leaf_size(pgd_t pgd)
{
if (pgd_val(pgd) & _PMD_PAGE_8M)

View File

@ -118,11 +118,6 @@ static inline pte_t pte_wrprotect(pte_t pte)
return __pte(pte_val(pte) & ~_PAGE_RW);
}
static inline pte_t pte_mkexec(pte_t pte)
{
return __pte(pte_val(pte) | _PAGE_EXEC);
}
#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)

View File

@ -48,7 +48,7 @@
#define _PAGE_WRITETHRU 0x800000 /* W: cache write-through */
/* "Higher level" linux bit combinations */
#define _PAGE_EXEC _PAGE_BAP_UX /* .. and was cache cleaned */
#define _PAGE_EXEC (_PAGE_BAP_SX | _PAGE_BAP_UX) /* .. and was cache cleaned */
#define _PAGE_RW (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
#define _PAGE_KERNEL_RW (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
#define _PAGE_KERNEL_RO (_PAGE_BAP_SR)
@ -93,11 +93,11 @@
/* Permission masks used to generate the __P and __S table */
#define PAGE_NONE __pgprot(_PAGE_BASE)
#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_BAP_UX)
#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_BAP_UX)
#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_BAP_UX)
#ifndef __ASSEMBLY__
static inline pte_t pte_mkprivileged(pte_t pte)
@ -113,6 +113,16 @@ static inline pte_t pte_mkuser(pte_t pte)
}
#define pte_mkuser pte_mkuser
static inline pte_t pte_mkexec(pte_t pte)
{
if (pte_val(pte) & _PAGE_BAP_UR)
return __pte((pte_val(pte) & ~_PAGE_BAP_SX) | _PAGE_BAP_UX);
else
return __pte((pte_val(pte) & ~_PAGE_BAP_UX) | _PAGE_BAP_SX);
}
#define pte_mkexec pte_mkexec
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */

View File

@ -32,11 +32,26 @@ extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
#ifdef CONFIG_PPC_8xx
static inline void local_flush_tlb_mm(struct mm_struct *mm)
{
unsigned int pid = READ_ONCE(mm->context.id);
if (pid != MMU_NO_CONTEXT)
asm volatile ("sync; tlbia; isync" : : : "memory");
}
static inline void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
{
asm volatile ("tlbie %0; sync" : : "r" (vmaddr) : "memory");
}
#else
extern void local_flush_tlb_mm(struct mm_struct *mm);
extern void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
extern void __local_flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
int tsize, int ind);
#endif
#ifdef CONFIG_SMP
extern void flush_tlb_mm(struct mm_struct *mm);

View File

@ -21,7 +21,7 @@ static inline bool is_shared_processor(void)
return static_branch_unlikely(&shared_processor);
}
/* If bit 0 is set, the cpu has been preempted */
/* If bit 0 is set, the cpu has been ceded, conferred, or preempted */
static inline u32 yield_count_of(int cpu)
{
__be32 yield_count = READ_ONCE(lppaca_of(cpu).yield_count);
@ -92,17 +92,47 @@ static inline void prod_cpu(int cpu)
#define vcpu_is_preempted vcpu_is_preempted
static inline bool vcpu_is_preempted(int cpu)
{
/*
* The dispatch/yield bit alone is an imperfect indicator of
* whether the hypervisor has dispatched @cpu to run on a physical
* processor. When it is clear, @cpu is definitely not preempted.
* But when it is set, it means only that it *might* be, subject to
* other conditions. So we check other properties of the VM and
* @cpu first, resorting to the yield count last.
*/
/*
* Hypervisor preemption isn't possible in dedicated processor
* mode by definition.
*/
if (!is_shared_processor())
return false;
#ifdef CONFIG_PPC_SPLPAR
if (!is_kvm_guest()) {
int first_cpu = cpu_first_thread_sibling(smp_processor_id());
int first_cpu;
/*
* Preemption can only happen at core granularity. This CPU
* is not preempted if one of the CPU of this core is not
* preempted.
* The result of vcpu_is_preempted() is used in a
* speculative way, and is always subject to invalidation
* by events internal and external to Linux. While we can
* be called in preemptable context (in the Linux sense),
* we're not accessing per-cpu resources in a way that can
* race destructively with Linux scheduler preemption and
* migration, and callers can tolerate the potential for
* error introduced by sampling the CPU index without
* pinning the task to it. So it is permissible to use
* raw_smp_processor_id() here to defeat the preempt debug
* warnings that can arise from using smp_processor_id()
* in arbitrary contexts.
*/
first_cpu = cpu_first_thread_sibling(raw_smp_processor_id());
/*
* The PowerVM hypervisor dispatches VMs on a whole core
* basis. So we know that a thread sibling of the local CPU
* cannot have been preempted by the hypervisor, even if it
* has called H_CONFER, which will set the yield bit.
*/
if (cpu_first_thread_sibling(cpu) == first_cpu)
return false;

View File

@ -2,17 +2,33 @@
#ifndef _ASM_POWERPC_PGTABLE_TYPES_H
#define _ASM_POWERPC_PGTABLE_TYPES_H
#if defined(__CHECKER__) || !defined(CONFIG_PPC32)
#define STRICT_MM_TYPECHECKS
#endif
/* PTE level */
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
typedef struct { pte_basic_t pte, pte1, pte2, pte3; } pte_t;
#else
#elif defined(STRICT_MM_TYPECHECKS)
typedef struct { pte_basic_t pte; } pte_t;
#else
typedef pte_basic_t pte_t;
#endif
#if defined(STRICT_MM_TYPECHECKS) || \
(defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES))
#define __pte(x) ((pte_t) { (x) })
static inline pte_basic_t pte_val(pte_t x)
{
return x.pte;
}
#else
#define __pte(x) ((pte_t)(x))
static inline pte_basic_t pte_val(pte_t x)
{
return x;
}
#endif
/* PMD level */
#ifdef CONFIG_PPC64

View File

@ -28,8 +28,8 @@
#else
#define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base)
#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base)
#define SAVE_NVGPRS(base) stmw 13, GPR0+4*13(base)
#define REST_NVGPRS(base) lmw 13, GPR0+4*13(base)
#define SAVE_NVGPRS(base) SAVE_GPR(13, base); SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
#define REST_NVGPRS(base) REST_GPR(13, base); REST_8GPRS(14, base); REST_10GPRS(22, base)
#endif
#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)

View File

@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_POWERPC_STATIC_CALL_H
#define _ASM_POWERPC_STATIC_CALL_H
#define __PPC_SCT(name, inst) \
asm(".pushsection .text, \"ax\" \n" \
".align 5 \n" \
".globl " STATIC_CALL_TRAMP_STR(name) " \n" \
STATIC_CALL_TRAMP_STR(name) ": \n" \
inst " \n" \
" lis 12,2f@ha \n" \
" lwz 12,2f@l(12) \n" \
" mtctr 12 \n" \
" bctr \n" \
"1: li 3, 0 \n" \
" blr \n" \
"2: .long 0 \n" \
".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \
".size " STATIC_CALL_TRAMP_STR(name) ", . - " STATIC_CALL_TRAMP_STR(name) " \n" \
".popsection \n")
#define PPC_SCT_RET0 20 /* Offset of label 1 */
#define PPC_SCT_DATA 28 /* Offset of label 2 */
#define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func) __PPC_SCT(name, "b " #func)
#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) __PPC_SCT(name, "blr")
#endif /* _ASM_POWERPC_STATIC_CALL_H */

View File

@ -86,7 +86,7 @@ __pu_failed: \
"1: " op "%U1%X1 %0,%1 # put_user\n" \
EX_TABLE(1b, %l2) \
: \
: "r" (x), "m"UPD_CONSTR (*addr) \
: "r" (x), "m<>" (*addr) \
: \
: label)
@ -143,7 +143,7 @@ do { \
"1: "op"%U1%X1 %0, %1 # get_user\n" \
EX_TABLE(1b, %l2) \
: "=r" (x) \
: "m"UPD_CONSTR (*addr) \
: "m<>" (*addr) \
: \
: label)
@ -200,7 +200,7 @@ __gus_failed: \
".previous\n" \
EX_TABLE(1b, 3b) \
: "=r" (err), "=r" (x) \
: "m"UPD_CONSTR (*addr), "i" (-EFAULT), "0" (err))
: "m<>" (*addr), "i" (-EFAULT), "0" (err))
#ifdef __powerpc64__
#define __get_user_asm2(x, addr, err) \

View File

@ -61,27 +61,35 @@ enum perf_event_powerpc_regs {
PERF_REG_POWERPC_PMC4,
PERF_REG_POWERPC_PMC5,
PERF_REG_POWERPC_PMC6,
/* Max regs without the extended regs */
PERF_REG_POWERPC_SDAR,
PERF_REG_POWERPC_SIAR,
/* Max mask value for interrupt regs w/o extended regs */
PERF_REG_POWERPC_MAX = PERF_REG_POWERPC_MMCRA + 1,
/* Max mask value for interrupt regs including extended regs */
PERF_REG_EXTENDED_MAX = PERF_REG_POWERPC_SIAR + 1,
};
#define PERF_REG_PMU_MASK ((1ULL << PERF_REG_POWERPC_MAX) - 1)
/* Exclude MMCR3, SIER2, SIER3 for CPU_FTR_ARCH_300 */
#define PERF_EXCLUDE_REG_EXT_300 (7ULL << PERF_REG_POWERPC_MMCR3)
/*
* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_300
* includes 9 SPRS from MMCR0 to PMC6 excluding the
* unsupported SPRS in PERF_EXCLUDE_REG_EXT_300.
* includes 11 SPRS from MMCR0 to SIAR excluding the
* unsupported SPRS MMCR3, SIER2 and SIER3.
*/
#define PERF_REG_PMU_MASK_300 ((0xfffULL << PERF_REG_POWERPC_MMCR0) - PERF_EXCLUDE_REG_EXT_300)
#define PERF_REG_PMU_MASK_300 \
((1ULL << PERF_REG_POWERPC_MMCR0) | (1ULL << PERF_REG_POWERPC_MMCR1) | \
(1ULL << PERF_REG_POWERPC_MMCR2) | (1ULL << PERF_REG_POWERPC_PMC1) | \
(1ULL << PERF_REG_POWERPC_PMC2) | (1ULL << PERF_REG_POWERPC_PMC3) | \
(1ULL << PERF_REG_POWERPC_PMC4) | (1ULL << PERF_REG_POWERPC_PMC5) | \
(1ULL << PERF_REG_POWERPC_PMC6) | (1ULL << PERF_REG_POWERPC_SDAR) | \
(1ULL << PERF_REG_POWERPC_SIAR))
/*
* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_31
* includes 12 SPRs from MMCR0 to PMC6.
* includes 14 SPRs from MMCR0 to SIAR.
*/
#define PERF_REG_PMU_MASK_31 (0xfffULL << PERF_REG_POWERPC_MMCR0)
#define PERF_REG_PMU_MASK_31 \
(PERF_REG_PMU_MASK_300 | (1ULL << PERF_REG_POWERPC_MMCR3) | \
(1ULL << PERF_REG_POWERPC_SIER2) | (1ULL << PERF_REG_POWERPC_SIER3))
#define PERF_REG_EXTENDED_MAX (PERF_REG_POWERPC_PMC6 + 1)
#endif /* _UAPI_ASM_POWERPC_PERF_REGS_H */

View File

@ -106,7 +106,7 @@ extra-y += vmlinux.lds
obj-$(CONFIG_RELOCATABLE) += reloc_$(BITS).o
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o early_32.o
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o early_32.o static_call.o
obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o

View File

@ -349,6 +349,7 @@ int fix_alignment(struct pt_regs *regs)
if (op.type != CACHEOP + DCBZ)
return -EINVAL;
PPC_WARN_ALIGNMENT(dcbz, regs);
WARN_ON_ONCE(!user_mode(regs));
r = emulate_dcbz(op.ea, regs);
} else {
if (type == LARX || type == STCX)

View File

@ -589,6 +589,7 @@ EXPORT_SYMBOL(eeh_check_failure);
/**
* eeh_pci_enable - Enable MMIO or DMA transfers for this slot
* @pe: EEH PE
* @function: EEH option
*
* This routine should be called to reenable frozen MMIO or DMA
* so that it would work correctly again. It's useful while doing
@ -761,8 +762,8 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
}
/**
* eeh_set_pe_freset - Check the required reset for the indicated device
* @data: EEH device
* eeh_set_dev_freset - Check the required reset for the indicated device
* @edev: EEH device
* @flag: return value
*
* Each device might have its preferred reset type: fundamental or
@ -801,6 +802,7 @@ static void eeh_pe_refreeze_passed(struct eeh_pe *root)
/**
* eeh_pe_reset_full - Complete a full reset process on the indicated PE
* @pe: EEH PE
* @include_passed: include passed-through devices?
*
* This function executes a full reset procedure on a PE, including setting
* the appropriate flags, performing a fundamental or hot reset, and then
@ -937,6 +939,7 @@ static struct notifier_block eeh_device_nb = {
/**
* eeh_init - System wide EEH initialization
* @ops: struct to trace EEH operation callback functions
*
* It's the platform's job to call this from an arch_initcall().
*/
@ -1442,6 +1445,7 @@ static int eeh_pe_reenable_devices(struct eeh_pe *pe, bool include_passed)
* eeh_pe_reset - Issue PE reset according to specified type
* @pe: EEH PE
* @option: reset type
* @include_passed: include passed-through devices?
*
* The routine is called to reset the specified PE with the
* indicated type, either fundamental reset or hot reset.
@ -1513,12 +1517,12 @@ EXPORT_SYMBOL_GPL(eeh_pe_configure);
* eeh_pe_inject_err - Injecting the specified PCI error to the indicated PE
* @pe: the indicated PE
* @type: error type
* @function: error function
* @func: error function
* @addr: address
* @mask: address mask
*
* The routine is called to inject the specified PCI error, which
* is determined by @type and @function, to the indicated PE for
* is determined by @type and @func, to the indicated PE for
* testing purpose.
*/
int eeh_pe_inject_err(struct eeh_pe *pe, int type, int func,

View File

@ -31,11 +31,10 @@ int __init check_kvm_guest(void)
if (!hyper_node)
return 0;
if (!of_device_is_compatible(hyper_node, "linux,kvm"))
return 0;
static_branch_enable(&kvm_guest);
if (of_device_is_compatible(hyper_node, "linux,kvm"))
static_branch_enable(&kvm_guest);
of_node_put(hyper_node);
return 0;
}
core_initcall(check_kvm_guest); // before kvm_guest_init()

View File

@ -755,7 +755,7 @@ _GLOBAL(mmu_pin_tlb)
cmplw r6, r9
bdnzt lt, 2b
4: LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT)
4: LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT)
2: ori r0, r6, MD_EVALID
mtspr SPRN_MD_CTR, r5
mtspr SPRN_MD_EPN, r0

View File

@ -465,12 +465,21 @@ label:
bl do_page_fault; \
b interrupt_return
/*
* Instruction TLB Error interrupt handlers may call InstructionStorage
* directly without clearing ESR, so the ESR at this point may be left over
* from a prior interrupt.
*
* In any case, do_page_fault for BOOK3E does not use ESR and always expects
* dsisr to be 0. ESR_DST from a prior store in particular would confuse fault
* handling.
*/
#define INSTRUCTION_STORAGE_EXCEPTION \
START_EXCEPTION(InstructionStorage) \
NORMAL_EXCEPTION_PROLOG(0x400, INST_STORAGE); \
mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \
NORMAL_EXCEPTION_PROLOG(0x400, INST_STORAGE); \
li r5,0; /* Store 0 in regs->esr (dsisr) */ \
stw r5,_ESR(r11); \
stw r12, _DEAR(r11); /* Pass SRR0 as arg2 */ \
stw r12, _DEAR(r11); /* Set regs->dear (dar) to SRR0 */ \
prepare_transfer_to_handler; \
bl do_page_fault; \
b interrupt_return

View File

@ -127,15 +127,6 @@ bool wp_check_constraints(struct pt_regs *regs, struct ppc_inst instr,
return false;
}
static int cache_op_size(void)
{
#ifdef __powerpc64__
return ppc64_caches.l1d.block_size;
#else
return L1_CACHE_BYTES;
#endif
}
void wp_get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr,
int *type, int *size, unsigned long *ea)
{
@ -147,14 +138,14 @@ void wp_get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr,
analyse_instr(&op, regs, *instr);
*type = GETTYPE(op.type);
*ea = op.ea;
#ifdef __powerpc64__
if (!(regs->msr & MSR_64BIT))
*ea &= 0xffffffffUL;
#endif
*size = GETSIZE(op.type);
if (*type == CACHEOP) {
*size = cache_op_size();
*size = l1_dcache_bytes();
*ea &= ~(*size - 1);
} else if (*type == LOAD_VMX || *type == STORE_VMX) {
*ea &= ~(*size - 1);

View File

@ -266,7 +266,7 @@ static void check_return_regs_valid(struct pt_regs *regs)
if (trap_is_scv(regs))
return;
trap = regs->trap;
trap = TRAP(regs);
// EE in HV mode sets HSRRs like 0xea0
if (cpu_has_feature(CPU_FTR_HVMODE) && trap == INTERRUPT_EXTERNAL)
trap = 0xea0;

View File

@ -278,9 +278,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "clock\t\t: %lu.%06luMHz\n",
proc_freq / 1000000, proc_freq % 1000000);
if (ppc_md.show_percpuinfo != NULL)
ppc_md.show_percpuinfo(m, cpu_id);
/* If we are a Freescale core do a simple check so
* we dont have to keep adding cases in the future */
if (PVR_VER(pvr) & 0x8000) {

View File

@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/memory.h>
#include <linux/static_call.h>
#include <asm/code-patching.h>
void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
{
int err;
bool is_ret0 = (func == __static_call_return0);
unsigned long target = (unsigned long)(is_ret0 ? tramp + PPC_SCT_RET0 : func);
bool is_short = is_offset_in_branch_range((long)target - (long)tramp);
if (!tramp)
return;
mutex_lock(&text_mutex);
if (func && !is_short) {
err = patch_instruction(tramp + PPC_SCT_DATA, ppc_inst(target));
if (err)
goto out;
}
if (!func)
err = patch_instruction(tramp, ppc_inst(PPC_RAW_BLR()));
else if (is_short)
err = patch_branch(tramp, target, 0);
else
err = patch_instruction(tramp, ppc_inst(PPC_RAW_NOP()));
out:
mutex_unlock(&text_mutex);
if (err)
panic("%s: patching failed %pS at %pS\n", __func__, func, tramp);
}
EXPORT_SYMBOL_GPL(arch_static_call_transform);

View File

@ -17,8 +17,3 @@ void do_after_copyback(void)
touch_softlockup_watchdog();
mb();
}
void _iommu_save(void)
{
iommu_save();
}

View File

@ -128,7 +128,6 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
* stack pointer on the stack like a real stackframe */
addi r1,r1,-128
bl _iommu_save
bl swsusp_save
/* restore LR */

View File

@ -928,7 +928,8 @@ static int unregister_cpu_online(unsigned int cpu)
struct device_attribute *attrs, *pmc_attrs;
int i, nattrs;
BUG_ON(!c->hotpluggable);
if (WARN_RATELIMIT(!c->hotpluggable, "cpu %d can't be offlined\n", cpu))
return -EBUSY;
#ifdef CONFIG_PPC64
if (cpu_has_feature(CPU_FTR_SMT))

View File

@ -631,8 +631,12 @@ void timer_broadcast_interrupt(void)
#endif
#ifdef CONFIG_SUSPEND
static void generic_suspend_disable_irqs(void)
/* Overrides the weak version in kernel/power/main.c */
void arch_suspend_disable_irqs(void)
{
if (ppc_md.suspend_disable_irqs)
ppc_md.suspend_disable_irqs();
/* Disable the decrementer, so that it doesn't interfere
* with suspending.
*/
@ -642,23 +646,11 @@ static void generic_suspend_disable_irqs(void)
set_dec(decrementer_max);
}
static void generic_suspend_enable_irqs(void)
{
local_irq_enable();
}
/* Overrides the weak version in kernel/power/main.c */
void arch_suspend_disable_irqs(void)
{
if (ppc_md.suspend_disable_irqs)
ppc_md.suspend_disable_irqs();
generic_suspend_disable_irqs();
}
/* Overrides the weak version in kernel/power/main.c */
void arch_suspend_enable_irqs(void)
{
generic_suspend_enable_irqs();
local_irq_enable();
if (ppc_md.suspend_enable_irqs)
ppc_md.suspend_enable_irqs();
}

View File

@ -143,6 +143,12 @@ SECTIONS
SOFT_MASK_TABLE(8)
RESTART_TABLE(8)
.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
__start_opd = .;
KEEP(*(.opd))
__end_opd = .;
}
. = ALIGN(8);
__stf_entry_barrier_fixup : AT(ADDR(__stf_entry_barrier_fixup) - LOAD_OFFSET) {
__start___stf_entry_barrier_fixup = .;
@ -339,12 +345,6 @@ SECTIONS
*(.branch_lt)
}
.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
__start_opd = .;
KEEP(*(.opd))
__end_opd = .;
}
. = ALIGN(256);
.got : AT(ADDR(.got) - LOAD_OFFSET) {
__toc_start = .;

View File

@ -48,19 +48,6 @@ void machine_crash_shutdown(struct pt_regs *regs)
default_machine_crash_shutdown(regs);
}
/*
* Do what every setup is needed on image and the
* reboot code buffer to allow us to avoid allocations
* later.
*/
int machine_kexec_prepare(struct kimage *image)
{
if (ppc_md.machine_kexec_prepare)
return ppc_md.machine_kexec_prepare(image);
else
return default_machine_kexec_prepare(image);
}
void machine_kexec_cleanup(struct kimage *image)
{
}

View File

@ -63,7 +63,7 @@ void default_machine_kexec(struct kimage *image)
(*rnk)(page_list, reboot_code_buffer_phys, image->start);
}
int default_machine_kexec_prepare(struct kimage *image)
int machine_kexec_prepare(struct kimage *image)
{
return 0;
}

View File

@ -32,7 +32,7 @@
#include <asm/svm.h>
#include <asm/ultravisor.h>
int default_machine_kexec_prepare(struct kimage *image)
int machine_kexec_prepare(struct kimage *image)
{
int i;
unsigned long begin, end; /* limits of segment */

View File

@ -700,6 +700,7 @@ static int update_usable_mem_fdt(void *fdt, struct crash_mem *usable_mem)
if (ret) {
pr_err("Failed to set linux,usable-memory property for %s node",
dn->full_name);
of_node_put(dn);
goto out;
}
}

View File

@ -3726,7 +3726,20 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
kvmppc_set_host_core(pcpu);
guest_exit_irqoff();
context_tracking_guest_exit();
if (!vtime_accounting_enabled_this_cpu()) {
local_irq_enable();
/*
* Service IRQs here before vtime_account_guest_exit() so any
* ticks that occurred while running the guest are accounted to
* the guest. If vtime accounting is enabled, accounting uses
* TB rather than ticks, so it can be done without enabling
* interrupts here, which has the problem that it accounts
* interrupt processing overhead to the host.
*/
local_irq_disable();
}
vtime_account_guest_exit();
local_irq_enable();
@ -4510,7 +4523,20 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
kvmppc_set_host_core(pcpu);
guest_exit_irqoff();
context_tracking_guest_exit();
if (!vtime_accounting_enabled_this_cpu()) {
local_irq_enable();
/*
* Service IRQs here before vtime_account_guest_exit() so any
* ticks that occurred while running the guest are accounted to
* the guest. If vtime accounting is enabled, accounting uses
* TB rather than ticks, so it can be done without enabling
* interrupts here, which has the problem that it accounts
* interrupt processing overhead to the host.
*/
local_irq_disable();
}
vtime_account_guest_exit();
local_irq_enable();

View File

@ -207,6 +207,15 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
if (kvm_is_radix(kvm))
return H_FUNCTION;
/*
* The HPTE gets used by compute_tlbie_rb() to set TLBIE bits, so
* these functions should work together -- must ensure a guest can not
* cause problems with the TLBIE that KVM executes.
*/
if ((pteh >> HPTE_V_SSIZE_SHIFT) & 0x2) {
/* B=0b1x is a reserved value, disallow it. */
return H_PARAMETER;
}
psize = kvmppc_actual_pgsz(pteh, ptel);
if (!psize)
return H_PARAMETER;

View File

@ -1042,7 +1042,21 @@ int kvmppc_handle_exit(struct kvm_vcpu *vcpu, unsigned int exit_nr)
}
trace_kvm_exit(exit_nr, vcpu);
guest_exit_irqoff();
context_tracking_guest_exit();
if (!vtime_accounting_enabled_this_cpu()) {
local_irq_enable();
/*
* Service IRQs here before vtime_account_guest_exit() so any
* ticks that occurred while running the guest are accounted to
* the guest. If vtime accounting is enabled, accounting uses
* TB rather than ticks, so it can be done without enabling
* interrupts here, which has the problem that it accounts
* interrupt processing overhead to the host.
*/
local_irq_disable();
}
vtime_account_guest_exit();
local_irq_enable();

View File

@ -1094,7 +1094,7 @@ static inline u64 sp_to_dp(u32 fprs)
preempt_disable();
enable_kernel_fp();
asm ("lfs%U1%X1 0,%1; stfd%U0%X0 0,%0" : "=m"UPD_CONSTR (fprd) : "m"UPD_CONSTR (fprs)
asm ("lfs%U1%X1 0,%1; stfd%U0%X0 0,%0" : "=m<>" (fprd) : "m<>" (fprs)
: "fr0");
preempt_enable();
return fprd;
@ -1106,7 +1106,7 @@ static inline u32 dp_to_sp(u64 fprd)
preempt_disable();
enable_kernel_fp();
asm ("lfd%U1%X1 0,%1; stfs%U0%X0 0,%0" : "=m"UPD_CONSTR (fprs) : "m"UPD_CONSTR (fprd)
asm ("lfd%U1%X1 0,%1; stfs%U0%X0 0,%0" : "=m<>" (fprs) : "m<>" (fprd)
: "fr0");
preempt_enable();
return fprs;

View File

@ -228,6 +228,7 @@ static void do_stf_exit_barrier_fixups(enum stf_barrier_type types)
static bool stf_exit_reentrant = false;
static bool rfi_exit_reentrant = false;
static DEFINE_MUTEX(exit_flush_lock);
static int __do_stf_barrier_fixups(void *data)
{
@ -253,6 +254,9 @@ void do_stf_barrier_fixups(enum stf_barrier_type types)
* low level interrupt exit code before patching. After the patching,
* if allowed, then flip the branch to allow fast exits.
*/
// Prevent static key update races with do_rfi_flush_fixups()
mutex_lock(&exit_flush_lock);
static_branch_enable(&interrupt_exit_not_reentrant);
stop_machine(__do_stf_barrier_fixups, &types, NULL);
@ -264,6 +268,8 @@ void do_stf_barrier_fixups(enum stf_barrier_type types)
if (stf_exit_reentrant && rfi_exit_reentrant)
static_branch_disable(&interrupt_exit_not_reentrant);
mutex_unlock(&exit_flush_lock);
}
void do_uaccess_flush_fixups(enum l1d_flush_type types)
@ -486,6 +492,9 @@ void do_rfi_flush_fixups(enum l1d_flush_type types)
* without stop_machine, so this could be achieved with a broadcast
* IPI instead, but this matches the stf sequence.
*/
// Prevent static key update races with do_stf_barrier_fixups()
mutex_lock(&exit_flush_lock);
static_branch_enable(&interrupt_exit_not_reentrant);
stop_machine(__do_rfi_flush_fixups, &types, NULL);
@ -497,6 +506,8 @@ void do_rfi_flush_fixups(enum l1d_flush_type types)
if (stf_exit_reentrant && rfi_exit_reentrant)
static_branch_disable(&interrupt_exit_not_reentrant);
mutex_unlock(&exit_flush_lock);
}
void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end)

View File

@ -302,33 +302,51 @@ static nokprobe_inline void do_byte_reverse(void *ptr, int nb)
}
}
static nokprobe_inline int read_mem_aligned(unsigned long *dest,
unsigned long ea, int nb,
struct pt_regs *regs)
static __always_inline int
__read_mem_aligned(unsigned long *dest, unsigned long ea, int nb, struct pt_regs *regs)
{
int err = 0;
unsigned long x = 0;
switch (nb) {
case 1:
err = __get_user(x, (unsigned char __user *) ea);
unsafe_get_user(x, (unsigned char __user *)ea, Efault);
break;
case 2:
err = __get_user(x, (unsigned short __user *) ea);
unsafe_get_user(x, (unsigned short __user *)ea, Efault);
break;
case 4:
err = __get_user(x, (unsigned int __user *) ea);
unsafe_get_user(x, (unsigned int __user *)ea, Efault);
break;
#ifdef __powerpc64__
case 8:
err = __get_user(x, (unsigned long __user *) ea);
unsafe_get_user(x, (unsigned long __user *)ea, Efault);
break;
#endif
}
if (!err)
*dest = x;
else
*dest = x;
return 0;
Efault:
regs->dar = ea;
return -EFAULT;
}
static nokprobe_inline int
read_mem_aligned(unsigned long *dest, unsigned long ea, int nb, struct pt_regs *regs)
{
int err;
if (is_kernel_addr(ea))
return __read_mem_aligned(dest, ea, nb, regs);
if (user_read_access_begin((void __user *)ea, nb)) {
err = __read_mem_aligned(dest, ea, nb, regs);
user_read_access_end();
} else {
err = -EFAULT;
regs->dar = ea;
}
return err;
}
@ -336,10 +354,8 @@ static nokprobe_inline int read_mem_aligned(unsigned long *dest,
* Copy from userspace to a buffer, using the largest possible
* aligned accesses, up to sizeof(long).
*/
static nokprobe_inline int copy_mem_in(u8 *dest, unsigned long ea, int nb,
struct pt_regs *regs)
static __always_inline int __copy_mem_in(u8 *dest, unsigned long ea, int nb, struct pt_regs *regs)
{
int err = 0;
int c;
for (; nb > 0; nb -= c) {
@ -348,31 +364,46 @@ static nokprobe_inline int copy_mem_in(u8 *dest, unsigned long ea, int nb,
c = max_align(nb);
switch (c) {
case 1:
err = __get_user(*dest, (unsigned char __user *) ea);
unsafe_get_user(*dest, (u8 __user *)ea, Efault);
break;
case 2:
err = __get_user(*(u16 *)dest,
(unsigned short __user *) ea);
unsafe_get_user(*(u16 *)dest, (u16 __user *)ea, Efault);
break;
case 4:
err = __get_user(*(u32 *)dest,
(unsigned int __user *) ea);
unsafe_get_user(*(u32 *)dest, (u32 __user *)ea, Efault);
break;
#ifdef __powerpc64__
case 8:
err = __get_user(*(unsigned long *)dest,
(unsigned long __user *) ea);
unsafe_get_user(*(u64 *)dest, (u64 __user *)ea, Efault);
break;
#endif
}
if (err) {
regs->dar = ea;
return err;
}
dest += c;
ea += c;
}
return 0;
Efault:
regs->dar = ea;
return -EFAULT;
}
static nokprobe_inline int copy_mem_in(u8 *dest, unsigned long ea, int nb, struct pt_regs *regs)
{
int err;
if (is_kernel_addr(ea))
return __copy_mem_in(dest, ea, nb, regs);
if (user_read_access_begin((void __user *)ea, nb)) {
err = __copy_mem_in(dest, ea, nb, regs);
user_read_access_end();
} else {
err = -EFAULT;
regs->dar = ea;
}
return err;
}
static nokprobe_inline int read_mem_unaligned(unsigned long *dest,
@ -410,30 +441,48 @@ static int read_mem(unsigned long *dest, unsigned long ea, int nb,
}
NOKPROBE_SYMBOL(read_mem);
static nokprobe_inline int write_mem_aligned(unsigned long val,
unsigned long ea, int nb,
struct pt_regs *regs)
static __always_inline int
__write_mem_aligned(unsigned long val, unsigned long ea, int nb, struct pt_regs *regs)
{
int err = 0;
switch (nb) {
case 1:
err = __put_user(val, (unsigned char __user *) ea);
unsafe_put_user(val, (unsigned char __user *)ea, Efault);
break;
case 2:
err = __put_user(val, (unsigned short __user *) ea);
unsafe_put_user(val, (unsigned short __user *)ea, Efault);
break;
case 4:
err = __put_user(val, (unsigned int __user *) ea);
unsafe_put_user(val, (unsigned int __user *)ea, Efault);
break;
#ifdef __powerpc64__
case 8:
err = __put_user(val, (unsigned long __user *) ea);
unsafe_put_user(val, (unsigned long __user *)ea, Efault);
break;
#endif
}
if (err)
return 0;
Efault:
regs->dar = ea;
return -EFAULT;
}
static nokprobe_inline int
write_mem_aligned(unsigned long val, unsigned long ea, int nb, struct pt_regs *regs)
{
int err;
if (is_kernel_addr(ea))
return __write_mem_aligned(val, ea, nb, regs);
if (user_write_access_begin((void __user *)ea, nb)) {
err = __write_mem_aligned(val, ea, nb, regs);
user_write_access_end();
} else {
err = -EFAULT;
regs->dar = ea;
}
return err;
}
@ -441,10 +490,8 @@ static nokprobe_inline int write_mem_aligned(unsigned long val,
* Copy from a buffer to userspace, using the largest possible
* aligned accesses, up to sizeof(long).
*/
static nokprobe_inline int copy_mem_out(u8 *dest, unsigned long ea, int nb,
struct pt_regs *regs)
static nokprobe_inline int __copy_mem_out(u8 *dest, unsigned long ea, int nb, struct pt_regs *regs)
{
int err = 0;
int c;
for (; nb > 0; nb -= c) {
@ -453,31 +500,46 @@ static nokprobe_inline int copy_mem_out(u8 *dest, unsigned long ea, int nb,
c = max_align(nb);
switch (c) {
case 1:
err = __put_user(*dest, (unsigned char __user *) ea);
unsafe_put_user(*dest, (u8 __user *)ea, Efault);
break;
case 2:
err = __put_user(*(u16 *)dest,
(unsigned short __user *) ea);
unsafe_put_user(*(u16 *)dest, (u16 __user *)ea, Efault);
break;
case 4:
err = __put_user(*(u32 *)dest,
(unsigned int __user *) ea);
unsafe_put_user(*(u32 *)dest, (u32 __user *)ea, Efault);
break;
#ifdef __powerpc64__
case 8:
err = __put_user(*(unsigned long *)dest,
(unsigned long __user *) ea);
unsafe_put_user(*(u64 *)dest, (u64 __user *)ea, Efault);
break;
#endif
}
if (err) {
regs->dar = ea;
return err;
}
dest += c;
ea += c;
}
return 0;
Efault:
regs->dar = ea;
return -EFAULT;
}
static nokprobe_inline int copy_mem_out(u8 *dest, unsigned long ea, int nb, struct pt_regs *regs)
{
int err;
if (is_kernel_addr(ea))
return __copy_mem_out(dest, ea, nb, regs);
if (user_write_access_begin((void __user *)ea, nb)) {
err = __copy_mem_out(dest, ea, nb, regs);
user_write_access_end();
} else {
err = -EFAULT;
regs->dar = ea;
}
return err;
}
static nokprobe_inline int write_mem_unaligned(unsigned long val,
@ -986,10 +1048,24 @@ static nokprobe_inline int do_vsx_store(struct instruction_op *op,
}
#endif /* CONFIG_VSX */
static int __emulate_dcbz(unsigned long ea)
{
unsigned long i;
unsigned long size = l1_dcache_bytes();
for (i = 0; i < size; i += sizeof(long))
unsafe_put_user(0, (unsigned long __user *)(ea + i), Efault);
return 0;
Efault:
return -EFAULT;
}
int emulate_dcbz(unsigned long ea, struct pt_regs *regs)
{
int err;
unsigned long i, size;
unsigned long size;
#ifdef __powerpc64__
size = ppc64_caches.l1d.block_size;
@ -1001,14 +1077,21 @@ int emulate_dcbz(unsigned long ea, struct pt_regs *regs)
ea &= ~(size - 1);
if (!address_ok(regs, ea, size))
return -EFAULT;
for (i = 0; i < size; i += sizeof(long)) {
err = __put_user(0, (unsigned long __user *) (ea + i));
if (err) {
regs->dar = ea;
return err;
}
if (is_kernel_addr(ea)) {
err = __emulate_dcbz(ea);
} else if (user_write_access_begin((void __user *)ea, size)) {
err = __emulate_dcbz(ea);
user_write_access_end();
} else {
err = -EFAULT;
}
return 0;
if (err)
regs->dar = ea;
return err;
}
NOKPROBE_SYMBOL(emulate_dcbz);

View File

@ -1988,7 +1988,7 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi)
mmu_kernel_ssize, 0);
}
void __kernel_map_pages(struct page *page, int numpages, int enable)
void hash__kernel_map_pages(struct page *page, int numpages, int enable)
{
unsigned long flags, vaddr, lmi;
int i;

View File

@ -920,6 +920,13 @@ void __meminit radix__vmemmap_remove_mapping(unsigned long start, unsigned long
#endif
#endif
#ifdef CONFIG_DEBUG_PAGEALLOC
void radix__kernel_map_pages(struct page *page, int numpages, int enable)
{
pr_warn_once("DEBUG_PAGEALLOC not supported in radix mode\n");
}
#endif
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
unsigned long radix__pmd_hugepage_update(struct mm_struct *mm, unsigned long addr,

View File

@ -20,8 +20,8 @@
#include <asm/machdep.h>
#include <asm/rtas.h>
#include <asm/kasan.h>
#include <asm/sparsemem.h>
#include <asm/svm.h>
#include <asm/mmzone.h>
#include <mm/mmu_decl.h>
@ -256,7 +256,7 @@ void __init mem_init(void)
#endif
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
set_max_mapnr(max_pfn);
set_max_mapnr(max_low_pfn);
kasan_late_init();

View File

@ -126,7 +126,7 @@ unsigned long mmu_mapin_ram(unsigned long base, unsigned long top);
#ifdef CONFIG_PPC_FSL_BOOK3E
extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx,
bool dryrun);
bool dryrun, bool init);
extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
phys_addr_t phys);
#ifdef CONFIG_PPC32
@ -168,7 +168,7 @@ static inline phys_addr_t v_block_mapped(unsigned long va) { return 0; }
static inline unsigned long p_block_mapped(phys_addr_t pa) { return 0; }
#endif
#if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_8xx)
#if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_8xx) || defined(CONFIG_PPC_FSL_BOOK3E)
void mmu_mark_initmem_nx(void);
void mmu_mark_rodata_ro(void);
#else

View File

@ -7,7 +7,7 @@ obj-$(CONFIG_PPC_BOOK3E_64) += tlb_low_64e.o book3e_pgtable.o
obj-$(CONFIG_40x) += 40x.o
obj-$(CONFIG_44x) += 44x.o
obj-$(CONFIG_PPC_8xx) += 8xx.o
obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke.o
obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_book3e.o
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr_booke.o
ifdef CONFIG_HUGETLB_PAGE
obj-$(CONFIG_PPC_FSL_BOOK3E) += book3e_hugetlbpage.o
@ -16,4 +16,4 @@ endif
# Disable kcov instrumentation on sensitive code
# This is necessary for booting with kcov enabled on book3e machines
KCOV_INSTRUMENT_tlb.o := n
KCOV_INSTRUMENT_fsl_booke.o := n
KCOV_INSTRUMENT_fsl_book3e.o := n

View File

@ -122,15 +122,18 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
TLBCAM[index].MAS2 |= (flags & _PAGE_GUARDED) ? MAS2_G : 0;
TLBCAM[index].MAS2 |= (flags & _PAGE_ENDIAN) ? MAS2_E : 0;
TLBCAM[index].MAS3 = (phys & MAS3_RPN) | MAS3_SX | MAS3_SR;
TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
TLBCAM[index].MAS3 = (phys & MAS3_RPN) | MAS3_SR;
TLBCAM[index].MAS3 |= (flags & _PAGE_RW) ? MAS3_SW : 0;
if (mmu_has_feature(MMU_FTR_BIG_PHYS))
TLBCAM[index].MAS7 = (u64)phys >> 32;
/* Below is unlikely -- only for large user pages or similar */
if (pte_user(__pte(flags))) {
TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
TLBCAM[index].MAS3 |= MAS3_UR;
TLBCAM[index].MAS3 |= (flags & _PAGE_EXEC) ? MAS3_UX : 0;
TLBCAM[index].MAS3 |= (flags & _PAGE_RW) ? MAS3_UW : 0;
} else {
TLBCAM[index].MAS3 |= (flags & _PAGE_EXEC) ? MAS3_SX : 0;
}
tlbcam_addrs[index].start = virt;
@ -165,19 +168,38 @@ unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
unsigned long ram, int max_cam_idx,
bool dryrun)
bool dryrun, bool init)
{
int i;
unsigned long amount_mapped = 0;
unsigned long boundary;
if (strict_kernel_rwx_enabled())
boundary = (unsigned long)(_sinittext - _stext);
else
boundary = ram;
/* Calculate CAM values */
for (i = 0; ram && i < max_cam_idx; i++) {
for (i = 0; boundary && i < max_cam_idx; i++) {
unsigned long cam_sz;
pgprot_t prot = init ? PAGE_KERNEL_X : PAGE_KERNEL_ROX;
cam_sz = calc_cam_sz(boundary, virt, phys);
if (!dryrun)
settlbcam(i, virt, phys, cam_sz, pgprot_val(prot), 0);
boundary -= cam_sz;
amount_mapped += cam_sz;
virt += cam_sz;
phys += cam_sz;
}
for (ram -= amount_mapped; ram && i < max_cam_idx; i++) {
unsigned long cam_sz;
pgprot_t prot = init ? PAGE_KERNEL_X : PAGE_KERNEL;
cam_sz = calc_cam_sz(ram, virt, phys);
if (!dryrun)
settlbcam(i, virt, phys, cam_sz,
pgprot_val(PAGE_KERNEL_X), 0);
settlbcam(i, virt, phys, cam_sz, pgprot_val(prot), 0);
ram -= cam_sz;
amount_mapped += cam_sz;
@ -188,8 +210,13 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
if (dryrun)
return amount_mapped;
loadcam_multi(0, i, max_cam_idx);
tlbcam_index = i;
if (init) {
loadcam_multi(0, i, max_cam_idx);
tlbcam_index = i;
} else {
loadcam_multi(0, i, 0);
WARN_ON(i > tlbcam_index);
}
#ifdef CONFIG_PPC64
get_paca()->tcd.esel_next = i;
@ -200,12 +227,12 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
return amount_mapped;
}
unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, bool dryrun)
unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, bool dryrun, bool init)
{
unsigned long virt = PAGE_OFFSET;
phys_addr_t phys = memstart_addr;
return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx, dryrun);
return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx, dryrun, init);
}
#ifdef CONFIG_PPC32
@ -246,7 +273,7 @@ void __init adjust_total_lowmem(void)
ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
i = switch_to_as1();
__max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, false);
__max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, false, true);
restore_to_as0(i, 0, 0, 1);
pr_info("Memory CAM mapping: ");
@ -258,6 +285,25 @@ void __init adjust_total_lowmem(void)
memblock_set_current_limit(memstart_addr + __max_low_memory);
}
#ifdef CONFIG_STRICT_KERNEL_RWX
void mmu_mark_rodata_ro(void)
{
/* Everything is done in mmu_mark_initmem_nx() */
}
#endif
void mmu_mark_initmem_nx(void)
{
unsigned long remapped;
if (!strict_kernel_rwx_enabled())
return;
remapped = map_mem_in_cams(__max_low_memory, CONFIG_LOWMEM_CAM_NUM, false, false);
WARN_ON(__max_low_memory != remapped);
}
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
phys_addr_t first_memblock_size)
{
@ -317,11 +363,11 @@ notrace void __init relocate_init(u64 dt_ptr, phys_addr_t start)
/* map a 64M area for the second relocation */
if (memstart_addr > start)
map_mem_in_cams(0x4000000, CONFIG_LOWMEM_CAM_NUM,
false);
false, true);
else
map_mem_in_cams_addr(start, PAGE_OFFSET + offset,
0x4000000, CONFIG_LOWMEM_CAM_NUM,
false);
false, true);
restore_to_as0(n, offset, __va(dt_ptr), 1);
/* We should never reach here */
panic("Relocation error");

View File

@ -314,7 +314,7 @@ static unsigned long __init kaslr_choose_location(void *dt_ptr, phys_addr_t size
pr_warn("KASLR: No safe seed for randomizing the kernel base.\n");
ram = min_t(phys_addr_t, __max_low_memory, size);
ram = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, true);
ram = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, true, false);
linear_sz = min_t(unsigned long, ram, SZ_512M);
/* If the linear size is smaller than 64M, do not randmize */

View File

@ -185,6 +185,7 @@ EXPORT_PER_CPU_SYMBOL(next_tlbcam_idx);
* processor
*/
#ifndef CONFIG_PPC_8xx
/*
* These are the base non-SMP variants of page and mm flushing
*/
@ -218,6 +219,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
mmu_get_tsize(mmu_virtual_psize), 0);
}
EXPORT_SYMBOL(local_flush_tlb_page);
#endif
/*
* And here are the SMP non-local implementations
@ -643,7 +645,7 @@ static void early_init_this_mmu(void)
if (map)
linear_map_top = map_mem_in_cams(linear_map_top,
num_cams, false);
num_cams, true, true);
}
#endif
@ -764,7 +766,7 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
linear_sz = map_mem_in_cams(first_memblock_size, num_cams,
true);
false, true);
ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
} else

View File

@ -369,7 +369,7 @@ _GLOBAL(_tlbivax_bcast)
* extern void loadcam_entry(unsigned int index)
*
* Load TLBCAM[index] entry in to the L2 CAM MMU
* Must preserve r7, r8, r9, r10 and r11
* Must preserve r7, r8, r9, r10, r11, r12
*/
_GLOBAL(loadcam_entry)
mflr r5
@ -401,7 +401,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
*
* r3 = first entry to write
* r4 = number of entries to write
* r5 = temporary tlb entry
* r5 = temporary tlb entry (0 means no switch to AS1)
*/
_GLOBAL(loadcam_multi)
mflr r8
@ -409,6 +409,8 @@ _GLOBAL(loadcam_multi)
mfmsr r11
andi. r11,r11,MSR_IS
bne 10f
mr. r12, r5
beq 10f
/*
* Set up temporary TLB entry that is the same as what we're
@ -446,6 +448,8 @@ _GLOBAL(loadcam_multi)
/* Don't return to AS=0 if we were in AS=1 at function start */
andi. r11,r11,MSR_IS
bne 3f
cmpwi r12, 0
beq 3f
/* Return to AS=0 and clear the temporary entry */
mfmsr r6

View File

@ -222,7 +222,7 @@ tlb_miss_kernel_bolted:
tlb_miss_fault_bolted:
/* We need to check if it was an instruction miss */
andi. r10,r11,_PAGE_EXEC|_PAGE_BAP_SX
andi. r10,r11,_PAGE_BAP_UX|_PAGE_BAP_SX
bne itlb_miss_fault_bolted
dtlb_miss_fault_bolted:
tlb_epilog_bolted
@ -239,7 +239,7 @@ itlb_miss_fault_bolted:
srdi r15,r16,60 /* get region */
bne- itlb_miss_fault_bolted
li r11,_PAGE_PRESENT|_PAGE_EXEC /* Base perm */
li r11,_PAGE_PRESENT|_PAGE_BAP_UX /* Base perm */
/* We do the user/kernel test for the PID here along with the RW test
*/
@ -614,7 +614,7 @@ itlb_miss_fault_e6500:
/* We do the user/kernel test for the PID here along with the RW test
*/
li r11,_PAGE_PRESENT|_PAGE_EXEC /* Base perm */
li r11,_PAGE_PRESENT|_PAGE_BAP_UX /* Base perm */
oris r11,r11,_PAGE_ACCESSED@h
cmpldi cr0,r15,0 /* Check for user region */
@ -734,7 +734,7 @@ normal_tlb_miss_done:
normal_tlb_miss_access_fault:
/* We need to check if it was an instruction miss */
andi. r10,r11,_PAGE_EXEC
andi. r10,r11,_PAGE_BAP_UX
bne 1f
ld r14,EX_TLB_DEAR(r12)
ld r15,EX_TLB_ESR(r12)

View File

@ -271,7 +271,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_
{
pmd_t *pmd = pmd_off(mm, addr);
pte_basic_t val;
pte_basic_t *entry = &ptep->pte;
pte_basic_t *entry = (pte_basic_t *)ptep;
int num, i;
/*

View File

@ -173,7 +173,7 @@ void mark_rodata_ro(void)
}
#endif
#ifdef CONFIG_DEBUG_PAGEALLOC
#if defined(CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC) && defined(CONFIG_DEBUG_PAGEALLOC)
void __kernel_map_pages(struct page *page, int numpages, int enable)
{
unsigned long addr = (unsigned long)page_address(page);

View File

@ -241,8 +241,8 @@ skip_codegen_passes:
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_jit_binary_lock_ro(bpf_hdr);
bpf_prog_fill_jited_linfo(fp, addrs);
out_addrs:
kfree(addrs);

View File

@ -90,7 +90,11 @@ static u64 get_ext_regs_value(int idx)
return mfspr(SPRN_SIER2);
case PERF_REG_POWERPC_SIER3:
return mfspr(SPRN_SIER3);
case PERF_REG_POWERPC_SDAR:
return mfspr(SPRN_SDAR);
#endif
case PERF_REG_POWERPC_SIAR:
return mfspr(SPRN_SIAR);
default: return 0;
}
}

View File

@ -9,10 +9,10 @@
/*
* Power10 event codes.
*/
EVENT(PM_RUN_CYC, 0x600f4);
EVENT(PM_CYC, 0x600f4);
EVENT(PM_DISP_STALL_CYC, 0x100f8);
EVENT(PM_EXEC_STALL, 0x30008);
EVENT(PM_RUN_INST_CMPL, 0x500fa);
EVENT(PM_INST_CMPL, 0x500fa);
EVENT(PM_BR_CMPL, 0x4d05e);
EVENT(PM_BR_MPRED_CMPL, 0x400f6);
EVENT(PM_BR_FIN, 0x2f04a);
@ -50,8 +50,8 @@ EVENT(PM_DTLB_MISS, 0x300fc);
/* ITLB Reloaded */
EVENT(PM_ITLB_MISS, 0x400fc);
EVENT(PM_RUN_CYC_ALT, 0x0001e);
EVENT(PM_RUN_INST_CMPL_ALT, 0x00002);
EVENT(PM_CYC_ALT, 0x0001e);
EVENT(PM_INST_CMPL_ALT, 0x00002);
/*
* Memory Access Events

View File

@ -91,8 +91,8 @@ extern u64 PERF_REG_EXTENDED_MASK;
/* Table of alternatives, sorted by column 0 */
static const unsigned int power10_event_alternatives[][MAX_ALT] = {
{ PM_RUN_CYC_ALT, PM_RUN_CYC },
{ PM_RUN_INST_CMPL_ALT, PM_RUN_INST_CMPL },
{ PM_CYC_ALT, PM_CYC },
{ PM_INST_CMPL_ALT, PM_INST_CMPL },
};
static int power10_get_alternatives(u64 event, unsigned int flags, u64 alt[])
@ -118,8 +118,8 @@ static int power10_check_attr_config(struct perf_event *ev)
return 0;
}
GENERIC_EVENT_ATTR(cpu-cycles, PM_RUN_CYC);
GENERIC_EVENT_ATTR(instructions, PM_RUN_INST_CMPL);
GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC);
GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL);
GENERIC_EVENT_ATTR(branch-instructions, PM_BR_CMPL);
GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL);
GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1);
@ -148,8 +148,8 @@ CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS);
CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS);
static struct attribute *power10_events_attr_dd1[] = {
GENERIC_EVENT_PTR(PM_RUN_CYC),
GENERIC_EVENT_PTR(PM_RUN_INST_CMPL),
GENERIC_EVENT_PTR(PM_CYC),
GENERIC_EVENT_PTR(PM_INST_CMPL),
GENERIC_EVENT_PTR(PM_BR_CMPL),
GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL),
GENERIC_EVENT_PTR(PM_LD_REF_L1),
@ -173,8 +173,8 @@ static struct attribute *power10_events_attr_dd1[] = {
};
static struct attribute *power10_events_attr[] = {
GENERIC_EVENT_PTR(PM_RUN_CYC),
GENERIC_EVENT_PTR(PM_RUN_INST_CMPL),
GENERIC_EVENT_PTR(PM_CYC),
GENERIC_EVENT_PTR(PM_INST_CMPL),
GENERIC_EVENT_PTR(PM_BR_FIN),
GENERIC_EVENT_PTR(PM_MPRED_BR_FIN),
GENERIC_EVENT_PTR(PM_LD_REF_L1),
@ -271,8 +271,8 @@ static const struct attribute_group *power10_pmu_attr_groups[] = {
};
static int power10_generic_events_dd1[] = {
[PERF_COUNT_HW_CPU_CYCLES] = PM_RUN_CYC,
[PERF_COUNT_HW_INSTRUCTIONS] = PM_RUN_INST_CMPL,
[PERF_COUNT_HW_CPU_CYCLES] = PM_CYC,
[PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL,
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_CMPL,
[PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL,
[PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1,
@ -280,8 +280,8 @@ static int power10_generic_events_dd1[] = {
};
static int power10_generic_events[] = {
[PERF_COUNT_HW_CPU_CYCLES] = PM_RUN_CYC,
[PERF_COUNT_HW_INSTRUCTIONS] = PM_RUN_INST_CMPL,
[PERF_COUNT_HW_CPU_CYCLES] = PM_CYC,
[PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL,
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_FIN,
[PERF_COUNT_HW_BRANCH_MISSES] = PM_MPRED_BR_FIN,
[PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1,
@ -548,6 +548,24 @@ static u64 power10_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
#undef C
/*
* Set the MMCR0[CC56RUN] bit to enable counting for
* PMC5 and PMC6 regardless of the state of CTRL[RUN],
* so that we can use counters 5 and 6 as PM_INST_CMPL and
* PM_CYC.
*/
static int power10_compute_mmcr(u64 event[], int n_ev,
unsigned int hwc[], struct mmcr_regs *mmcr,
struct perf_event *pevents[], u32 flags)
{
int ret;
ret = isa207_compute_mmcr(event, n_ev, hwc, mmcr, pevents, flags);
if (!ret)
mmcr->mmcr0 |= MMCR0_C56RUN;
return ret;
}
static struct power_pmu power10_pmu = {
.name = "POWER10",
.n_counter = MAX_PMU_COUNTERS,
@ -555,7 +573,7 @@ static struct power_pmu power10_pmu = {
.test_adder = ISA207_TEST_ADDER,
.group_constraint_mask = CNST_CACHE_PMC4_MASK,
.group_constraint_val = CNST_CACHE_PMC4_VAL,
.compute_mmcr = isa207_compute_mmcr,
.compute_mmcr = power10_compute_mmcr,
.config_bhrb = power10_config_bhrb,
.bhrb_filter_map = power10_bhrb_filter_map,
.get_constraint = isa207_get_constraint,

View File

@ -208,6 +208,7 @@ static void node_irq_request(const char *compat, irq_handler_t errirq_handler)
if (irq == NO_IRQ) {
pr_err("device tree node %pOFn is missing a interrupt",
np);
of_node_put(np);
return;
}
@ -215,6 +216,7 @@ static void node_irq_request(const char *compat, irq_handler_t errirq_handler)
if (rc) {
pr_err("fsp_of_probe: request_irq failed: np=%pOF rc=%d",
np, rc);
of_node_put(np);
return;
}
}

View File

@ -219,7 +219,7 @@ static int board_rev = -1;
static int __init ppc47x_get_board_rev(void)
{
int reg;
u8 *fpga;
u8 __iomem *fpga;
struct device_node *np = NULL;
if (of_machine_is_compatible("ibm,currituck")) {
@ -233,7 +233,7 @@ static int __init ppc47x_get_board_rev(void)
if (!np)
goto fail;
fpga = (u8 *) of_iomap(np, 0);
fpga = of_iomap(np, 0);
of_node_put(np);
if (!fpga)
goto fail;

View File

@ -135,11 +135,10 @@ static int mcu_gpiochip_add(struct mcu *mcu)
return gpiochip_add_data(gc, mcu);
}
static int mcu_gpiochip_remove(struct mcu *mcu)
static void mcu_gpiochip_remove(struct mcu *mcu)
{
kfree(mcu->gc.label);
gpiochip_remove(&mcu->gc);
return 0;
}
static int mcu_probe(struct i2c_client *client)
@ -198,9 +197,7 @@ static int mcu_remove(struct i2c_client *client)
glob_mcu = NULL;
}
ret = mcu_gpiochip_remove(mcu);
if (ret)
return ret;
mcu_gpiochip_remove(mcu);
kfree(mcu);
return 0;
}

View File

@ -3,7 +3,9 @@
# Makefile for the PowerPC 85xx linux kernel.
#
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_FSL_PMC) += mpc85xx_pm_ops.o
ifneq ($(CONFIG_FSL_CORENET_RCPM),y)
obj-$(CONFIG_SMP) += mpc85xx_pm_ops.o
endif
obj-y += common.o

View File

@ -17,6 +17,7 @@
static struct ccsr_guts __iomem *guts;
#ifdef CONFIG_FSL_PMC
static void mpc85xx_irq_mask(int cpu)
{
@ -49,6 +50,7 @@ static void mpc85xx_cpu_up_prepare(int cpu)
{
}
#endif
static void mpc85xx_freeze_time_base(bool freeze)
{
@ -76,10 +78,12 @@ static const struct of_device_id mpc85xx_smp_guts_ids[] = {
static const struct fsl_pm_ops mpc85xx_pm_ops = {
.freeze_time_base = mpc85xx_freeze_time_base,
#ifdef CONFIG_FSL_PMC
.irq_mask = mpc85xx_irq_mask,
.irq_unmask = mpc85xx_irq_unmask,
.cpu_die = mpc85xx_cpu_die,
.cpu_up_prepare = mpc85xx_cpu_up_prepare,
#endif
};
int __init mpc85xx_setup_pmc(void)
@ -94,9 +98,8 @@ int __init mpc85xx_setup_pmc(void)
pr_err("Could not map guts node address\n");
return -ENOMEM;
}
qoriq_pm_ops = &mpc85xx_pm_ops;
}
qoriq_pm_ops = &mpc85xx_pm_ops;
return 0;
}

View File

@ -40,7 +40,6 @@ struct epapr_spin_table {
u32 pir;
};
#ifdef CONFIG_HOTPLUG_CPU
static u64 timebase;
static int tb_req;
static int tb_valid;
@ -112,6 +111,7 @@ static void mpc85xx_take_timebase(void)
local_irq_restore(flags);
}
#ifdef CONFIG_HOTPLUG_CPU
static void smp_85xx_cpu_offline_self(void)
{
unsigned int cpu = smp_processor_id();
@ -495,21 +495,21 @@ void __init mpc85xx_smp_init(void)
smp_85xx_ops.probe = NULL;
}
#ifdef CONFIG_HOTPLUG_CPU
#ifdef CONFIG_FSL_CORENET_RCPM
/* Assign a value to qoriq_pm_ops on PPC_E500MC */
fsl_rcpm_init();
#endif
#ifdef CONFIG_FSL_PMC
#else
/* Assign a value to qoriq_pm_ops on !PPC_E500MC */
mpc85xx_setup_pmc();
#endif
if (qoriq_pm_ops) {
smp_85xx_ops.give_timebase = mpc85xx_give_timebase;
smp_85xx_ops.take_timebase = mpc85xx_take_timebase;
#ifdef CONFIG_HOTPLUG_CPU
smp_85xx_ops.cpu_offline_self = smp_85xx_cpu_offline_self;
smp_85xx_ops.cpu_die = qoriq_cpu_kill;
}
#endif
}
smp_ops = &smp_85xx_ops;
#ifdef CONFIG_KEXEC_CORE

View File

@ -303,7 +303,7 @@ static int coproc_ioc_tx_win_open(struct file *fp, unsigned long arg)
return -EINVAL;
}
if (!cp_inst->coproc->vops && !cp_inst->coproc->vops->open_win) {
if (!cp_inst->coproc->vops || !cp_inst->coproc->vops->open_win) {
pr_err("VAS API is not registered\n");
return -EACCES;
}
@ -373,7 +373,7 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma)
return -EINVAL;
}
if (!cp_inst->coproc->vops && !cp_inst->coproc->vops->paste_addr) {
if (!cp_inst->coproc->vops || !cp_inst->coproc->vops->paste_addr) {
pr_err("%s(): VAS API is not registered\n", __func__);
return -EACCES;
}

View File

@ -27,7 +27,6 @@ extern void pmac_nvram_update(void);
extern unsigned char pmac_nvram_read_byte(int addr);
extern void pmac_nvram_write_byte(int addr, unsigned char val);
extern void pmac_pcibios_after_init(void);
extern int of_show_percpuinfo(struct seq_file *m, int i);
extern void pmac_setup_pci_dma(void);
extern void pmac_check_ht_link(void);

Some files were not shown because too many files have changed in this diff Show More