Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull powerpc updates from Michael Ellerman:

- Add support for syscall stack randomization

- Add support for atomic operations to the 32 & 64-bit BPF JIT

- Full support for KASAN on 64-bit Book3E

- Add a watchdog driver for the new PowerVM hypervisor watchdog

- Add a number of new selftests for the Power10 PMU support

- Add a driver for the PowerVM Platform KeyStore

- Increase the NMI watchdog timeout during live partition migration, to
avoid timeouts due to increased memory access latency

- Add support for using the 'linux,pci-domain' device tree property for
PCI domain assignment

- Many other small features and fixes

Thanks to Alexey Kardashevskiy, Andy Shevchenko, Arnd Bergmann, Athira
Rajeev, Bagas Sanjaya, Christophe Leroy, Erhard Furtner, Fabiano Rosas,
Greg Kroah-Hartman, Greg Kurz, Haowen Bai, Hari Bathini, Jason A.
Donenfeld, Jason Wang, Jiang Jian, Joel Stanley, Juerg Haefliger, Kajol
Jain, Kees Cook, Laurent Dufour, Madhavan Srinivasan, Masahiro Yamada,
Maxime Bizon, Miaoqian Lin, Murilo Opsfelder Araújo, Nathan Lynch,
Naveen N. Rao, Nayna Jain, Nicholas Piggin, Ning Qiang, Pali Rohár,
Petr Mladek, Rashmica Gupta, Sachin Sant, Scott Cheloha, Segher
Boessenkool, Stephen Rothwell, Uwe Kleine-König, Wolfram Sang, Xiu
Jianfeng, and Zhouyi Zhou.

* tag 'powerpc-6.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (191 commits)
powerpc/64e: Fix kexec build error
EDAC/ppc_4xx: Include required of_irq header directly
powerpc/pci: Fix PHB numbering when using opal-phbid
powerpc/64: Init jump labels before parse_early_param()
selftests/powerpc: Avoid GCC 12 uninitialised variable warning
powerpc/cell/axon_msi: Fix refcount leak in setup_msi_msg_address
powerpc/xive: Fix refcount leak in xive_get_max_prio
powerpc/spufs: Fix refcount leak in spufs_init_isolated_loader
powerpc/perf: Include caps feature for power10 DD1 version
powerpc: add support for syscall stack randomization
powerpc: Move system_call_exception() to syscall.c
powerpc/powernv: rename remaining rng powernv_ functions to pnv_
powerpc/powernv/kvm: Use darn for H_RANDOM on Power9
powerpc/powernv: Avoid crashing if rng is NULL
selftests/powerpc: Fix matrix multiply assist test
powerpc/signal: Update comment for clarity
powerpc: make facility_unavailable_exception 64s
powerpc/platforms/83xx/suspend: Remove write-only global variable
powerpc/platforms/83xx/suspend: Prevent unloading the driver
powerpc/platforms/83xx/suspend: Reorder to get rid of a forward declaration
...

+6807 -2118
+18
Documentation/ABI/testing/sysfs-bus-event_source-devices-caps
··· 1 + What: /sys/bus/event_source/devices/<dev>/caps 2 + Date: May 2022 3 + KernelVersion: 5.19 4 + Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> 5 + Description: 6 + Attribute group to describe the capabilities exposed 7 + for a particular pmu. Each attribute of this group can 8 + expose information specific to a PMU, say pmu_name, so that 9 + userspace can understand some of the feature which the 10 + platform specific PMU supports. 11 + 12 + One of the example available capability in supported platform 13 + like Intel is pmu_name, which exposes underlying CPU name known 14 + to the PMU driver. 15 + 16 + Example output in powerpc: 17 + grep . /sys/bus/event_source/devices/cpu/caps/* 18 + /sys/bus/event_source/devices/cpu/caps/pmu_name:POWER9
-6
Documentation/admin-guide/kernel-parameters.txt
··· 3553 3553 3554 3554 noautogroup Disable scheduler automatic task group creation. 3555 3555 3556 - nobats [PPC] Do not use BATs for mapping kernel lowmem 3557 - on "Classic" PPC cores. 3558 - 3559 3556 nocache [ARM] 3560 3557 3561 3558 nodsp [SH] Disable hardware DSP at boot time. ··· 3721 3724 nolapic [X86-32,APIC] Do not enable or use the local APIC. 3722 3725 3723 3726 nolapic_timer [X86-32,APIC] Do not use the local APIC timer. 3724 - 3725 - noltlbs [PPC] Do not use large page/tlb entries for kernel 3726 - lowmem mapping on PPC40x and PPC8xx 3727 3727 3728 3728 nomca [IA-64] Disable machine check abort handling 3729 3729
+12
Documentation/admin-guide/sysctl/kernel.rst
··· 592 592 Documentation/admin-guide/kernel-parameters.rst). 593 593 594 594 595 + nmi_wd_lpm_factor (PPC only) 596 + ============================ 597 + 598 + Factor to apply to the NMI watchdog timeout (only when ``nmi_watchdog`` is 599 + set to 1). This factor represents the percentage added to 600 + ``watchdog_thresh`` when calculating the NMI watchdog timeout during an 601 + LPM. The soft lockup timeout is not impacted. 602 + 603 + A value of 0 means no change. The default value is 200 meaning the NMI 604 + watchdog is set to 30s (based on ``watchdog_thresh`` equal to 10). 605 + 606 + 595 607 numa_balancing 596 608 ============== 597 609
+231
Documentation/powerpc/elf_hwcaps.rst
··· 1 + .. _elf_hwcaps_powerpc: 2 + 3 + ================== 4 + POWERPC ELF HWCAPs 5 + ================== 6 + 7 + This document describes the usage and semantics of the powerpc ELF HWCAPs. 8 + 9 + 10 + 1. Introduction 11 + --------------- 12 + 13 + Some hardware or software features are only available on some CPU 14 + implementations, and/or with certain kernel configurations, but have no other 15 + discovery mechanism available to userspace code. The kernel exposes the 16 + presence of these features to userspace through a set of flags called HWCAPs, 17 + exposed in the auxiliary vector. 18 + 19 + Userspace software can test for features by acquiring the AT_HWCAP or 20 + AT_HWCAP2 entry of the auxiliary vector, and testing whether the relevant 21 + flags are set, e.g.:: 22 + 23 + bool floating_point_is_present(void) 24 + { 25 + unsigned long HWCAPs = getauxval(AT_HWCAP); 26 + if (HWCAPs & PPC_FEATURE_HAS_FPU) 27 + return true; 28 + 29 + return false; 30 + } 31 + 32 + Where software relies on a feature described by a HWCAP, it should check the 33 + relevant HWCAP flag to verify that the feature is present before attempting to 34 + make use of the feature. 35 + 36 + HWCAP is the preferred method to test for the presence of a feature rather 37 + than probing through other means, which may not be reliable or may cause 38 + unpredictable behaviour. 39 + 40 + Software that targets a particular platform does not necessarily have to 41 + test for required or implied features. For example if the program requires 42 + FPU, VMX, VSX, it is not necessary to test those HWCAPs, and it may be 43 + impossible to do so if the compiler generates code requiring those features. 44 + 45 + 2. Facilities 46 + ------------- 47 + 48 + The Power ISA uses the term "facility" to describe a class of instructions, 49 + registers, interrupts, etc. The presence or absence of a facility indicates 50 + whether this class is available to be used, but the specifics depend on the 51 + ISA version. For example, if the VSX facility is available, the VSX 52 + instructions that can be used differ between the v3.0B and v3.1B ISA 53 + versions. 54 + 55 + 3. Categories 56 + ------------- 57 + 58 + The Power ISA before v3.0 uses the term "category" to describe certain 59 + classes of instructions and operating modes which may be optional or 60 + mutually exclusive, the exact meaning of the HWCAP flag may depend on 61 + context, e.g., the presence of the BOOKE feature implies that the server 62 + category is not implemented. 63 + 64 + 4. HWCAP allocation 65 + ------------------- 66 + 67 + HWCAPs are allocated as described in Power Architecture 64-Bit ELF V2 ABI 68 + Specification (which will be reflected in the kernel's uapi headers). 69 + 70 + 5. The HWCAPs exposed in AT_HWCAP 71 + --------------------------------- 72 + 73 + PPC_FEATURE_32 74 + 32-bit CPU 75 + 76 + PPC_FEATURE_64 77 + 64-bit CPU (userspace may be running in 32-bit mode). 78 + 79 + PPC_FEATURE_601_INSTR 80 + The processor is PowerPC 601. 81 + Unused in the kernel since f0ed73f3fa2c ("powerpc: Remove PowerPC 601") 82 + 83 + PPC_FEATURE_HAS_ALTIVEC 84 + Vector (aka Altivec, VMX) facility is available. 85 + 86 + PPC_FEATURE_HAS_FPU 87 + Floating point facility is available. 88 + 89 + PPC_FEATURE_HAS_MMU 90 + Memory management unit is present and enabled. 91 + 92 + PPC_FEATURE_HAS_4xxMAC 93 + The processor is 40x or 44x family. 94 + 95 + PPC_FEATURE_UNIFIED_CACHE 96 + The processor has a unified L1 cache for instructions and data, as 97 + found in NXP e200. 98 + Unused in the kernel since 39c8bf2b3cc1 ("powerpc: Retire e200 core (mpc555x processor)") 99 + 100 + PPC_FEATURE_HAS_SPE 101 + Signal Processing Engine facility is available. 102 + 103 + PPC_FEATURE_HAS_EFP_SINGLE 104 + Embedded Floating Point single precision operations are available. 105 + 106 + PPC_FEATURE_HAS_EFP_DOUBLE 107 + Embedded Floating Point double precision operations are available. 108 + 109 + PPC_FEATURE_NO_TB 110 + The timebase facility (mftb instruction) is not available. 111 + This is a 601 specific HWCAP, so if it is known that the processor 112 + running is not a 601, via other HWCAPs or other means, it is not 113 + required to test this bit before using the timebase. 114 + Unused in the kernel since f0ed73f3fa2c ("powerpc: Remove PowerPC 601") 115 + 116 + PPC_FEATURE_POWER4 117 + The processor is POWER4 or PPC970/FX/MP. 118 + POWER4 support dropped from the kernel since 471d7ff8b51b ("powerpc/64s: Remove POWER4 support") 119 + 120 + PPC_FEATURE_POWER5 121 + The processor is POWER5. 122 + 123 + PPC_FEATURE_POWER5_PLUS 124 + The processor is POWER5+. 125 + 126 + PPC_FEATURE_CELL 127 + The processor is Cell. 128 + 129 + PPC_FEATURE_BOOKE 130 + The processor implements the embedded category ("BookE") architecture. 131 + 132 + PPC_FEATURE_SMT 133 + The processor implements SMT. 134 + 135 + PPC_FEATURE_ICACHE_SNOOP 136 + The processor icache is coherent with the dcache, and instruction storage 137 + can be made consistent with data storage for the purpose of executing 138 + instructions with the sequence (as described in, e.g., POWER9 Processor 139 + User's Manual, 4.6.2.2 Instruction Cache Block Invalidate (icbi)):: 140 + 141 + sync 142 + icbi (to any address) 143 + isync 144 + 145 + PPC_FEATURE_ARCH_2_05 146 + The processor supports the v2.05 userlevel architecture. Processors 147 + supporting later architectures DO NOT set this feature. 148 + 149 + PPC_FEATURE_PA6T 150 + The processor is PA6T. 151 + 152 + PPC_FEATURE_HAS_DFP 153 + DFP facility is available. 154 + 155 + PPC_FEATURE_POWER6_EXT 156 + The processor is POWER6. 157 + 158 + PPC_FEATURE_ARCH_2_06 159 + The processor supports the v2.06 userlevel architecture. Processors 160 + supporting later architectures also set this feature. 161 + 162 + PPC_FEATURE_HAS_VSX 163 + VSX facility is available. 164 + 165 + PPC_FEATURE_PSERIES_PERFMON_COMPAT 166 + The processor supports architected PMU events in the range 0xE0-0xFF. 167 + 168 + PPC_FEATURE_TRUE_LE 169 + The processor supports true little-endian mode. 170 + 171 + PPC_FEATURE_PPC_LE 172 + The processor supports "PowerPC Little-Endian", that uses address 173 + munging to make storage access appear to be little-endian, but the 174 + data is stored in a different format that is unsuitable to be 175 + accessed by other agents not running in this mode. 176 + 177 + 6. The HWCAPs exposed in AT_HWCAP2 178 + ---------------------------------- 179 + 180 + PPC_FEATURE2_ARCH_2_07 181 + The processor supports the v2.07 userlevel architecture. Processors 182 + supporting later architectures also set this feature. 183 + 184 + PPC_FEATURE2_HTM 185 + Transactional Memory feature is available. 186 + 187 + PPC_FEATURE2_DSCR 188 + DSCR facility is available. 189 + 190 + PPC_FEATURE2_EBB 191 + EBB facility is available. 192 + 193 + PPC_FEATURE2_ISEL 194 + isel instruction is available. This is superseded by ARCH_2_07 and 195 + later. 196 + 197 + PPC_FEATURE2_TAR 198 + TAR facility is available. 199 + 200 + PPC_FEATURE2_VEC_CRYPTO 201 + v2.07 crypto instructions are available. 202 + 203 + PPC_FEATURE2_HTM_NOSC 204 + System calls fail if called in a transactional state, see 205 + Documentation/powerpc/syscall64-abi.rst 206 + 207 + PPC_FEATURE2_ARCH_3_00 208 + The processor supports the v3.0B / v3.0C userlevel architecture. Processors 209 + supporting later architectures also set this feature. 210 + 211 + PPC_FEATURE2_HAS_IEEE128 212 + IEEE 128-bit binary floating point is supported with VSX 213 + quad-precision instructions and data types. 214 + 215 + PPC_FEATURE2_DARN 216 + darn instruction is available. 217 + 218 + PPC_FEATURE2_SCV 219 + The scv 0 instruction may be used for system calls, see 220 + Documentation/powerpc/syscall64-abi.rst. 221 + 222 + PPC_FEATURE2_HTM_NO_SUSPEND 223 + A limited Transactional Memory facility that does not support suspend is 224 + available, see Documentation/powerpc/transactional_memory.rst. 225 + 226 + PPC_FEATURE2_ARCH_3_1 227 + The processor supports the v3.1 userlevel architecture. Processors 228 + supporting later architectures also set this feature. 229 + 230 + PPC_FEATURE2_MMA 231 + MMA facility is available.
+1
Documentation/powerpc/index.rst
··· 17 17 dawr-power9 18 18 dscr 19 19 eeh-pci-error-recovery 20 + elf_hwcaps 20 21 elfnote 21 22 firmware-assisted-dump 22 23 hvcs
+12
Documentation/watchdog/watchdog-parameters.rst
··· 425 425 426 426 ------------------------------------------------- 427 427 428 + pseries-wdt: 429 + action: 430 + Action taken when watchdog expires: 0 (power off), 1 (restart), 431 + 2 (dump and restart). (default=1) 432 + timeout: 433 + Initial watchdog timeout in seconds. (default=60) 434 + nowayout: 435 + Watchdog cannot be stopped once started. 436 + (default=kernel config parameter) 437 + 438 + ------------------------------------------------- 439 + 428 440 rc32434_wdt: 429 441 timeout: 430 442 Watchdog timeout value, in seconds (default=20)
+2 -2
MAINTAINERS
··· 11628 11628 11629 11629 LINUX FOR POWERPC (32-BIT AND 64-BIT) 11630 11630 M: Michael Ellerman <mpe@ellerman.id.au> 11631 - R: Benjamin Herrenschmidt <benh@kernel.crashing.org> 11632 - R: Paul Mackerras <paulus@samba.org> 11631 + R: Nicholas Piggin <npiggin@gmail.com> 11632 + R: Christophe Leroy <christophe.leroy@csgroup.eu> 11633 11633 L: linuxppc-dev@lists.ozlabs.org 11634 11634 S: Supported 11635 11635 W: https://github.com/linuxppc/wiki/wiki
+16 -3
arch/powerpc/Kconfig
··· 11 11 12 12 config LIVEPATCH_64 13 13 def_bool PPC64 14 - depends on LIVEPATCH 14 + depends on LIVEPATCH 15 15 16 16 config MMU 17 17 bool ··· 192 192 select HAVE_ARCH_JUMP_LABEL_RELATIVE 193 193 select HAVE_ARCH_KASAN if PPC32 && PPC_PAGE_SHIFT <= 14 194 194 select HAVE_ARCH_KASAN if PPC_RADIX_MMU 195 + select HAVE_ARCH_KASAN if PPC_BOOK3E_64 195 196 select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN 196 197 select HAVE_ARCH_KFENCE if PPC_BOOK3S_32 || PPC_8xx || 40x 198 + select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET 197 199 select HAVE_ARCH_KGDB 198 200 select HAVE_ARCH_MMAP_RND_BITS 199 201 select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT ··· 255 253 select IOMMU_HELPER if PPC64 256 254 select IRQ_DOMAIN 257 255 select IRQ_FORCED_THREADING 256 + select KASAN_VMALLOC if KASAN && MODULES 258 257 select MMU_GATHER_PAGE_SIZE 259 258 select MMU_GATHER_RCU_TABLE_FREE 260 259 select MMU_GATHER_MERGE_VMAS ··· 379 376 depends on PPC_DCR_NATIVE || PPC_DCR_MMIO 380 377 default y 381 378 379 + config PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT 380 + depends on PPC32 381 + depends on !PPC_PMAC && !PPC_CHRP 382 + bool "Assign PCI bus numbers from zero individually for each PCI domain" 383 + help 384 + By default on PPC32 were PCI bus numbers unique across all PCI domains. 385 + So system could have only 256 PCI buses independently of available 386 + PCI domains. When this option is enabled then PCI bus numbers are 387 + PCI domain dependent and each PCI controller on own domain can have 388 + 256 PCI buses, like it is on other Linux architectures. 389 + 382 390 config PPC_OF_PLATFORM_PCI 383 391 bool 384 392 depends on PCI ··· 466 452 default MATH_EMULATION_FULL 467 453 depends on MATH_EMULATION 468 454 469 - config MATH_EMULATION_FULL 455 + config MATH_EMULATION_FULL 470 456 bool "Emulate all the floating point instructions" 471 457 help 472 458 Select this option will enable the kernel to support to emulate ··· 568 554 bool "kexec file based system call" 569 555 select KEXEC_CORE 570 556 select HAVE_IMA_KEXEC if IMA 571 - select BUILD_BIN2C 572 557 select KEXEC_ELF 573 558 depends on PPC64 574 559 depends on CRYPTO=y
+2 -2
arch/powerpc/Kconfig.debug
··· 305 305 def_bool y 306 306 depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI 307 307 308 - 309 308 config PPC_EARLY_DEBUG_HVSI_VTERMNO 310 309 hex "vterm number to use with early debug HVSI" 311 310 depends on PPC_EARLY_DEBUG_LPAR_HVSI ··· 374 375 hex 375 376 depends on KASAN 376 377 default 0xe0000000 if PPC32 377 - default 0xa80e000000000000 if PPC64 378 + default 0xa80e000000000000 if PPC_BOOK3S_64 379 + default 0xa8001c0000000000 if PPC_BOOK3E_64
+2 -32
arch/powerpc/Makefile
··· 15 15 # Set default 32 bits cross compilers for vdso and boot wrapper 16 16 CROSS32_COMPILE ?= 17 17 18 - ifeq ($(HAS_BIARCH),y) 19 - ifeq ($(CROSS32_COMPILE),) 20 - ifdef CONFIG_PPC32 21 - # These options will be overridden by any -mcpu option that the CPU 22 - # or platform code sets later on the command line, but they are needed 23 - # to set a sane 32-bit cpu target for the 64-bit cross compiler which 24 - # may default to the wrong ISA. 25 - KBUILD_CFLAGS += -mcpu=powerpc 26 - KBUILD_AFLAGS += -mcpu=powerpc 27 - endif 28 - endif 29 - endif 30 - 31 - ifdef CONFIG_PPC_BOOK3S_32 32 - KBUILD_CFLAGS += -mcpu=powerpc 33 - endif 34 - 35 18 # If we're on a ppc/ppc64/ppc64le machine use that defconfig, otherwise just use 36 19 # ppc64_defconfig because we have nothing better to go on. 37 20 uname := $(shell uname -m) ··· 166 183 endif 167 184 168 185 CFLAGS-$(CONFIG_TARGET_CPU_BOOL) += $(call cc-option,-mcpu=$(CONFIG_TARGET_CPU)) 186 + AFLAGS-$(CONFIG_TARGET_CPU_BOOL) += $(call cc-option,-mcpu=$(CONFIG_TARGET_CPU)) 169 187 170 - # Altivec option not allowed with e500mc64 in GCC. 171 - ifdef CONFIG_ALTIVEC 172 - E5500_CPU := -mcpu=powerpc64 173 - else 174 - E5500_CPU := $(call cc-option,-mcpu=e500mc64,-mcpu=powerpc64) 175 - endif 176 - CFLAGS-$(CONFIG_E5500_CPU) += $(E5500_CPU) 188 + CFLAGS-$(CONFIG_E5500_CPU) += $(call cc-option,-mcpu=e500mc64,-mcpu=powerpc64) 177 189 CFLAGS-$(CONFIG_E6500_CPU) += $(call cc-option,-mcpu=e6500,$(E5500_CPU)) 178 - 179 - ifdef CONFIG_PPC32 180 - ifdef CONFIG_PPC_E500MC 181 - CFLAGS-y += $(call cc-option,-mcpu=e500mc,-mcpu=powerpc) 182 - else 183 - CFLAGS-$(CONFIG_E500) += $(call cc-option,-mcpu=8540 -msoft-float,-mcpu=powerpc) 184 - endif 185 - endif 186 190 187 191 asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1) 188 192
+3
arch/powerpc/boot/dts/fsl/p2020si-post.dtsi
··· 48 48 bus-range = <0 255>; 49 49 clock-frequency = <33333333>; 50 50 interrupts = <26 2 0 0>; 51 + law_trgt_if = <2>; 51 52 52 53 pcie@0 { 53 54 reg = <0 0 0 0 0>; ··· 77 76 bus-range = <0 255>; 78 77 clock-frequency = <33333333>; 79 78 interrupts = <25 2 0 0>; 79 + law_trgt_if = <1>; 80 80 81 81 pcie@0 { 82 82 reg = <0 0 0 0 0>; ··· 107 105 bus-range = <0 255>; 108 106 clock-frequency = <33333333>; 109 107 interrupts = <24 2 0 0>; 108 + law_trgt_if = <0>; 110 109 111 110 pcie@0 { 112 111 reg = <0 0 0 0 0>;
+483
arch/powerpc/boot/dts/turris1x.dts
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Turris 1.x Device Tree Source 4 + * 5 + * Copyright 2013 - 2022 CZ.NIC z.s.p.o. (http://www.nic.cz/) 6 + * 7 + * Pinout, Schematics and Altium hardware design files are open source 8 + * and available at: https://docs.turris.cz/hw/turris-1x/turris-1x/ 9 + */ 10 + 11 + #include <dt-bindings/gpio/gpio.h> 12 + #include <dt-bindings/interrupt-controller/irq.h> 13 + #include <dt-bindings/leds/common.h> 14 + /include/ "fsl/p2020si-pre.dtsi" 15 + 16 + / { 17 + model = "Turris 1.x"; 18 + compatible = "cznic,turris1x", "fsl,P2020RDB-PC"; /* fsl,P2020RDB-PC is required for booting Linux */ 19 + 20 + aliases { 21 + ethernet0 = &enet0; 22 + ethernet1 = &enet1; 23 + ethernet2 = &enet2; 24 + serial0 = &serial0; 25 + serial1 = &serial1; 26 + pci0 = &pci0; 27 + pci1 = &pci1; 28 + pci2 = &pci2; 29 + spi0 = &spi0; 30 + }; 31 + 32 + memory { 33 + device_type = "memory"; 34 + }; 35 + 36 + soc: soc@ffe00000 { 37 + ranges = <0x0 0x0 0xffe00000 0x00100000>; 38 + 39 + i2c@3000 { 40 + /* PCA9557PW GPIO controller for boot config */ 41 + gpio-controller@18 { 42 + compatible = "nxp,pca9557"; 43 + label = "bootcfg"; 44 + reg = <0x18>; 45 + #gpio-cells = <2>; 46 + gpio-controller; 47 + polarity = <0x00>; 48 + }; 49 + 50 + /* STM32F030R8T6 MCU for power control */ 51 + power-control@2a { 52 + /* 53 + * Turris Power Control firmware runs on STM32F0 MCU. 54 + * This firmware is open source and available at: 55 + * https://gitlab.nic.cz/turris/hw/turris_power_control 56 + */ 57 + reg = <0x2a>; 58 + }; 59 + 60 + /* DDR3 SPD/EEPROM PSWP instruction */ 61 + eeprom@32 { 62 + reg = <0x32>; 63 + }; 64 + 65 + /* SA56004ED temperature control */ 66 + temperature-sensor@4c { 67 + compatible = "nxp,sa56004"; 68 + reg = <0x4c>; 69 + interrupt-parent = <&gpio>; 70 + interrupts = <12 IRQ_TYPE_LEVEL_LOW>, /* GPIO12 - ALERT pin */ 71 + <13 IRQ_TYPE_LEVEL_LOW>; /* GPIO13 - CRIT pin */ 72 + }; 73 + 74 + /* DDR3 SPD/EEPROM */ 75 + eeprom@52 { 76 + compatible = "atmel,spd"; 77 + reg = <0x52>; 78 + }; 79 + 80 + /* MCP79402-I/ST Protected EEPROM */ 81 + eeprom@57 { 82 + reg = <0x57>; 83 + }; 84 + 85 + /* ATSHA204-TH-DA-T crypto module */ 86 + crypto@64 { 87 + compatible = "atmel,atsha204"; 88 + reg = <0x64>; 89 + }; 90 + 91 + /* IDT6V49205BNLGI clock generator */ 92 + clock-generator@69 { 93 + compatible = "idt,6v49205b"; 94 + reg = <0x69>; 95 + }; 96 + 97 + /* MCP79402-I/ST RTC */ 98 + rtc@6f { 99 + compatible = "microchip,mcp7940x"; 100 + reg = <0x6f>; 101 + interrupt-parent = <&gpio>; 102 + interrupts = <14 0>; /* GPIO14 - MFP pin */ 103 + }; 104 + }; 105 + 106 + /* SPI on connector P1 */ 107 + spi0: spi@7000 { 108 + }; 109 + 110 + gpio: gpio-controller@fc00 { 111 + #interrupt-cells = <2>; 112 + interrupt-controller; 113 + }; 114 + 115 + /* Connected to SMSC USB2412-DZK 2-Port USB 2.0 Hub Controller */ 116 + usb@22000 { 117 + phy_type = "ulpi"; 118 + dr_mode = "host"; 119 + }; 120 + 121 + enet0: ethernet@24000 { 122 + /* Connected to port 6 of QCA8337N-AL3C switch */ 123 + phy-connection-type = "rgmii-id"; 124 + 125 + fixed-link { 126 + speed = <1000>; 127 + full-duplex; 128 + }; 129 + }; 130 + 131 + mdio@24520 { 132 + /* KSZ9031RNXCA ethernet phy for WAN port */ 133 + phy: ethernet-phy@7 { 134 + interrupts = <3 1 0 0>; 135 + reg = <0x7>; 136 + }; 137 + 138 + /* QCA8337N-AL3C switch with integrated ethernet PHYs for LAN ports */ 139 + switch@10 { 140 + compatible = "qca,qca8337"; 141 + interrupts = <2 1 0 0>; 142 + reg = <0x10>; 143 + 144 + ports { 145 + #address-cells = <1>; 146 + #size-cells = <0>; 147 + 148 + port@0 { 149 + reg = <0>; 150 + label = "cpu1"; 151 + ethernet = <&enet1>; 152 + phy-mode = "rgmii-id"; 153 + 154 + fixed-link { 155 + speed = <1000>; 156 + full-duplex; 157 + }; 158 + }; 159 + 160 + port@1 { 161 + reg = <1>; 162 + label = "lan5"; 163 + }; 164 + 165 + port@2 { 166 + reg = <2>; 167 + label = "lan4"; 168 + }; 169 + 170 + port@3 { 171 + reg = <3>; 172 + label = "lan3"; 173 + }; 174 + 175 + port@4 { 176 + reg = <4>; 177 + label = "lan2"; 178 + }; 179 + 180 + port@5 { 181 + reg = <5>; 182 + label = "lan1"; 183 + }; 184 + 185 + port@6 { 186 + reg = <6>; 187 + label = "cpu0"; 188 + ethernet = <&enet0>; 189 + phy-mode = "rgmii-id"; 190 + 191 + fixed-link { 192 + speed = <1000>; 193 + full-duplex; 194 + }; 195 + }; 196 + }; 197 + }; 198 + }; 199 + 200 + ptp_clock@24e00 { 201 + fsl,tclk-period = <5>; 202 + fsl,tmr-prsc = <200>; 203 + fsl,tmr-add = <0xcccccccd>; 204 + fsl,tmr-fiper1 = <0x3b9ac9fb>; 205 + fsl,tmr-fiper2 = <0x0001869b>; 206 + fsl,max-adj = <249999999>; 207 + }; 208 + 209 + enet1: ethernet@25000 { 210 + /* Connected to port 0 of QCA8337N-AL3C switch */ 211 + phy-connection-type = "rgmii-id"; 212 + 213 + fixed-link { 214 + speed = <1000>; 215 + full-duplex; 216 + }; 217 + }; 218 + 219 + mdio@25520 { 220 + status = "disabled"; 221 + }; 222 + 223 + enet2: ethernet@26000 { 224 + /* Connected to KSZ9031RNXCA ethernet phy (WAN port) */ 225 + label = "wan"; 226 + phy-handle = <&phy>; 227 + phy-connection-type = "rgmii-id"; 228 + }; 229 + 230 + mdio@26520 { 231 + status = "disabled"; 232 + }; 233 + 234 + sdhc@2e000 { 235 + bus-width = <4>; 236 + cd-gpios = <&gpio 8 GPIO_ACTIVE_LOW>; 237 + }; 238 + }; 239 + 240 + lbc: localbus@ffe05000 { 241 + reg = <0 0xffe05000 0 0x1000>; 242 + 243 + ranges = <0x0 0x0 0x0 0xef000000 0x01000000>, /* NOR */ 244 + <0x1 0x0 0x0 0xff800000 0x00040000>, /* NAND */ 245 + <0x3 0x0 0x0 0xffa00000 0x00020000>; /* CPLD */ 246 + 247 + /* S29GL128P90TFIR10 NOR */ 248 + nor@0,0 { 249 + compatible = "cfi-flash"; 250 + reg = <0x0 0x0 0x01000000>; 251 + bank-width = <2>; 252 + device-width = <1>; 253 + 254 + partitions { 255 + compatible = "fixed-partitions"; 256 + #address-cells = <1>; 257 + #size-cells = <1>; 258 + 259 + partition@0 { 260 + /* 128 kB for Device Tree Blob */ 261 + reg = <0x00000000 0x00020000>; 262 + label = "dtb"; 263 + }; 264 + 265 + partition@20000 { 266 + /* 1.7 MB for Rescue Linux Kernel Image */ 267 + reg = <0x00020000 0x001a0000>; 268 + label = "rescue-kernel"; 269 + }; 270 + 271 + partition@1c0000 { 272 + /* 1.5 MB for Rescue JFFS2 Root File System */ 273 + reg = <0x001c0000 0x00180000>; 274 + label = "rescue-rootfs"; 275 + }; 276 + 277 + partition@340000 { 278 + /* 11 MB for TAR.XZ Backup with content of NAND Root File System */ 279 + reg = <0x00340000 0x00b00000>; 280 + label = "backup-rootfs"; 281 + }; 282 + 283 + partition@e40000 { 284 + /* 768 kB for Certificates JFFS2 File System */ 285 + reg = <0x00e40000 0x000c0000>; 286 + label = "certificates"; 287 + }; 288 + 289 + /* free unused space 0x00f00000-0x00f20000 */ 290 + 291 + partition@f20000 { 292 + /* 128 kB for U-Boot Environment Variables */ 293 + reg = <0x00f20000 0x00020000>; 294 + label = "u-boot-env"; 295 + }; 296 + 297 + partition@f40000 { 298 + /* 768 kB for U-Boot Bootloader Image */ 299 + reg = <0x00f40000 0x000c0000>; 300 + label = "u-boot"; 301 + }; 302 + }; 303 + }; 304 + 305 + /* MT29F2G08ABAEAWP:E NAND */ 306 + nand@1,0 { 307 + compatible = "fsl,p2020-fcm-nand", "fsl,elbc-fcm-nand"; 308 + reg = <0x1 0x0 0x00040000>; 309 + nand-ecc-mode = "soft"; 310 + nand-ecc-algo = "bch"; 311 + 312 + partitions { 313 + compatible = "fixed-partitions"; 314 + #address-cells = <1>; 315 + #size-cells = <1>; 316 + 317 + partition@0 { 318 + /* 256 MB for UBI with one volume: UBIFS Root File System */ 319 + reg = <0x00000000 0x10000000>; 320 + label = "rootfs"; 321 + }; 322 + }; 323 + }; 324 + 325 + /* LCMXO1200C-3FTN256C FPGA */ 326 + cpld@3,0 { 327 + /* 328 + * Turris CPLD firmware which runs on this Lattice FPGA, 329 + * is extended version of P1021RDB-PC CPLD v4.1 firmware. 330 + * It is backward compatible with its original version 331 + * and the only extension is support for Turris LEDs. 332 + * Turris CPLD firmware is open source and available at: 333 + * https://gitlab.nic.cz/turris/hw/turris_cpld/-/blob/master/CZ_NIC_Router_CPLD.v 334 + */ 335 + compatible = "cznic,turris1x-cpld", "fsl,p1021rdb-pc-cpld", "simple-bus", "syscon"; 336 + reg = <0x3 0x0 0x30>; 337 + #address-cells = <1>; 338 + #size-cells = <1>; 339 + ranges = <0x0 0x3 0x0 0x00020000>; 340 + 341 + /* MAX6370KA+T watchdog */ 342 + watchdog@2 { 343 + /* 344 + * CPLD firmware maps SET0, SET1 and SET2 345 + * input logic of MAX6370KA+T chip to CPLD 346 + * memory space at byte offset 0x2. WDI 347 + * input logic is outside of the CPLD and 348 + * connected via external GPIO. 349 + */ 350 + compatible = "maxim,max6370"; 351 + reg = <0x02 0x01>; 352 + gpios = <&gpio 11 GPIO_ACTIVE_LOW>; 353 + }; 354 + 355 + reboot@d { 356 + compatible = "syscon-reboot"; 357 + reg = <0x0d 0x01>; 358 + offset = <0x0d>; 359 + mask = <0x01>; 360 + value = <0x01>; 361 + }; 362 + 363 + led-controller@13 { 364 + /* 365 + * LEDs are controlled by CPLD firmware. 366 + * All five LAN LEDs share common RGB settings 367 + * and so it is not possible to set different 368 + * colors on different LAN ports. 369 + */ 370 + compatible = "cznic,turris1x-leds"; 371 + reg = <0x13 0x1d>; 372 + #address-cells = <1>; 373 + #size-cells = <0>; 374 + 375 + multi-led@0 { 376 + reg = <0x0>; 377 + color = <LED_COLOR_ID_RGB>; 378 + function = LED_FUNCTION_WAN; 379 + }; 380 + 381 + multi-led@1 { 382 + reg = <0x1>; 383 + color = <LED_COLOR_ID_RGB>; 384 + function = LED_FUNCTION_LAN; 385 + function-enumerator = <5>; 386 + }; 387 + 388 + multi-led@2 { 389 + reg = <0x2>; 390 + color = <LED_COLOR_ID_RGB>; 391 + function = LED_FUNCTION_LAN; 392 + function-enumerator = <4>; 393 + }; 394 + 395 + multi-led@3 { 396 + reg = <0x3>; 397 + color = <LED_COLOR_ID_RGB>; 398 + function = LED_FUNCTION_LAN; 399 + function-enumerator = <3>; 400 + }; 401 + 402 + multi-led@4 { 403 + reg = <0x4>; 404 + color = <LED_COLOR_ID_RGB>; 405 + function = LED_FUNCTION_LAN; 406 + function-enumerator = <2>; 407 + }; 408 + 409 + multi-led@5 { 410 + reg = <0x5>; 411 + color = <LED_COLOR_ID_RGB>; 412 + function = LED_FUNCTION_LAN; 413 + function-enumerator = <1>; 414 + }; 415 + 416 + multi-led@6 { 417 + reg = <0x6>; 418 + color = <LED_COLOR_ID_RGB>; 419 + function = LED_FUNCTION_WLAN; 420 + }; 421 + 422 + multi-led@7 { 423 + reg = <0x7>; 424 + color = <LED_COLOR_ID_RGB>; 425 + function = LED_FUNCTION_POWER; 426 + }; 427 + }; 428 + }; 429 + }; 430 + 431 + pci2: pcie@ffe08000 { 432 + /* 433 + * PCIe bus for on-board TUSB7340RKM USB 3.0 xHCI controller. 434 + * This xHCI controller is available only on Turris 1.1 boards. 435 + * Turris 1.0 boards have nothing connected to this PCIe bus, 436 + * so system would see only PCIe Root Port of this PCIe Root 437 + * Complex. TUSB7340RKM xHCI controller has four SuperSpeed 438 + * channels. Channel 0 is connected to the front USB 3.0 port, 439 + * channel 1 (but only USB 2.0 subset) to USB 2.0 pins on mPCIe 440 + * slot 1 (CN5), channels 2 and 3 to connector P600. 441 + * 442 + * P2020 PCIe Root Port uses 1MB of PCIe MEM and xHCI controller 443 + * uses 64kB + 8kB of PCIe MEM. No PCIe IO is used or required. 444 + * So allocate 2MB of PCIe MEM for this PCIe bus. 445 + */ 446 + reg = <0 0xffe08000 0 0x1000>; 447 + ranges = <0x02000000 0x0 0xc0000000 0 0xc0000000 0x0 0x00200000>, /* MEM */ 448 + <0x01000000 0x0 0x00000000 0 0xffc20000 0x0 0x00010000>; /* IO */ 449 + 450 + pcie@0 { 451 + ranges; 452 + }; 453 + }; 454 + 455 + pci1: pcie@ffe09000 { 456 + /* PCIe bus on mPCIe slot 2 (CN6) for expansion mPCIe card */ 457 + reg = <0 0xffe09000 0 0x1000>; 458 + ranges = <0x02000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000>, /* MEM */ 459 + <0x01000000 0x0 0x00000000 0 0xffc10000 0x0 0x00010000>; /* IO */ 460 + 461 + pcie@0 { 462 + ranges; 463 + }; 464 + }; 465 + 466 + pci0: pcie@ffe0a000 { 467 + /* 468 + * PCIe bus on mPCIe slot 1 (CN5) for expansion mPCIe card. 469 + * Turris 1.1 boards have in this mPCIe slot additional USB 2.0 470 + * pins via channel 1 of TUSB7340RKM xHCI controller and also 471 + * additional SIM card slot, both for USB-based WWAN cards. 472 + */ 473 + reg = <0 0xffe0a000 0 0x1000>; 474 + ranges = <0x02000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000>, /* MEM */ 475 + <0x01000000 0x0 0x00000000 0 0xffc00000 0x0 0x00010000>; /* IO */ 476 + 477 + pcie@0 { 478 + ranges; 479 + }; 480 + }; 481 + }; 482 + 483 + /include/ "fsl/p2020si-post.dtsi"
+1 -1
arch/powerpc/configs/44x/akebono_defconfig
··· 118 118 CONFIG_NLS_DEFAULT="n" 119 119 CONFIG_NLS_CODEPAGE_437=y 120 120 CONFIG_NLS_ISO8859_1=y 121 - CONFIG_DEBUG_INFO=y 121 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 122 122 CONFIG_MAGIC_SYSRQ=y 123 123 CONFIG_DETECT_HUNG_TASK=y 124 124 CONFIG_XMON=y
+1 -1
arch/powerpc/configs/44x/currituck_defconfig
··· 73 73 CONFIG_NFS_V3_ACL=y 74 74 CONFIG_NFS_V4=y 75 75 CONFIG_NLS_DEFAULT="n" 76 - CONFIG_DEBUG_INFO=y 76 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 77 77 CONFIG_MAGIC_SYSRQ=y 78 78 CONFIG_DETECT_HUNG_TASK=y 79 79 CONFIG_XMON=y
+1 -1
arch/powerpc/configs/44x/fsp2_defconfig
··· 110 110 CONFIG_PRINTK_TIME=y 111 111 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=3 112 112 CONFIG_DYNAMIC_DEBUG=y 113 - CONFIG_DEBUG_INFO=y 113 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 114 114 CONFIG_MAGIC_SYSRQ=y 115 115 CONFIG_DETECT_HUNG_TASK=y 116 116 CONFIG_CRYPTO_CBC=y
+1 -1
arch/powerpc/configs/44x/iss476-smp_defconfig
··· 56 56 CONFIG_TMPFS=y 57 57 CONFIG_CRAMFS=y 58 58 # CONFIG_NETWORK_FILESYSTEMS is not set 59 - CONFIG_DEBUG_INFO=y 59 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 60 60 CONFIG_MAGIC_SYSRQ=y 61 61 CONFIG_DETECT_HUNG_TASK=y 62 62 CONFIG_PPC_EARLY_DEBUG=y
+1 -1
arch/powerpc/configs/44x/warp_defconfig
··· 88 88 CONFIG_CRC_CCITT=y 89 89 CONFIG_CRC_T10DIF=y 90 90 CONFIG_PRINTK_TIME=y 91 - CONFIG_DEBUG_INFO=y 91 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 92 92 CONFIG_DEBUG_FS=y 93 93 CONFIG_MAGIC_SYSRQ=y 94 94 CONFIG_DETECT_HUNG_TASK=y
+1 -1
arch/powerpc/configs/52xx/lite5200b_defconfig
··· 58 58 CONFIG_NFS_V4=y 59 59 CONFIG_ROOT_NFS=y 60 60 CONFIG_PRINTK_TIME=y 61 - CONFIG_DEBUG_INFO=y 61 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 62 62 CONFIG_DETECT_HUNG_TASK=y 63 63 # CONFIG_DEBUG_BUGVERBOSE is not set
+1 -1
arch/powerpc/configs/52xx/motionpro_defconfig
··· 84 84 CONFIG_NLS_CODEPAGE_437=y 85 85 CONFIG_NLS_ISO8859_1=y 86 86 CONFIG_PRINTK_TIME=y 87 - CONFIG_DEBUG_INFO=y 87 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 88 88 CONFIG_DETECT_HUNG_TASK=y 89 89 # CONFIG_DEBUG_BUGVERBOSE is not set 90 90 CONFIG_CRYPTO_ECB=y
+1 -1
arch/powerpc/configs/52xx/tqm5200_defconfig
··· 85 85 CONFIG_NLS_CODEPAGE_437=y 86 86 CONFIG_NLS_ISO8859_1=y 87 87 CONFIG_PRINTK_TIME=y 88 - CONFIG_DEBUG_INFO=y 88 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 89 89 CONFIG_DETECT_HUNG_TASK=y 90 90 # CONFIG_DEBUG_BUGVERBOSE is not set 91 91 CONFIG_CRYPTO_ECB=y
+1 -1
arch/powerpc/configs/adder875_defconfig
··· 45 45 CONFIG_NFS_FS=y 46 46 CONFIG_ROOT_NFS=y 47 47 CONFIG_CRC32_SLICEBY4=y 48 - CONFIG_DEBUG_INFO=y 48 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 49 49 CONFIG_DEBUG_FS=y 50 50 CONFIG_MAGIC_SYSRQ=y 51 51 CONFIG_DETECT_HUNG_TASK=y
+1 -1
arch/powerpc/configs/ep8248e_defconfig
··· 59 59 CONFIG_NLS_ASCII=y 60 60 CONFIG_NLS_ISO8859_1=y 61 61 CONFIG_NLS_UTF8=y 62 - CONFIG_DEBUG_INFO=y 62 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 63 63 CONFIG_MAGIC_SYSRQ=y 64 64 # CONFIG_SCHED_DEBUG is not set 65 65 CONFIG_BDI_SWITCH=y
+1 -1
arch/powerpc/configs/ep88xc_defconfig
··· 48 48 CONFIG_NFS_FS=y 49 49 CONFIG_ROOT_NFS=y 50 50 CONFIG_CRC32_SLICEBY4=y 51 - CONFIG_DEBUG_INFO=y 51 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 52 52 CONFIG_MAGIC_SYSRQ=y 53 53 CONFIG_DETECT_HUNG_TASK=y
+1 -1
arch/powerpc/configs/fsl-emb-nonhw.config
··· 24 24 CONFIG_CRYPTO_SHA256=y 25 25 CONFIG_CRYPTO_SHA512=y 26 26 CONFIG_DEBUG_FS=y 27 - CONFIG_DEBUG_INFO=y 27 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 28 28 CONFIG_DEBUG_KERNEL=y 29 29 CONFIG_DEBUG_SHIRQ=y 30 30 CONFIG_DETECT_HUNG_TASK=y
+1 -1
arch/powerpc/configs/mgcoge_defconfig
··· 73 73 CONFIG_NLS_ASCII=y 74 74 CONFIG_NLS_ISO8859_1=y 75 75 CONFIG_NLS_UTF8=y 76 - CONFIG_DEBUG_INFO=y 76 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 77 77 CONFIG_DEBUG_FS=y 78 78 CONFIG_MAGIC_SYSRQ=y 79 79 # CONFIG_SCHED_DEBUG is not set
+1 -1
arch/powerpc/configs/mpc5200_defconfig
··· 122 122 CONFIG_NLS_CODEPAGE_437=y 123 123 CONFIG_NLS_ISO8859_1=y 124 124 CONFIG_PRINTK_TIME=y 125 - CONFIG_DEBUG_INFO=y 125 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 126 126 CONFIG_DEBUG_KERNEL=y 127 127 CONFIG_DETECT_HUNG_TASK=y
+1 -1
arch/powerpc/configs/mpc8272_ads_defconfig
··· 67 67 CONFIG_NLS_ASCII=y 68 68 CONFIG_NLS_ISO8859_1=y 69 69 CONFIG_NLS_UTF8=y 70 - CONFIG_DEBUG_INFO=y 70 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 71 71 CONFIG_MAGIC_SYSRQ=y 72 72 CONFIG_DETECT_HUNG_TASK=y 73 73 CONFIG_BDI_SWITCH=y
+1 -1
arch/powerpc/configs/mpc885_ads_defconfig
··· 71 71 CONFIG_CRYPTO=y 72 72 CONFIG_CRYPTO_DEV_TALITOS=y 73 73 CONFIG_CRC32_SLICEBY4=y 74 - CONFIG_DEBUG_INFO=y 74 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 75 75 CONFIG_MAGIC_SYSRQ=y 76 76 CONFIG_DEBUG_FS=y 77 77 CONFIG_DEBUG_VM_PGTABLE=y
+1 -1
arch/powerpc/configs/ppc6xx_defconfig
··· 1065 1065 CONFIG_NLS_ISO8859_15=m 1066 1066 CONFIG_NLS_KOI8_R=m 1067 1067 CONFIG_NLS_KOI8_U=m 1068 - CONFIG_DEBUG_INFO=y 1068 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 1069 1069 CONFIG_HEADERS_INSTALL=y 1070 1070 CONFIG_MAGIC_SYSRQ=y 1071 1071 CONFIG_DEBUG_KERNEL=y
+1 -1
arch/powerpc/configs/pq2fads_defconfig
··· 68 68 CONFIG_NLS_ASCII=y 69 69 CONFIG_NLS_ISO8859_1=y 70 70 CONFIG_NLS_UTF8=y 71 - CONFIG_DEBUG_INFO=y 71 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 72 72 CONFIG_MAGIC_SYSRQ=y 73 73 CONFIG_DETECT_HUNG_TASK=y 74 74 # CONFIG_SCHED_DEBUG is not set
+1 -1
arch/powerpc/configs/ps3_defconfig
··· 153 153 CONFIG_NLS_ISO8859_1=y 154 154 CONFIG_CRC_CCITT=m 155 155 CONFIG_CRC_T10DIF=y 156 - CONFIG_DEBUG_INFO=y 156 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 157 157 CONFIG_MAGIC_SYSRQ=y 158 158 CONFIG_DEBUG_MEMORY_INIT=y 159 159 CONFIG_DEBUG_STACKOVERFLOW=y
+1 -1
arch/powerpc/configs/tqm8xx_defconfig
··· 55 55 CONFIG_NFS_FS=y 56 56 CONFIG_ROOT_NFS=y 57 57 CONFIG_CRC32_SLICEBY4=y 58 - CONFIG_DEBUG_INFO=y 58 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 59 59 CONFIG_MAGIC_SYSRQ=y 60 60 CONFIG_DETECT_HUNG_TASK=y
+1 -6
arch/powerpc/include/asm/archrandom.h
··· 17 17 } 18 18 19 19 #ifdef CONFIG_PPC_POWERNV 20 - int powernv_hwrng_present(void); 21 - int powernv_get_random_long(unsigned long *v); 22 - int powernv_get_random_real_mode(unsigned long *v); 23 - #else 24 - static inline int powernv_hwrng_present(void) { return 0; } 25 - static inline int powernv_get_random_real_mode(unsigned long *v) { return 0; } 20 + int pnv_get_random_long(unsigned long *v); 26 21 #endif 27 22 28 23 #endif /* _ASM_POWERPC_ARCHRANDOM_H */
+3 -8
arch/powerpc/include/asm/asm-prototypes.h
··· 2 2 #ifndef _ASM_POWERPC_ASM_PROTOTYPES_H 3 3 #define _ASM_POWERPC_ASM_PROTOTYPES_H 4 4 /* 5 - * This file is for prototypes of C functions that are only called 6 - * from asm, and any associated variables. 5 + * This file is for C prototypes of asm symbols that are EXPORTed. 6 + * It allows the modversions logic to see their prototype and 7 + * generate proper CRCs for them. 7 8 * 8 9 * Copyright 2016, Daniel Axtens, IBM Corporation. 9 10 */ ··· 34 33 int64_t __opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3, 35 34 int64_t a4, int64_t a5, int64_t a6, int64_t a7, 36 35 int64_t opcode, uint64_t msr); 37 - 38 - /* prom_init (OpenFirmware) */ 39 - unsigned long __init prom_init(unsigned long r3, unsigned long r4, 40 - unsigned long pp, 41 - unsigned long r6, unsigned long r7, 42 - unsigned long kbase); 43 36 44 37 /* misc runtime */ 45 38 extern u64 __bswapdi2(u64);
+2
arch/powerpc/include/asm/barrier.h
··· 42 42 /* The sub-arch has lwsync */ 43 43 #if defined(CONFIG_PPC64) || defined(CONFIG_PPC_E500MC) 44 44 # define SMPWMB LWSYNC 45 + #elif defined(CONFIG_BOOKE) 46 + # define SMPWMB mbar 45 47 #else 46 48 # define SMPWMB eieio 47 49 #endif
+3
arch/powerpc/include/asm/book3s/64/hugetlb.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 #ifndef _ASM_POWERPC_BOOK3S_64_HUGETLB_H 3 3 #define _ASM_POWERPC_BOOK3S_64_HUGETLB_H 4 + 5 + #include <asm/firmware.h> 6 + 4 7 /* 5 8 * For radix we want generic code to handle hugetlb. But then if we want 6 9 * both hash and radix to be enabled together we need to workaround the
+23 -3
arch/powerpc/include/asm/book3s/64/tlbflush.h
··· 138 138 static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma, 139 139 unsigned long address) 140 140 { 141 - /* See ptep_set_access_flags comment */ 142 - if (atomic_read(&vma->vm_mm->context.copros) > 0) 143 - flush_tlb_page(vma, address); 141 + /* 142 + * Book3S 64 does not require spurious fault flushes because the PTE 143 + * must be re-fetched in case of an access permission problem. So the 144 + * only reason for a spurious fault should be concurrent modification 145 + * to the PTE, in which case the PTE will eventually be re-fetched by 146 + * the MMU when it attempts the access again. 147 + * 148 + * See: Power ISA Version 3.1B, 6.10.1.2 Modifying a Translation Table 149 + * Entry, Setting a Reference or Change Bit or Upgrading Access 150 + * Authority (PTE Subject to Atomic Hardware Updates): 151 + * 152 + * "If the only change being made to a valid PTE that is subject to 153 + * atomic hardware updates is to set the Reference or Change bit to 154 + * 1 or to upgrade access authority, a simpler sequence suffices 155 + * because the translation hardware will refetch the PTE if an 156 + * access is attempted for which the only problems were reference 157 + * and/or change bits needing to be set or insufficient access 158 + * authority." 159 + * 160 + * The nest MMU in POWER9 does not perform this PTE re-fetch, but 161 + * it avoids the spurious fault problem by flushing the TLB before 162 + * upgrading PTE permissions, see radix__ptep_set_access_flags. 163 + */ 144 164 } 145 165 146 166 extern bool tlbie_capable;
-3
arch/powerpc/include/asm/cputable.h
··· 70 70 /* Used to restore cpu setup on secondary processors and at resume */ 71 71 cpu_restore_t cpu_restore; 72 72 73 - /* Used by oprofile userspace to select the right counters */ 74 - char *oprofile_cpu_type; 75 - 76 73 /* Name of processor class, for the ELF AT_PLATFORM entry */ 77 74 char *platform; 78 75
+1
arch/powerpc/include/asm/cputime.h
··· 19 19 #include <asm/div64.h> 20 20 #include <asm/time.h> 21 21 #include <asm/param.h> 22 + #include <asm/firmware.h> 22 23 23 24 typedef u64 __nocast cputime_t; 24 25 typedef u64 __nocast cputime64_t;
+2 -1
arch/powerpc/include/asm/firmware.h
··· 55 55 #define FW_FEATURE_RPT_INVALIDATE ASM_CONST(0x0000010000000000) 56 56 #define FW_FEATURE_FORM2_AFFINITY ASM_CONST(0x0000020000000000) 57 57 #define FW_FEATURE_ENERGY_SCALE_INFO ASM_CONST(0x0000040000000000) 58 + #define FW_FEATURE_WATCHDOG ASM_CONST(0x0000080000000000) 58 59 59 60 #ifndef __ASSEMBLY__ 60 61 ··· 77 76 FW_FEATURE_DRC_INFO | FW_FEATURE_BLOCK_REMOVE | 78 77 FW_FEATURE_PAPR_SCM | FW_FEATURE_ULTRAVISOR | 79 78 FW_FEATURE_RPT_INVALIDATE | FW_FEATURE_FORM2_AFFINITY | 80 - FW_FEATURE_ENERGY_SCALE_INFO, 79 + FW_FEATURE_ENERGY_SCALE_INFO | FW_FEATURE_WATCHDOG, 81 80 FW_FEATURE_PSERIES_ALWAYS = 0, 82 81 FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_ULTRAVISOR, 83 82 FW_FEATURE_POWERNV_ALWAYS = 0,
+22 -1
arch/powerpc/include/asm/hvcall.h
··· 79 79 #define H_NOT_ENOUGH_RESOURCES -44 80 80 #define H_R_STATE -45 81 81 #define H_RESCINDED -46 82 + #define H_P1 -54 82 83 #define H_P2 -55 83 84 #define H_P3 -56 84 85 #define H_P4 -57 ··· 88 87 #define H_P7 -60 89 88 #define H_P8 -61 90 89 #define H_P9 -62 90 + #define H_NOOP -63 91 91 #define H_TOO_BIG -64 92 92 #define H_UNSUPPORTED -67 93 93 #define H_OVERLAP -68 ··· 99 97 #define H_OP_MODE -73 100 98 #define H_COP_HW -74 101 99 #define H_STATE -75 100 + #define H_IN_USE -77 101 + #define H_ABORTED -78 102 102 #define H_UNSUPPORTED_FLAG_START -256 103 103 #define H_UNSUPPORTED_FLAG_END -511 104 104 #define H_MULTI_THREADS_ACTIVE -9005 ··· 325 321 #define H_SCM_UNBIND_ALL 0x3FC 326 322 #define H_SCM_HEALTH 0x400 327 323 #define H_SCM_PERFORMANCE_STATS 0x418 324 + #define H_PKS_GET_CONFIG 0x41C 325 + #define H_PKS_SET_PASSWORD 0x420 326 + #define H_PKS_GEN_PASSWORD 0x424 327 + #define H_PKS_WRITE_OBJECT 0x42C 328 + #define H_PKS_GEN_KEY 0x430 329 + #define H_PKS_READ_OBJECT 0x434 330 + #define H_PKS_REMOVE_OBJECT 0x438 331 + #define H_PKS_CONFIRM_OBJECT_FLUSHED 0x43C 328 332 #define H_RPT_INVALIDATE 0x448 329 333 #define H_SCM_FLUSH 0x44C 330 334 #define H_GET_ENERGY_SCALE_INFO 0x450 331 - #define MAX_HCALL_OPCODE H_GET_ENERGY_SCALE_INFO 335 + #define H_WATCHDOG 0x45C 336 + #define MAX_HCALL_OPCODE H_WATCHDOG 332 337 333 338 /* Scope args for H_SCM_UNBIND_ALL */ 334 339 #define H_UNBIND_SCOPE_ALL (0x1) ··· 362 349 363 350 /* Platform specific hcalls, used by KVM */ 364 351 #define H_RTAS 0xf000 352 + 353 + /* 354 + * Platform specific hcalls, used by QEMU/SLOF. These are ignored by 355 + * KVM and only kept here so we can identify them during tracing. 356 + */ 357 + #define H_LOGICAL_MEMOP 0xF001 358 + #define H_CAS 0XF002 359 + #define H_UPDATE_DT 0XF003 365 360 366 361 /* "Platform specific hcalls", provided by PHYP */ 367 362 #define H_GET_24X7_CATALOG_PAGE 0xF078
+22 -55
arch/powerpc/include/asm/hw_irq.h
··· 113 113 114 114 static inline notrace unsigned long irq_soft_mask_return(void) 115 115 { 116 - unsigned long flags; 117 - 118 - asm volatile( 119 - "lbz %0,%1(13)" 120 - : "=r" (flags) 121 - : "i" (offsetof(struct paca_struct, irq_soft_mask))); 122 - 123 - return flags; 116 + return READ_ONCE(local_paca->irq_soft_mask); 124 117 } 125 118 126 119 /* ··· 123 130 */ 124 131 static inline notrace void irq_soft_mask_set(unsigned long mask) 125 132 { 126 - #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG 127 133 /* 128 134 * The irq mask must always include the STD bit if any are set. 129 135 * ··· 137 145 * unmasks to be replayed, among other things. For now, take 138 146 * the simple approach. 139 147 */ 140 - WARN_ON(mask && !(mask & IRQS_DISABLED)); 141 - #endif 148 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 149 + WARN_ON(mask && !(mask & IRQS_DISABLED)); 142 150 143 - asm volatile( 144 - "stb %0,%1(13)" 145 - : 146 - : "r" (mask), 147 - "i" (offsetof(struct paca_struct, irq_soft_mask)) 148 - : "memory"); 151 + WRITE_ONCE(local_paca->irq_soft_mask, mask); 152 + barrier(); 149 153 } 150 154 151 155 static inline notrace unsigned long irq_soft_mask_set_return(unsigned long mask) 152 156 { 153 - unsigned long flags; 157 + unsigned long flags = irq_soft_mask_return(); 154 158 155 - #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG 156 - WARN_ON(mask && !(mask & IRQS_DISABLED)); 157 - #endif 158 - 159 - asm volatile( 160 - "lbz %0,%1(13); stb %2,%1(13)" 161 - : "=&r" (flags) 162 - : "i" (offsetof(struct paca_struct, irq_soft_mask)), 163 - "r" (mask) 164 - : "memory"); 159 + irq_soft_mask_set(mask); 165 160 166 161 return flags; 167 162 } 168 163 169 164 static inline notrace unsigned long irq_soft_mask_or_return(unsigned long mask) 170 165 { 171 - unsigned long flags, tmp; 166 + unsigned long flags = irq_soft_mask_return(); 172 167 173 - asm volatile( 174 - "lbz %0,%2(13); or %1,%0,%3; stb %1,%2(13)" 175 - : "=&r" (flags), "=r" (tmp) 176 - : "i" (offsetof(struct paca_struct, irq_soft_mask)), 177 - "r" (mask) 178 - : "memory"); 179 - 180 - #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG 181 - WARN_ON((mask | flags) && !((mask | flags) & IRQS_DISABLED)); 182 - #endif 168 + irq_soft_mask_set(flags | mask); 183 169 184 170 return flags; 185 171 } ··· 282 312 flags = irq_soft_mask_set_return(IRQS_ALL_DISABLED); \ 283 313 local_paca->irq_happened |= PACA_IRQ_HARD_DIS; \ 284 314 if (!arch_irqs_disabled_flags(flags)) { \ 285 - asm ("stdx %%r1, 0, %1 ;" \ 286 - : "=m" (local_paca->saved_r1) \ 287 - : "b" (&local_paca->saved_r1)); \ 315 + WRITE_ONCE(local_paca->saved_r1, current_stack_pointer);\ 288 316 trace_hardirqs_off(); \ 289 317 } \ 290 318 } while(0) ··· 321 353 */ 322 354 static inline bool should_hard_irq_enable(void) 323 355 { 324 - #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG 325 - WARN_ON(irq_soft_mask_return() == IRQS_ENABLED); 326 - WARN_ON(mfmsr() & MSR_EE); 327 - #endif 328 - #ifdef CONFIG_PERF_EVENTS 356 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) { 357 + WARN_ON(irq_soft_mask_return() == IRQS_ENABLED); 358 + WARN_ON(mfmsr() & MSR_EE); 359 + } 360 + 361 + if (!IS_ENABLED(CONFIG_PERF_EVENTS)) 362 + return false; 329 363 /* 330 364 * If the PMU is not running, there is not much reason to enable 331 365 * MSR[EE] in irq handlers because any interrupts would just be ··· 342 372 return false; 343 373 344 374 return true; 345 - #else 346 - return false; 347 - #endif 348 375 } 349 376 350 377 /* ··· 349 382 */ 350 383 static inline void do_hard_irq_enable(void) 351 384 { 352 - #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG 353 - WARN_ON(irq_soft_mask_return() == IRQS_ENABLED); 354 - WARN_ON(get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK); 355 - WARN_ON(mfmsr() & MSR_EE); 356 - #endif 385 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) { 386 + WARN_ON(irq_soft_mask_return() == IRQS_ENABLED); 387 + WARN_ON(get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK); 388 + WARN_ON(mfmsr() & MSR_EE); 389 + } 357 390 /* 358 391 * This allows PMI interrupts (and watchdog soft-NMIs) through. 359 392 * There is no other reason to enable this way.
-19
arch/powerpc/include/asm/inst.h
··· 139 139 *(u64 *)ptr = ppc_inst_as_ulong(x); 140 140 } 141 141 142 - #define PPC_INST_STR_LEN sizeof("00000000 00000000") 143 - 144 - static inline char *__ppc_inst_as_str(char str[PPC_INST_STR_LEN], ppc_inst_t x) 145 - { 146 - if (ppc_inst_prefixed(x)) 147 - sprintf(str, "%08x %08x", ppc_inst_val(x), ppc_inst_suffix(x)); 148 - else 149 - sprintf(str, "%08x", ppc_inst_val(x)); 150 - 151 - return str; 152 - } 153 - 154 - #define ppc_inst_as_str(x) \ 155 - ({ \ 156 - char __str[PPC_INST_STR_LEN]; \ 157 - __ppc_inst_as_str(__str, x); \ 158 - __str; \ 159 - }) 160 - 161 142 static inline int __copy_inst_from_kernel_nofault(ppc_inst_t *inst, u32 *src) 162 143 { 163 144 unsigned int val, suffix;
+1
arch/powerpc/include/asm/interrupt.h
··· 69 69 #include <linux/context_tracking.h> 70 70 #include <linux/hardirq.h> 71 71 #include <asm/cputime.h> 72 + #include <asm/firmware.h> 72 73 #include <asm/ftrace.h> 73 74 #include <asm/kprobes.h> 74 75 #include <asm/runlatch.h>
-1
arch/powerpc/include/asm/io.h
··· 33 33 #include <asm/delay.h> 34 34 #include <asm/mmiowb.h> 35 35 #include <asm/mmu.h> 36 - #include <asm/ppc_asm.h> 37 36 38 37 #define SIO_CONFIG_RA 0x398 39 38 #define SIO_CONFIG_RD 0x399
-1
arch/powerpc/include/asm/irq.h
··· 54 54 55 55 void __do_IRQ(struct pt_regs *regs); 56 56 extern void __init init_IRQ(void); 57 - extern void __do_irq(struct pt_regs *regs); 58 57 59 58 int irq_choose_cpu(const struct cpumask *mask); 60 59
+12 -1
arch/powerpc/include/asm/kasan.h
··· 19 19 20 20 #define KASAN_SHADOW_SCALE_SHIFT 3 21 21 22 - #ifdef CONFIG_MODULES 22 + #if defined(CONFIG_MODULES) && defined(CONFIG_PPC32) 23 23 #define KASAN_KERN_START ALIGN_DOWN(PAGE_OFFSET - SZ_256M, SZ_256M) 24 24 #else 25 25 #define KASAN_KERN_START PAGE_OFFSET ··· 39 39 * c00e000000000000 << 3 + a80e000000000000 = c00fc00000000000 40 40 */ 41 41 #define KASAN_SHADOW_END 0xc00fc00000000000UL 42 + 43 + #else 44 + 45 + /* 46 + * The shadow ends before the highest accessible address 47 + * because we don't need a shadow for the shadow. 48 + * But it doesn't hurt to have a shadow for the shadow, 49 + * keep shadow end aligned eases things. 50 + */ 51 + #define KASAN_SHADOW_END 0xc000200000000000UL 52 + 42 53 #endif 43 54 44 55 #ifdef CONFIG_KASAN
+1
arch/powerpc/include/asm/kexec.h
··· 83 83 extern int crash_shutdown_register(crash_shutdown_t handler); 84 84 extern int crash_shutdown_unregister(crash_shutdown_t handler); 85 85 86 + extern void crash_kexec_prepare(void); 86 87 extern void crash_kexec_secondary(struct pt_regs *regs); 87 88 int __init overlaps_crashkernel(unsigned long start, unsigned long size); 88 89 extern void reserve_crashkernel(void);
+1 -1
arch/powerpc/include/asm/kprobes.h
··· 29 29 struct pt_regs; 30 30 struct kprobe; 31 31 32 - typedef ppc_opcode_t kprobe_opcode_t; 32 + typedef u32 kprobe_opcode_t; 33 33 34 34 extern kprobe_opcode_t optinsn_slot; 35 35
-3
arch/powerpc/include/asm/kvm_book3s.h
··· 280 280 extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu); 281 281 282 282 long kvmppc_read_intr(void); 283 - void kvmppc_bad_interrupt(struct pt_regs *regs); 284 - void kvmhv_p9_set_lpcr(struct kvm_split_mode *sip); 285 - void kvmhv_p9_restore_lpcr(struct kvm_split_mode *sip); 286 283 void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr); 287 284 void kvmppc_inject_interrupt_hv(struct kvm_vcpu *vcpu, int vec, u64 srr1_flags); 288 285
+15 -1
arch/powerpc/include/asm/kvm_host.h
··· 523 523 struct kvmppc_book3s_shadow_vcpu *shadow_vcpu; 524 524 #endif 525 525 526 - struct pt_regs regs; 526 + /* 527 + * This is passed along to the HV via H_ENTER_NESTED. Align to 528 + * prevent it crossing a real 4K page. 529 + */ 530 + struct pt_regs regs __aligned(512); 527 531 528 532 struct thread_fp_state fp; 529 533 ··· 834 830 #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 835 831 struct kvmhv_tb_accumulator *cur_activity; /* What we're timing */ 836 832 u64 cur_tb_start; /* when it started */ 833 + #ifdef CONFIG_KVM_BOOK3S_HV_P9_TIMING 834 + struct kvmhv_tb_accumulator vcpu_entry; 835 + struct kvmhv_tb_accumulator vcpu_exit; 836 + struct kvmhv_tb_accumulator in_guest; 837 + struct kvmhv_tb_accumulator hcall; 838 + struct kvmhv_tb_accumulator pg_fault; 839 + struct kvmhv_tb_accumulator guest_entry; 840 + struct kvmhv_tb_accumulator guest_exit; 841 + #else 837 842 struct kvmhv_tb_accumulator rm_entry; /* real-mode entry code */ 838 843 struct kvmhv_tb_accumulator rm_intr; /* real-mode intr handling */ 839 844 struct kvmhv_tb_accumulator rm_exit; /* real-mode exit code */ 840 845 struct kvmhv_tb_accumulator guest_time; /* guest execution */ 841 846 struct kvmhv_tb_accumulator cede_time; /* time napping inside guest */ 847 + #endif 842 848 #endif /* CONFIG_KVM_BOOK3S_HV_EXIT_TIMING */ 843 849 }; 844 850
-2
arch/powerpc/include/asm/machdep.h
··· 8 8 #include <linux/dma-mapping.h> 9 9 #include <linux/export.h> 10 10 11 - #include <asm/setup.h> 12 - 13 11 struct pt_regs; 14 12 struct pci_bus; 15 13 struct device_node;
+1
arch/powerpc/include/asm/mman.h
··· 12 12 #include <linux/mm.h> 13 13 #include <linux/pkeys.h> 14 14 #include <asm/cpu_has_feature.h> 15 + #include <asm/firmware.h> 15 16 16 17 static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, 17 18 unsigned long pkey)
-12
arch/powerpc/include/asm/mmu.h
··· 96 96 */ 97 97 #define MMU_FTR_NEED_DTLB_SW_LRU ASM_CONST(0x00200000) 98 98 99 - /* Enable use of TLB reservation. Processor should support tlbsrx. 100 - * instruction and MAS0[WQ]. 101 - */ 102 - #define MMU_FTR_USE_TLBRSRV ASM_CONST(0x00800000) 103 - 104 - /* Use paired MAS registers (MAS7||MAS3, etc.) 105 - */ 106 - #define MMU_FTR_USE_PAIRED_MAS ASM_CONST(0x01000000) 107 - 108 99 /* Doesn't support the B bit (1T segment) in SLBIE 109 100 */ 110 101 #define MMU_FTR_NO_SLBIE_B ASM_CONST(0x02000000) ··· 170 179 #endif 171 180 #ifdef CONFIG_PPC_83xx 172 181 MMU_FTR_NEED_DTLB_SW_LRU | 173 - #endif 174 - #ifdef CONFIG_PPC_BOOK3E_64 175 - MMU_FTR_USE_TLBRSRV | MMU_FTR_USE_PAIRED_MAS | 176 182 #endif 177 183 #ifdef CONFIG_PPC_BOOK3S_64 178 184 MMU_FTR_KERNEL_RO |
+2 -2
arch/powerpc/include/asm/mpc52xx.h
··· 15 15 16 16 #ifndef __ASSEMBLY__ 17 17 #include <asm/types.h> 18 - #include <asm/prom.h> 19 18 #include <asm/mpc5xxx.h> 20 19 #endif /* __ASSEMBLY__ */ 21 20 ··· 267 268 268 269 #ifndef __ASSEMBLY__ 269 270 271 + struct device_node; 272 + 270 273 /* mpc52xx_common.c */ 271 274 extern void mpc5200_setup_xlb_arbiter(void); 272 275 extern void mpc52xx_declare_of_platform_devices(void); 273 276 extern int mpc5200_psc_ac97_gpio_reset(int psc_number); 274 277 extern void mpc52xx_map_common_devices(void); 275 278 extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv); 276 - extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node); 277 279 extern void __noreturn mpc52xx_restart(char *cmd); 278 280 279 281 /* mpc52xx_gpt.c */
+8 -1
arch/powerpc/include/asm/mpc5xxx.h
··· 11 11 #ifndef __ASM_POWERPC_MPC5xxx_H__ 12 12 #define __ASM_POWERPC_MPC5xxx_H__ 13 13 14 - extern unsigned long mpc5xxx_get_bus_frequency(struct device_node *node); 14 + #include <linux/property.h> 15 + 16 + unsigned long mpc5xxx_fwnode_get_bus_frequency(struct fwnode_handle *fwnode); 17 + 18 + static inline unsigned long mpc5xxx_get_bus_frequency(struct device *dev) 19 + { 20 + return mpc5xxx_fwnode_get_bus_frequency(dev_fwnode(dev)); 21 + } 15 22 16 23 #endif /* __ASM_POWERPC_MPC5xxx_H__ */ 17 24
+2
arch/powerpc/include/asm/nmi.h
··· 5 5 #ifdef CONFIG_PPC_WATCHDOG 6 6 extern void arch_touch_nmi_watchdog(void); 7 7 long soft_nmi_interrupt(struct pt_regs *regs); 8 + void watchdog_nmi_set_timeout_pct(u64 pct); 8 9 #else 9 10 static inline void arch_touch_nmi_watchdog(void) {} 11 + static inline void watchdog_nmi_set_timeout_pct(u64 pct) {} 10 12 #endif 11 13 12 14 #ifdef CONFIG_NMI_IPI
+4 -1
arch/powerpc/include/asm/nohash/64/pgalloc.h
··· 15 15 }; 16 16 extern struct vmemmap_backing *vmemmap_list; 17 17 18 - #define p4d_populate(MM, P4D, PUD) p4d_set(P4D, (unsigned long)PUD) 18 + static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4d, pud_t *pud) 19 + { 20 + p4d_set(p4d, (unsigned long)pud); 21 + } 19 22 20 23 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) 21 24 {
+5 -18
arch/powerpc/include/asm/nohash/64/pgtable.h
··· 25 25 /* 26 26 * Define the address range of the kernel non-linear virtual area 27 27 */ 28 - #define KERN_VIRT_START ASM_CONST(0x8000000000000000) 28 + #define KERN_VIRT_START ASM_CONST(0xc000100000000000) 29 29 #define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000) 30 30 31 31 /* ··· 38 38 #define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) 39 39 40 40 /* 41 - * The second half of the kernel virtual space is used for IO mappings, 41 + * The third quarter of the kernel virtual space is used for IO mappings, 42 42 * it's itself carved into the PIO region (ISA and PHB IO space) and 43 43 * the ioremap space 44 44 * 45 45 * ISA_IO_BASE = KERN_IO_START, 64K reserved area 46 46 * PHB_IO_BASE = ISA_IO_BASE + 64K to ISA_IO_BASE + 2G, PHB IO spaces 47 - * IOREMAP_BASE = ISA_IO_BASE + 2G to VMALLOC_START + PGTABLE_RANGE 47 + * IOREMAP_BASE = ISA_IO_BASE + 2G to KERN_IO_START + KERN_IO_SIZE 48 48 */ 49 49 #define KERN_IO_START (KERN_VIRT_START + (KERN_VIRT_SIZE >> 1)) 50 + #define KERN_IO_SIZE (KERN_VIRT_SIZE >> 2) 50 51 #define FULL_IO_SIZE 0x80000000ul 51 52 #define ISA_IO_BASE (KERN_IO_START) 52 53 #define ISA_IO_END (KERN_IO_START + 0x10000ul) ··· 55 54 #define PHB_IO_END (KERN_IO_START + FULL_IO_SIZE) 56 55 #define IOREMAP_BASE (PHB_IO_END) 57 56 #define IOREMAP_START (ioremap_bot) 58 - #define IOREMAP_END (KERN_VIRT_START + KERN_VIRT_SIZE - FIXADDR_SIZE) 57 + #define IOREMAP_END (KERN_IO_START + KERN_IO_SIZE - FIXADDR_SIZE) 59 58 #define FIXADDR_SIZE SZ_32M 60 - 61 - 62 - /* 63 - * Region IDs 64 - */ 65 - #define REGION_SHIFT 60UL 66 - #define REGION_MASK (0xfUL << REGION_SHIFT) 67 - #define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) 68 - 69 - #define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START)) 70 - #define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET)) 71 - #define USER_REGION_ID (0UL) 72 59 73 60 /* 74 61 * Defines the address of the vmemap area, in its own region on ··· 71 82 * Include the PTE bits definitions 72 83 */ 73 84 #include <asm/nohash/pte-book3e.h> 74 - 75 - #define _PAGE_SAO 0 76 85 77 86 #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) 78 87
+1 -1
arch/powerpc/include/asm/nohash/pgtable.h
··· 193 193 if (IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_PTE_64BIT) && !percpu) { 194 194 __asm__ __volatile__("\ 195 195 stw%X0 %2,%0\n\ 196 - eieio\n\ 196 + mbar\n\ 197 197 stw%X1 %L2,%1" 198 198 : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) 199 199 : "r" (pte) : "memory");
+4
arch/powerpc/include/asm/pci-bridge.h
··· 170 170 return bus->sysdata; 171 171 } 172 172 173 + #ifdef CONFIG_PPC_PMAC 173 174 extern int pci_device_from_OF_node(struct device_node *node, 174 175 u8 *bus, u8 *devfn); 176 + #endif 175 177 #ifndef CONFIG_PPC64 176 178 179 + #ifdef CONFIG_PPC_CHRP 177 180 extern void pci_create_OF_bus_map(void); 181 + #endif 178 182 179 183 #else /* CONFIG_PPC64 */ 180 184
-1
arch/powerpc/include/asm/pci.h
··· 14 14 15 15 #include <asm/machdep.h> 16 16 #include <asm/io.h> 17 - #include <asm/prom.h> 18 17 #include <asm/pci-bridge.h> 19 18 20 19 /* Return values for pci_controller_ops.probe_mode function */
+2 -3
arch/powerpc/include/asm/plpar_wrappers.h
··· 43 43 set_cede_latency_hint(latency_hint); 44 44 45 45 rc = cede_processor(); 46 - #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG 46 + 47 47 /* Ensure that H_CEDE returns with IRQs on */ 48 - if (WARN_ON(!(mfmsr() & MSR_EE))) 48 + if (WARN_ON(IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG) && !(mfmsr() & MSR_EE))) 49 49 __hard_irq_enable(); 50 - #endif 51 50 52 51 set_cede_latency_hint(old_latency_hint); 53 52
+3 -1
arch/powerpc/include/asm/ppc-opcode.h
··· 290 290 #define PPC_INST_STRING 0x7c00042a 291 291 #define PPC_INST_STRING_MASK 0xfc0007fe 292 292 #define PPC_INST_STRING_GEN_MASK 0xfc00067e 293 - #define PPC_INST_SETB 0x7c000100 294 293 #define PPC_INST_STSWI 0x7c0005aa 295 294 #define PPC_INST_STSWX 0x7c00052a 296 295 #define PPC_INST_TRECHKPT 0x7c0007dd ··· 580 581 581 582 #define PPC_RAW_BRANCH(offset) (0x48000000 | PPC_LI(offset)) 582 583 #define PPC_RAW_BL(offset) (0x48000001 | PPC_LI(offset)) 584 + #define PPC_RAW_TW(t0, a, b) (0x7f000008 | ___PPC_RS(t0) | ___PPC_RA(a) | ___PPC_RB(b)) 585 + #define PPC_RAW_TRAP() PPC_RAW_TW(31, 0, 0) 586 + #define PPC_RAW_SETB(t, bfa) (0x7c000100 | ___PPC_RT(t) | ___PPC_RA((bfa) << 2)) 583 587 584 588 /* Deal with instructions that older assemblers aren't aware of */ 585 589 #define PPC_BCCTR_FLUSH stringify_in_c(.long PPC_INST_BCCTR_FLUSH)
+2 -2
arch/powerpc/include/asm/probes.h
··· 9 9 */ 10 10 #include <linux/types.h> 11 11 #include <asm/disassemble.h> 12 + #include <asm/ppc-opcode.h> 12 13 13 - typedef u32 ppc_opcode_t; 14 - #define BREAKPOINT_INSTRUCTION 0x7fe00008 /* trap */ 14 + #define BREAKPOINT_INSTRUCTION PPC_RAW_TRAP() /* trap */ 15 15 16 16 /* Trap definitions per ISA */ 17 17 #define IS_TW(instr) (((instr) & 0xfc0007fe) == 0x7c000008)
+3 -8
arch/powerpc/include/asm/prom.h
··· 12 12 * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp. 13 13 */ 14 14 #include <linux/types.h> 15 - #include <asm/irq.h> 16 - #include <linux/atomic.h> 15 + #include <asm/firmware.h> 17 16 18 - /* These includes should be removed once implicit includes are cleaned up. */ 19 - #include <linux/of.h> 20 - #include <linux/of_fdt.h> 21 - #include <linux/of_address.h> 22 - #include <linux/of_irq.h> 23 - #include <linux/platform_device.h> 17 + struct device_node; 18 + struct property; 24 19 25 20 #define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ 26 21 #define OF_DT_END_NODE 0x2 /* End node */
+5 -1
arch/powerpc/include/asm/setup.h
··· 12 12 extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); 13 13 14 14 struct device_node; 15 - extern void note_scsi_host(struct device_node *, void *); 16 15 17 16 /* Used in very early kernel initialization. */ 18 17 extern unsigned long reloc_offset(void); ··· 83 84 #endif 84 85 void __init early_setup(unsigned long dt_ptr); 85 86 void early_setup_secondary(void); 87 + 88 + /* prom_init (OpenFirmware) */ 89 + unsigned long __init prom_init(unsigned long r3, unsigned long r4, 90 + unsigned long pp, unsigned long r6, 91 + unsigned long r7, unsigned long kbase); 86 92 87 93 #endif /* !__ASSEMBLY__ */ 88 94
+4 -1
arch/powerpc/include/asm/synch.h
··· 14 14 15 15 static inline void eieio(void) 16 16 { 17 - __asm__ __volatile__ ("eieio" : : : "memory"); 17 + if (IS_ENABLED(CONFIG_BOOKE)) 18 + __asm__ __volatile__ ("mbar" : : : "memory"); 19 + else 20 + __asm__ __volatile__ ("eieio" : : : "memory"); 18 21 } 19 22 20 23 static inline void isync(void)
-1
arch/powerpc/include/asm/uaccess.h
··· 2 2 #ifndef _ARCH_POWERPC_UACCESS_H 3 3 #define _ARCH_POWERPC_UACCESS_H 4 4 5 - #include <asm/ppc_asm.h> 6 5 #include <asm/processor.h> 7 6 #include <asm/page.h> 8 7 #include <asm/extable.h>
+1 -1
arch/powerpc/include/asm/uprobes.h
··· 12 12 #include <linux/notifier.h> 13 13 #include <asm/probes.h> 14 14 15 - typedef ppc_opcode_t uprobe_opcode_t; 15 + typedef u32 uprobe_opcode_t; 16 16 17 17 #define MAX_UINSN_BYTES 8 18 18 #define UPROBE_XOL_SLOT_BYTES (MAX_UINSN_BYTES)
+1 -1
arch/powerpc/include/asm/word-at-a-time.h
··· 7 7 8 8 #include <linux/kernel.h> 9 9 #include <asm/asm-compat.h> 10 - #include <asm/ppc_asm.h> 10 + #include <asm/extable.h> 11 11 12 12 #ifdef __BIG_ENDIAN__ 13 13
+9 -2
arch/powerpc/kernel/Makefile
··· 54 54 CFLAGS_btext.o += -DDISABLE_BRANCH_PROFILING 55 55 endif 56 56 57 + #ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET 58 + # Remove stack protector to avoid triggering unneeded stack canary 59 + # checks due to randomize_kstack_offset. 60 + CFLAGS_REMOVE_syscall.o = -fstack-protector -fstack-protector-strong 61 + CFLAGS_syscall.o += -fno-stack-protector 62 + #endif 63 + 57 64 obj-y := cputable.o syscalls.o \ 58 65 irq.o align.o signal_$(BITS).o pmc.o vdso.o \ 59 66 process.o systbl.o idle.o \ ··· 69 62 udbg.o misc.o io.o misc_$(BITS).o \ 70 63 of_platform.o prom_parse.o firmware.o \ 71 64 hw_breakpoint_constraints.o interrupt.o \ 72 - kdebugfs.o stacktrace.o 65 + kdebugfs.o stacktrace.o syscall.o 73 66 obj-y += ptrace/ 74 - obj-$(CONFIG_PPC64) += setup_64.o \ 67 + obj-$(CONFIG_PPC64) += setup_64.o irq_64.o\ 75 68 paca.o nvram_64.o note.o 76 69 obj-$(CONFIG_COMPAT) += sys_ppc32.o signal_32.o 77 70 obj-$(CONFIG_VDSO32) += vdso32_wrapper.o
+1 -1
arch/powerpc/kernel/asm-offsets.c
··· 379 379 OFFSET(VCPU_SPRG2, kvm_vcpu, arch.shregs.sprg2); 380 380 OFFSET(VCPU_SPRG3, kvm_vcpu, arch.shregs.sprg3); 381 381 #endif 382 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 382 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 383 383 OFFSET(VCPU_TB_RMENTRY, kvm_vcpu, arch.rm_entry); 384 384 OFFSET(VCPU_TB_RMINTR, kvm_vcpu, arch.rm_intr); 385 385 OFFSET(VCPU_TB_RMEXIT, kvm_vcpu, arch.rm_exit);
+1 -1
arch/powerpc/kernel/btext.c
··· 73 73 * the display during identify_machine() and MMU_Init() 74 74 * 75 75 * The display is mapped to virtual address 0xD0000000, rather 76 - * than 1:1, because some some CHRP machines put the frame buffer 76 + * than 1:1, because some CHRP machines put the frame buffer 77 77 * in the region starting at 0xC0000000 (PAGE_OFFSET). 78 78 * This mapping is temporary and will disappear as soon as the 79 79 * setup done by MMU_Init() is applied.
+2 -65
arch/powerpc/kernel/cputable.c
··· 149 149 .pmc_type = PPC_PMC_IBM, 150 150 .cpu_setup = __setup_cpu_ppc970, 151 151 .cpu_restore = __restore_cpu_ppc970, 152 - .oprofile_cpu_type = "ppc64/970", 153 152 .platform = "ppc970", 154 153 }, 155 154 { /* PPC970FX */ ··· 165 166 .pmc_type = PPC_PMC_IBM, 166 167 .cpu_setup = __setup_cpu_ppc970, 167 168 .cpu_restore = __restore_cpu_ppc970, 168 - .oprofile_cpu_type = "ppc64/970", 169 169 .platform = "ppc970", 170 170 }, 171 171 { /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */ ··· 181 183 .pmc_type = PPC_PMC_IBM, 182 184 .cpu_setup = __setup_cpu_ppc970, 183 185 .cpu_restore = __restore_cpu_ppc970, 184 - .oprofile_cpu_type = "ppc64/970MP", 185 186 .platform = "ppc970", 186 187 }, 187 188 { /* PPC970MP */ ··· 197 200 .pmc_type = PPC_PMC_IBM, 198 201 .cpu_setup = __setup_cpu_ppc970MP, 199 202 .cpu_restore = __restore_cpu_ppc970, 200 - .oprofile_cpu_type = "ppc64/970MP", 201 203 .platform = "ppc970", 202 204 }, 203 205 { /* PPC970GX */ ··· 212 216 .num_pmcs = 8, 213 217 .pmc_type = PPC_PMC_IBM, 214 218 .cpu_setup = __setup_cpu_ppc970, 215 - .oprofile_cpu_type = "ppc64/970", 216 219 .platform = "ppc970", 217 220 }, 218 221 { /* Power5 GR */ ··· 225 230 .dcache_bsize = 128, 226 231 .num_pmcs = 6, 227 232 .pmc_type = PPC_PMC_IBM, 228 - .oprofile_cpu_type = "ppc64/power5", 229 233 .platform = "power5", 230 234 }, 231 235 { /* Power5++ */ ··· 237 243 .icache_bsize = 128, 238 244 .dcache_bsize = 128, 239 245 .num_pmcs = 6, 240 - .oprofile_cpu_type = "ppc64/power5++", 241 246 .platform = "power5+", 242 247 }, 243 248 { /* Power5 GS */ ··· 250 257 .dcache_bsize = 128, 251 258 .num_pmcs = 6, 252 259 .pmc_type = PPC_PMC_IBM, 253 - .oprofile_cpu_type = "ppc64/power5+", 254 260 .platform = "power5+", 255 261 }, 256 262 { /* POWER6 in P5+ mode; 2.04-compliant processor */ ··· 261 269 .mmu_features = MMU_FTRS_POWER5, 262 270 .icache_bsize = 128, 263 271 .dcache_bsize = 128, 264 - .oprofile_cpu_type = "ppc64/ibm-compat-v1", 265 272 .platform = "power5+", 266 273 }, 267 274 { /* Power6 */ ··· 275 284 .dcache_bsize = 128, 276 285 .num_pmcs = 6, 277 286 .pmc_type = PPC_PMC_IBM, 278 - .oprofile_cpu_type = "ppc64/power6", 279 287 .platform = "power6x", 280 288 }, 281 289 { /* 2.05-compliant processor, i.e. Power6 "architected" mode */ ··· 286 296 .mmu_features = MMU_FTRS_POWER6, 287 297 .icache_bsize = 128, 288 298 .dcache_bsize = 128, 289 - .oprofile_cpu_type = "ppc64/ibm-compat-v1", 290 299 .platform = "power6", 291 300 }, 292 301 { /* 2.06-compliant processor, i.e. Power7 "architected" mode */ ··· 298 309 .mmu_features = MMU_FTRS_POWER7, 299 310 .icache_bsize = 128, 300 311 .dcache_bsize = 128, 301 - .oprofile_cpu_type = "ppc64/ibm-compat-v1", 302 312 .cpu_setup = __setup_cpu_power7, 303 313 .cpu_restore = __restore_cpu_power7, 304 314 .machine_check_early = __machine_check_early_realmode_p7, ··· 313 325 .mmu_features = MMU_FTRS_POWER8, 314 326 .icache_bsize = 128, 315 327 .dcache_bsize = 128, 316 - .oprofile_cpu_type = "ppc64/ibm-compat-v1", 317 328 .cpu_setup = __setup_cpu_power8, 318 329 .cpu_restore = __restore_cpu_power8, 319 330 .machine_check_early = __machine_check_early_realmode_p8, ··· 328 341 .mmu_features = MMU_FTRS_POWER9, 329 342 .icache_bsize = 128, 330 343 .dcache_bsize = 128, 331 - .oprofile_cpu_type = "ppc64/ibm-compat-v1", 332 344 .cpu_setup = __setup_cpu_power9, 333 345 .cpu_restore = __restore_cpu_power9, 334 346 .platform = "power9", ··· 342 356 .mmu_features = MMU_FTRS_POWER10, 343 357 .icache_bsize = 128, 344 358 .dcache_bsize = 128, 345 - .oprofile_cpu_type = "ppc64/ibm-compat-v1", 346 359 .cpu_setup = __setup_cpu_power10, 347 360 .cpu_restore = __restore_cpu_power10, 348 361 .platform = "power10", ··· 358 373 .dcache_bsize = 128, 359 374 .num_pmcs = 6, 360 375 .pmc_type = PPC_PMC_IBM, 361 - .oprofile_cpu_type = "ppc64/power7", 362 376 .cpu_setup = __setup_cpu_power7, 363 377 .cpu_restore = __restore_cpu_power7, 364 378 .machine_check_early = __machine_check_early_realmode_p7, ··· 375 391 .dcache_bsize = 128, 376 392 .num_pmcs = 6, 377 393 .pmc_type = PPC_PMC_IBM, 378 - .oprofile_cpu_type = "ppc64/power7", 379 394 .cpu_setup = __setup_cpu_power7, 380 395 .cpu_restore = __restore_cpu_power7, 381 396 .machine_check_early = __machine_check_early_realmode_p7, ··· 392 409 .dcache_bsize = 128, 393 410 .num_pmcs = 6, 394 411 .pmc_type = PPC_PMC_IBM, 395 - .oprofile_cpu_type = "ppc64/power8", 396 412 .cpu_setup = __setup_cpu_power8, 397 413 .cpu_restore = __restore_cpu_power8, 398 414 .machine_check_early = __machine_check_early_realmode_p8, ··· 409 427 .dcache_bsize = 128, 410 428 .num_pmcs = 6, 411 429 .pmc_type = PPC_PMC_IBM, 412 - .oprofile_cpu_type = "ppc64/power8", 413 430 .cpu_setup = __setup_cpu_power8, 414 431 .cpu_restore = __restore_cpu_power8, 415 432 .machine_check_early = __machine_check_early_realmode_p8, ··· 426 445 .dcache_bsize = 128, 427 446 .num_pmcs = 6, 428 447 .pmc_type = PPC_PMC_IBM, 429 - .oprofile_cpu_type = "ppc64/power8", 430 448 .cpu_setup = __setup_cpu_power8, 431 449 .cpu_restore = __restore_cpu_power8, 432 450 .machine_check_early = __machine_check_early_realmode_p8, ··· 443 463 .dcache_bsize = 128, 444 464 .num_pmcs = 6, 445 465 .pmc_type = PPC_PMC_IBM, 446 - .oprofile_cpu_type = "ppc64/power9", 447 466 .cpu_setup = __setup_cpu_power9, 448 467 .cpu_restore = __restore_cpu_power9, 449 468 .machine_check_early = __machine_check_early_realmode_p9, ··· 460 481 .dcache_bsize = 128, 461 482 .num_pmcs = 6, 462 483 .pmc_type = PPC_PMC_IBM, 463 - .oprofile_cpu_type = "ppc64/power9", 464 484 .cpu_setup = __setup_cpu_power9, 465 485 .cpu_restore = __restore_cpu_power9, 466 486 .machine_check_early = __machine_check_early_realmode_p9, ··· 477 499 .dcache_bsize = 128, 478 500 .num_pmcs = 6, 479 501 .pmc_type = PPC_PMC_IBM, 480 - .oprofile_cpu_type = "ppc64/power9", 481 502 .cpu_setup = __setup_cpu_power9, 482 503 .cpu_restore = __restore_cpu_power9, 483 504 .machine_check_early = __machine_check_early_realmode_p9, ··· 494 517 .dcache_bsize = 128, 495 518 .num_pmcs = 6, 496 519 .pmc_type = PPC_PMC_IBM, 497 - .oprofile_cpu_type = "ppc64/power9", 498 520 .cpu_setup = __setup_cpu_power9, 499 521 .cpu_restore = __restore_cpu_power9, 500 522 .machine_check_early = __machine_check_early_realmode_p9, ··· 511 535 .dcache_bsize = 128, 512 536 .num_pmcs = 6, 513 537 .pmc_type = PPC_PMC_IBM, 514 - .oprofile_cpu_type = "ppc64/power10", 515 538 .cpu_setup = __setup_cpu_power10, 516 539 .cpu_restore = __restore_cpu_power10, 517 540 .machine_check_early = __machine_check_early_realmode_p10, ··· 529 554 .dcache_bsize = 128, 530 555 .num_pmcs = 4, 531 556 .pmc_type = PPC_PMC_IBM, 532 - .oprofile_cpu_type = "ppc64/cell-be", 533 557 .platform = "ppc-cell-be", 534 558 }, 535 559 { /* PA Semi PA6T */ ··· 544 570 .pmc_type = PPC_PMC_PA6T, 545 571 .cpu_setup = __setup_cpu_pa6t, 546 572 .cpu_restore = __restore_cpu_pa6t, 547 - .oprofile_cpu_type = "ppc64/pa6t", 548 573 .platform = "pa6t", 549 574 }, 550 575 { /* default match */ ··· 707 734 .cpu_setup = __setup_cpu_750, 708 735 .machine_check = machine_check_generic, 709 736 .platform = "ppc750", 710 - .oprofile_cpu_type = "ppc/750", 711 737 }, 712 738 { /* 745/755 */ 713 739 .pvr_mask = 0xfffff000, ··· 737 765 .cpu_setup = __setup_cpu_750, 738 766 .machine_check = machine_check_generic, 739 767 .platform = "ppc750", 740 - .oprofile_cpu_type = "ppc/750", 741 768 }, 742 769 { /* 750FX rev 2.0 must disable HID0[DPM] */ 743 770 .pvr_mask = 0xffffffff, ··· 752 781 .cpu_setup = __setup_cpu_750, 753 782 .machine_check = machine_check_generic, 754 783 .platform = "ppc750", 755 - .oprofile_cpu_type = "ppc/750", 756 784 }, 757 785 { /* 750FX (All revs except 2.0) */ 758 786 .pvr_mask = 0xffff0000, ··· 767 797 .cpu_setup = __setup_cpu_750fx, 768 798 .machine_check = machine_check_generic, 769 799 .platform = "ppc750", 770 - .oprofile_cpu_type = "ppc/750", 771 800 }, 772 801 { /* 750GX */ 773 802 .pvr_mask = 0xffff0000, ··· 782 813 .cpu_setup = __setup_cpu_750fx, 783 814 .machine_check = machine_check_generic, 784 815 .platform = "ppc750", 785 - .oprofile_cpu_type = "ppc/750", 786 816 }, 787 817 { /* 740/750 (L2CR bit need fixup for 740) */ 788 818 .pvr_mask = 0xffff0000, ··· 859 891 .num_pmcs = 6, 860 892 .pmc_type = PPC_PMC_G4, 861 893 .cpu_setup = __setup_cpu_745x, 862 - .oprofile_cpu_type = "ppc/7450", 863 894 .machine_check = machine_check_generic, 864 895 .platform = "ppc7450", 865 896 }, ··· 875 908 .num_pmcs = 6, 876 909 .pmc_type = PPC_PMC_G4, 877 910 .cpu_setup = __setup_cpu_745x, 878 - .oprofile_cpu_type = "ppc/7450", 879 911 .machine_check = machine_check_generic, 880 912 .platform = "ppc7450", 881 913 }, ··· 891 925 .num_pmcs = 6, 892 926 .pmc_type = PPC_PMC_G4, 893 927 .cpu_setup = __setup_cpu_745x, 894 - .oprofile_cpu_type = "ppc/7450", 895 928 .machine_check = machine_check_generic, 896 929 .platform = "ppc7450", 897 930 }, ··· 907 942 .num_pmcs = 6, 908 943 .pmc_type = PPC_PMC_G4, 909 944 .cpu_setup = __setup_cpu_745x, 910 - .oprofile_cpu_type = "ppc/7450", 911 945 .machine_check = machine_check_generic, 912 946 .platform = "ppc7450", 913 947 }, ··· 923 959 .num_pmcs = 6, 924 960 .pmc_type = PPC_PMC_G4, 925 961 .cpu_setup = __setup_cpu_745x, 926 - .oprofile_cpu_type = "ppc/7450", 927 962 .machine_check = machine_check_generic, 928 963 .platform = "ppc7450", 929 964 }, ··· 939 976 .num_pmcs = 6, 940 977 .pmc_type = PPC_PMC_G4, 941 978 .cpu_setup = __setup_cpu_745x, 942 - .oprofile_cpu_type = "ppc/7450", 943 979 .machine_check = machine_check_generic, 944 980 .platform = "ppc7450", 945 981 }, ··· 955 993 .num_pmcs = 6, 956 994 .pmc_type = PPC_PMC_G4, 957 995 .cpu_setup = __setup_cpu_745x, 958 - .oprofile_cpu_type = "ppc/7450", 959 996 .machine_check = machine_check_generic, 960 997 .platform = "ppc7450", 961 998 }, ··· 971 1010 .num_pmcs = 6, 972 1011 .pmc_type = PPC_PMC_G4, 973 1012 .cpu_setup = __setup_cpu_745x, 974 - .oprofile_cpu_type = "ppc/7450", 975 1013 .machine_check = machine_check_generic, 976 1014 .platform = "ppc7450", 977 1015 }, ··· 986 1026 .num_pmcs = 6, 987 1027 .pmc_type = PPC_PMC_G4, 988 1028 .cpu_setup = __setup_cpu_745x, 989 - .oprofile_cpu_type = "ppc/7450", 990 1029 .machine_check = machine_check_generic, 991 1030 .platform = "ppc7450", 992 1031 }, ··· 1002 1043 .num_pmcs = 6, 1003 1044 .pmc_type = PPC_PMC_G4, 1004 1045 .cpu_setup = __setup_cpu_745x, 1005 - .oprofile_cpu_type = "ppc/7450", 1006 1046 .machine_check = machine_check_generic, 1007 1047 .platform = "ppc7450", 1008 1048 }, ··· 1018 1060 .num_pmcs = 6, 1019 1061 .pmc_type = PPC_PMC_G4, 1020 1062 .cpu_setup = __setup_cpu_745x, 1021 - .oprofile_cpu_type = "ppc/7450", 1022 1063 .machine_check = machine_check_generic, 1023 1064 .platform = "ppc7450", 1024 1065 }, ··· 1129 1172 .cpu_setup = __setup_cpu_603, 1130 1173 .machine_check = machine_check_83xx, 1131 1174 .num_pmcs = 4, 1132 - .oprofile_cpu_type = "ppc/e300", 1133 1175 .platform = "ppc603", 1134 1176 }, 1135 1177 { /* e300c4 (e300c1, plus one IU) */ ··· 1144 1188 .cpu_setup = __setup_cpu_603, 1145 1189 .machine_check = machine_check_83xx, 1146 1190 .num_pmcs = 4, 1147 - .oprofile_cpu_type = "ppc/e300", 1148 1191 .platform = "ppc603", 1149 1192 }, 1150 1193 #endif ··· 1839 1884 .icache_bsize = 32, 1840 1885 .dcache_bsize = 32, 1841 1886 .num_pmcs = 4, 1842 - .oprofile_cpu_type = "ppc/e500", 1843 1887 .cpu_setup = __setup_cpu_e500v1, 1844 1888 .machine_check = machine_check_e500, 1845 1889 .platform = "ppc8540", ··· 1857 1903 .icache_bsize = 32, 1858 1904 .dcache_bsize = 32, 1859 1905 .num_pmcs = 4, 1860 - .oprofile_cpu_type = "ppc/e500", 1861 1906 .cpu_setup = __setup_cpu_e500v2, 1862 1907 .machine_check = machine_check_e500, 1863 1908 .platform = "ppc8548", ··· 1875 1922 .icache_bsize = 64, 1876 1923 .dcache_bsize = 64, 1877 1924 .num_pmcs = 4, 1878 - .oprofile_cpu_type = "ppc/e500mc", 1879 1925 .cpu_setup = __setup_cpu_e500mc, 1880 1926 .machine_check = machine_check_e500mc, 1881 1927 .platform = "ppce500mc", ··· 1895 1943 .icache_bsize = 64, 1896 1944 .dcache_bsize = 64, 1897 1945 .num_pmcs = 4, 1898 - .oprofile_cpu_type = "ppc/e500mc", 1899 1946 .cpu_setup = __setup_cpu_e5500, 1900 1947 #ifndef CONFIG_PPC32 1901 1948 .cpu_restore = __restore_cpu_e5500, ··· 1916 1965 .icache_bsize = 64, 1917 1966 .dcache_bsize = 64, 1918 1967 .num_pmcs = 6, 1919 - .oprofile_cpu_type = "ppc/e6500", 1920 1968 .cpu_setup = __setup_cpu_e6500, 1921 1969 #ifndef CONFIG_PPC32 1922 1970 .cpu_restore = __restore_cpu_e6500, ··· 1983 2033 t->pmc_type = old.pmc_type; 1984 2034 1985 2035 /* 1986 - * If we have passed through this logic once before and 1987 - * have pulled the default case because the real PVR was 1988 - * not found inside cpu_specs[], then we are possibly 1989 - * running in compatibility mode. In that case, let the 1990 - * oprofiler know which set of compatibility counters to 1991 - * pull from by making sure the oprofile_cpu_type string 1992 - * is set to that of compatibility mode. If the 1993 - * oprofile_cpu_type already has a value, then we are 1994 - * possibly overriding a real PVR with a logical one, 1995 - * and, in that case, keep the current value for 1996 - * oprofile_cpu_type. Furthermore, let's ensure that the 2036 + * Let's ensure that the 1997 2037 * fix for the PMAO bug is enabled on compatibility mode. 1998 2038 */ 1999 - if (old.oprofile_cpu_type != NULL) { 2000 - t->oprofile_cpu_type = old.oprofile_cpu_type; 2001 - t->cpu_features |= old.cpu_features & CPU_FTR_PMAO_BUG; 2002 - } 2039 + t->cpu_features |= old.cpu_features & CPU_FTR_PMAO_BUG; 2003 2040 } 2004 2041 2005 2042 *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
+1
arch/powerpc/kernel/dawr.c
··· 11 11 #include <linux/debugfs.h> 12 12 #include <asm/machdep.h> 13 13 #include <asm/hvcall.h> 14 + #include <asm/firmware.h> 14 15 15 16 bool dawr_force_enable; 16 17 EXPORT_SYMBOL_GPL(dawr_force_enable);
-4
arch/powerpc/kernel/dt_cpu_ftrs.c
··· 102 102 .dcache_bsize = 32, /* cache info init. */ 103 103 .num_pmcs = 0, 104 104 .pmc_type = PPC_PMC_DEFAULT, 105 - .oprofile_cpu_type = NULL, 106 105 .cpu_setup = NULL, 107 106 .cpu_restore = __restore_cpu_cpufeatures, 108 107 .machine_check_early = NULL, ··· 386 387 387 388 cur_cpu_spec->num_pmcs = 6; 388 389 cur_cpu_spec->pmc_type = PPC_PMC_IBM; 389 - cur_cpu_spec->oprofile_cpu_type = "ppc64/power8"; 390 390 391 391 return 1; 392 392 } ··· 421 423 422 424 cur_cpu_spec->num_pmcs = 6; 423 425 cur_cpu_spec->pmc_type = PPC_PMC_IBM; 424 - cur_cpu_spec->oprofile_cpu_type = "ppc64/power9"; 425 426 426 427 return 1; 427 428 } ··· 446 449 447 450 cur_cpu_spec->num_pmcs = 6; 448 451 cur_cpu_spec->pmc_type = PPC_PMC_IBM; 449 - cur_cpu_spec->oprofile_cpu_type = "ppc64/power10"; 450 452 451 453 return 1; 452 454 }
+1 -1
arch/powerpc/kernel/eeh_driver.c
··· 750 750 * @pdev: pci_dev to check 751 751 * 752 752 * This function may return a false positive if we can't determine the slot's 753 - * presence state. This might happen for for PCIe slots if the PE containing 753 + * presence state. This might happen for PCIe slots if the PE containing 754 754 * the upstream bridge is also frozen, or the bridge is part of the same PE 755 755 * as the device. 756 756 *
+1 -1
arch/powerpc/kernel/exceptions-64s.S
··· 2779 2779 2780 2780 /* 2781 2781 * An interrupt came in while soft-disabled. We set paca->irq_happened, then: 2782 - * - If it was a decrementer interrupt, we bump the dec to max and and return. 2782 + * - If it was a decrementer interrupt, we bump the dec to max and return. 2783 2783 * - If it was a doorbell we return immediately since doorbells are edge 2784 2784 * triggered and won't automatically refire. 2785 2785 * - If it was a HMI we return immediately since we handled it in realmode
+3
arch/powerpc/kernel/head_64.S
··· 965 965 * and SLB setup before we turn on relocation. 966 966 */ 967 967 968 + #ifdef CONFIG_KASAN 969 + bl kasan_early_init 970 + #endif 968 971 /* Restore parameters passed from prom_init/kexec */ 969 972 mr r3,r31 970 973 LOAD_REG_ADDR(r12, DOTSYM(early_setup))
+2 -2
arch/powerpc/kernel/head_book3s_32.S
··· 418 418 */ 419 419 /* Get PTE (linux-style) and check access */ 420 420 mfspr r3,SPRN_IMISS 421 - #if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE) 421 + #ifdef CONFIG_MODULES 422 422 lis r1, TASK_SIZE@h /* check if kernel address */ 423 423 cmplw 0,r1,r3 424 424 #endif 425 425 mfspr r2, SPRN_SDR1 426 426 li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER 427 427 rlwinm r2, r2, 28, 0xfffff000 428 - #if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE) 428 + #ifdef CONFIG_MODULES 429 429 bgt- 112f 430 430 lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ 431 431 li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
-161
arch/powerpc/kernel/interrupt.c
··· 24 24 unsigned long global_dbcr0[NR_CPUS]; 25 25 #endif 26 26 27 - typedef long (*syscall_fn)(long, long, long, long, long, long); 28 - 29 27 #ifdef CONFIG_PPC_BOOK3S_64 30 28 DEFINE_STATIC_KEY_FALSE(interrupt_exit_not_reentrant); 31 29 static inline bool exit_must_hard_disable(void) ··· 69 71 } 70 72 #endif 71 73 return true; 72 - } 73 - 74 - /* Has to run notrace because it is entered not completely "reconciled" */ 75 - notrace long system_call_exception(long r3, long r4, long r5, 76 - long r6, long r7, long r8, 77 - unsigned long r0, struct pt_regs *regs) 78 - { 79 - syscall_fn f; 80 - 81 - kuap_lock(); 82 - 83 - regs->orig_gpr3 = r3; 84 - 85 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 86 - BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED); 87 - 88 - trace_hardirqs_off(); /* finish reconciling */ 89 - 90 - CT_WARN_ON(ct_state() == CONTEXT_KERNEL); 91 - user_exit_irqoff(); 92 - 93 - BUG_ON(regs_is_unrecoverable(regs)); 94 - BUG_ON(!(regs->msr & MSR_PR)); 95 - BUG_ON(arch_irq_disabled_regs(regs)); 96 - 97 - #ifdef CONFIG_PPC_PKEY 98 - if (mmu_has_feature(MMU_FTR_PKEY)) { 99 - unsigned long amr, iamr; 100 - bool flush_needed = false; 101 - /* 102 - * When entering from userspace we mostly have the AMR/IAMR 103 - * different from kernel default values. Hence don't compare. 104 - */ 105 - amr = mfspr(SPRN_AMR); 106 - iamr = mfspr(SPRN_IAMR); 107 - regs->amr = amr; 108 - regs->iamr = iamr; 109 - if (mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) { 110 - mtspr(SPRN_AMR, AMR_KUAP_BLOCKED); 111 - flush_needed = true; 112 - } 113 - if (mmu_has_feature(MMU_FTR_BOOK3S_KUEP)) { 114 - mtspr(SPRN_IAMR, AMR_KUEP_BLOCKED); 115 - flush_needed = true; 116 - } 117 - if (flush_needed) 118 - isync(); 119 - } else 120 - #endif 121 - kuap_assert_locked(); 122 - 123 - booke_restore_dbcr0(); 124 - 125 - account_cpu_user_entry(); 126 - 127 - account_stolen_time(); 128 - 129 - /* 130 - * This is not required for the syscall exit path, but makes the 131 - * stack frame look nicer. If this was initialised in the first stack 132 - * frame, or if the unwinder was taught the first stack frame always 133 - * returns to user with IRQS_ENABLED, this store could be avoided! 134 - */ 135 - irq_soft_mask_regs_set_state(regs, IRQS_ENABLED); 136 - 137 - /* 138 - * If system call is called with TM active, set _TIF_RESTOREALL to 139 - * prevent RFSCV being used to return to userspace, because POWER9 140 - * TM implementation has problems with this instruction returning to 141 - * transactional state. Final register values are not relevant because 142 - * the transaction will be aborted upon return anyway. Or in the case 143 - * of unsupported_scv SIGILL fault, the return state does not much 144 - * matter because it's an edge case. 145 - */ 146 - if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && 147 - unlikely(MSR_TM_TRANSACTIONAL(regs->msr))) 148 - set_bits(_TIF_RESTOREALL, &current_thread_info()->flags); 149 - 150 - /* 151 - * If the system call was made with a transaction active, doom it and 152 - * return without performing the system call. Unless it was an 153 - * unsupported scv vector, in which case it's treated like an illegal 154 - * instruction. 155 - */ 156 - #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 157 - if (unlikely(MSR_TM_TRANSACTIONAL(regs->msr)) && 158 - !trap_is_unsupported_scv(regs)) { 159 - /* Enable TM in the kernel, and disable EE (for scv) */ 160 - hard_irq_disable(); 161 - mtmsr(mfmsr() | MSR_TM); 162 - 163 - /* tabort, this dooms the transaction, nothing else */ 164 - asm volatile(".long 0x7c00071d | ((%0) << 16)" 165 - :: "r"(TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)); 166 - 167 - /* 168 - * Userspace will never see the return value. Execution will 169 - * resume after the tbegin. of the aborted transaction with the 170 - * checkpointed register state. A context switch could occur 171 - * or signal delivered to the process before resuming the 172 - * doomed transaction context, but that should all be handled 173 - * as expected. 174 - */ 175 - return -ENOSYS; 176 - } 177 - #endif // CONFIG_PPC_TRANSACTIONAL_MEM 178 - 179 - local_irq_enable(); 180 - 181 - if (unlikely(read_thread_flags() & _TIF_SYSCALL_DOTRACE)) { 182 - if (unlikely(trap_is_unsupported_scv(regs))) { 183 - /* Unsupported scv vector */ 184 - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); 185 - return regs->gpr[3]; 186 - } 187 - /* 188 - * We use the return value of do_syscall_trace_enter() as the 189 - * syscall number. If the syscall was rejected for any reason 190 - * do_syscall_trace_enter() returns an invalid syscall number 191 - * and the test against NR_syscalls will fail and the return 192 - * value to be used is in regs->gpr[3]. 193 - */ 194 - r0 = do_syscall_trace_enter(regs); 195 - if (unlikely(r0 >= NR_syscalls)) 196 - return regs->gpr[3]; 197 - r3 = regs->gpr[3]; 198 - r4 = regs->gpr[4]; 199 - r5 = regs->gpr[5]; 200 - r6 = regs->gpr[6]; 201 - r7 = regs->gpr[7]; 202 - r8 = regs->gpr[8]; 203 - 204 - } else if (unlikely(r0 >= NR_syscalls)) { 205 - if (unlikely(trap_is_unsupported_scv(regs))) { 206 - /* Unsupported scv vector */ 207 - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); 208 - return regs->gpr[3]; 209 - } 210 - return -ENOSYS; 211 - } 212 - 213 - /* May be faster to do array_index_nospec? */ 214 - barrier_nospec(); 215 - 216 - if (unlikely(is_compat_task())) { 217 - f = (void *)compat_sys_call_table[r0]; 218 - 219 - r3 &= 0x00000000ffffffffULL; 220 - r4 &= 0x00000000ffffffffULL; 221 - r5 &= 0x00000000ffffffffULL; 222 - r6 &= 0x00000000ffffffffULL; 223 - r7 &= 0x00000000ffffffffULL; 224 - r8 &= 0x00000000ffffffffULL; 225 - 226 - } else { 227 - f = (void *)sys_call_table[r0]; 228 - } 229 - 230 - return f(r3, r4, r5, r6, r7, r8); 231 74 } 232 75 233 76 static notrace void booke_load_dbcr0(void)
+5
arch/powerpc/kernel/iommu.c
··· 775 775 /* ignore reserved bit0 */ 776 776 if (tbl->it_offset == 0) 777 777 start = 1; 778 + 779 + /* Simple case with no reserved MMIO32 region */ 780 + if (!tbl->it_reserved_start && !tbl->it_reserved_end) 781 + return find_next_bit(tbl->it_map, tbl->it_size, start) != tbl->it_size; 782 + 778 783 end = tbl->it_reserved_start - tbl->it_offset; 779 784 if (find_next_bit(tbl->it_map, end, start) != end) 780 785 return true;
+36 -460
arch/powerpc/kernel/irq.c
··· 65 65 #include <asm/smp.h> 66 66 #include <asm/hw_irq.h> 67 67 #include <asm/softirq_stack.h> 68 + #include <asm/ppc_asm.h> 68 69 69 - #ifdef CONFIG_PPC64 70 - #include <asm/paca.h> 71 - #include <asm/firmware.h> 72 - #include <asm/lv1call.h> 73 - #include <asm/dbell.h> 74 - #endif 75 70 #define CREATE_TRACE_POINTS 76 71 #include <asm/trace.h> 77 72 #include <asm/cpu_has_feature.h> ··· 82 87 u32 tau_interrupts(unsigned long cpu); 83 88 #endif 84 89 #endif /* CONFIG_PPC32 */ 85 - 86 - #ifdef CONFIG_PPC64 87 - 88 - int distribute_irqs = 1; 89 - 90 - static inline notrace unsigned long get_irq_happened(void) 91 - { 92 - unsigned long happened; 93 - 94 - __asm__ __volatile__("lbz %0,%1(13)" 95 - : "=r" (happened) : "i" (offsetof(struct paca_struct, irq_happened))); 96 - 97 - return happened; 98 - } 99 - 100 - void replay_soft_interrupts(void) 101 - { 102 - struct pt_regs regs; 103 - 104 - /* 105 - * Be careful here, calling these interrupt handlers can cause 106 - * softirqs to be raised, which they may run when calling irq_exit, 107 - * which will cause local_irq_enable() to be run, which can then 108 - * recurse into this function. Don't keep any state across 109 - * interrupt handler calls which may change underneath us. 110 - * 111 - * We use local_paca rather than get_paca() to avoid all the 112 - * debug_smp_processor_id() business in this low level function. 113 - */ 114 - 115 - ppc_save_regs(&regs); 116 - regs.softe = IRQS_ENABLED; 117 - regs.msr |= MSR_EE; 118 - 119 - again: 120 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 121 - WARN_ON_ONCE(mfmsr() & MSR_EE); 122 - 123 - /* 124 - * Force the delivery of pending soft-disabled interrupts on PS3. 125 - * Any HV call will have this side effect. 126 - */ 127 - if (firmware_has_feature(FW_FEATURE_PS3_LV1)) { 128 - u64 tmp, tmp2; 129 - lv1_get_version_info(&tmp, &tmp2); 130 - } 131 - 132 - /* 133 - * Check if an hypervisor Maintenance interrupt happened. 134 - * This is a higher priority interrupt than the others, so 135 - * replay it first. 136 - */ 137 - if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_HMI)) { 138 - local_paca->irq_happened &= ~PACA_IRQ_HMI; 139 - regs.trap = INTERRUPT_HMI; 140 - handle_hmi_exception(&regs); 141 - if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 142 - hard_irq_disable(); 143 - } 144 - 145 - if (local_paca->irq_happened & PACA_IRQ_DEC) { 146 - local_paca->irq_happened &= ~PACA_IRQ_DEC; 147 - regs.trap = INTERRUPT_DECREMENTER; 148 - timer_interrupt(&regs); 149 - if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 150 - hard_irq_disable(); 151 - } 152 - 153 - if (local_paca->irq_happened & PACA_IRQ_EE) { 154 - local_paca->irq_happened &= ~PACA_IRQ_EE; 155 - regs.trap = INTERRUPT_EXTERNAL; 156 - do_IRQ(&regs); 157 - if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 158 - hard_irq_disable(); 159 - } 160 - 161 - if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (local_paca->irq_happened & PACA_IRQ_DBELL)) { 162 - local_paca->irq_happened &= ~PACA_IRQ_DBELL; 163 - regs.trap = INTERRUPT_DOORBELL; 164 - doorbell_exception(&regs); 165 - if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 166 - hard_irq_disable(); 167 - } 168 - 169 - /* Book3E does not support soft-masking PMI interrupts */ 170 - if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_PMI)) { 171 - local_paca->irq_happened &= ~PACA_IRQ_PMI; 172 - regs.trap = INTERRUPT_PERFMON; 173 - performance_monitor_exception(&regs); 174 - if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 175 - hard_irq_disable(); 176 - } 177 - 178 - if (local_paca->irq_happened & ~PACA_IRQ_HARD_DIS) { 179 - /* 180 - * We are responding to the next interrupt, so interrupt-off 181 - * latencies should be reset here. 182 - */ 183 - trace_hardirqs_on(); 184 - trace_hardirqs_off(); 185 - goto again; 186 - } 187 - } 188 - 189 - #if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_KUAP) 190 - static inline void replay_soft_interrupts_irqrestore(void) 191 - { 192 - unsigned long kuap_state = get_kuap(); 193 - 194 - /* 195 - * Check if anything calls local_irq_enable/restore() when KUAP is 196 - * disabled (user access enabled). We handle that case here by saving 197 - * and re-locking AMR but we shouldn't get here in the first place, 198 - * hence the warning. 199 - */ 200 - kuap_assert_locked(); 201 - 202 - if (kuap_state != AMR_KUAP_BLOCKED) 203 - set_kuap(AMR_KUAP_BLOCKED); 204 - 205 - replay_soft_interrupts(); 206 - 207 - if (kuap_state != AMR_KUAP_BLOCKED) 208 - set_kuap(kuap_state); 209 - } 210 - #else 211 - #define replay_soft_interrupts_irqrestore() replay_soft_interrupts() 212 - #endif 213 - 214 - notrace void arch_local_irq_restore(unsigned long mask) 215 - { 216 - unsigned char irq_happened; 217 - 218 - /* Write the new soft-enabled value if it is a disable */ 219 - if (mask) { 220 - irq_soft_mask_set(mask); 221 - return; 222 - } 223 - 224 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 225 - WARN_ON_ONCE(in_nmi() || in_hardirq()); 226 - 227 - /* 228 - * After the stb, interrupts are unmasked and there are no interrupts 229 - * pending replay. The restart sequence makes this atomic with 230 - * respect to soft-masked interrupts. If this was just a simple code 231 - * sequence, a soft-masked interrupt could become pending right after 232 - * the comparison and before the stb. 233 - * 234 - * This allows interrupts to be unmasked without hard disabling, and 235 - * also without new hard interrupts coming in ahead of pending ones. 236 - */ 237 - asm_volatile_goto( 238 - "1: \n" 239 - " lbz 9,%0(13) \n" 240 - " cmpwi 9,0 \n" 241 - " bne %l[happened] \n" 242 - " stb 9,%1(13) \n" 243 - "2: \n" 244 - RESTART_TABLE(1b, 2b, 1b) 245 - : : "i" (offsetof(struct paca_struct, irq_happened)), 246 - "i" (offsetof(struct paca_struct, irq_soft_mask)) 247 - : "cr0", "r9" 248 - : happened); 249 - 250 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 251 - WARN_ON_ONCE(!(mfmsr() & MSR_EE)); 252 - 253 - return; 254 - 255 - happened: 256 - irq_happened = get_irq_happened(); 257 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 258 - WARN_ON_ONCE(!irq_happened); 259 - 260 - if (irq_happened == PACA_IRQ_HARD_DIS) { 261 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 262 - WARN_ON_ONCE(mfmsr() & MSR_EE); 263 - irq_soft_mask_set(IRQS_ENABLED); 264 - local_paca->irq_happened = 0; 265 - __hard_irq_enable(); 266 - return; 267 - } 268 - 269 - /* Have interrupts to replay, need to hard disable first */ 270 - if (!(irq_happened & PACA_IRQ_HARD_DIS)) { 271 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) { 272 - if (!(mfmsr() & MSR_EE)) { 273 - /* 274 - * An interrupt could have come in and cleared 275 - * MSR[EE] and set IRQ_HARD_DIS, so check 276 - * IRQ_HARD_DIS again and warn if it is still 277 - * clear. 278 - */ 279 - irq_happened = get_irq_happened(); 280 - WARN_ON_ONCE(!(irq_happened & PACA_IRQ_HARD_DIS)); 281 - } 282 - } 283 - __hard_irq_disable(); 284 - local_paca->irq_happened |= PACA_IRQ_HARD_DIS; 285 - } else { 286 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) { 287 - if (WARN_ON_ONCE(mfmsr() & MSR_EE)) 288 - __hard_irq_disable(); 289 - } 290 - } 291 - 292 - /* 293 - * Disable preempt here, so that the below preempt_enable will 294 - * perform resched if required (a replayed interrupt may set 295 - * need_resched). 296 - */ 297 - preempt_disable(); 298 - irq_soft_mask_set(IRQS_ALL_DISABLED); 299 - trace_hardirqs_off(); 300 - 301 - replay_soft_interrupts_irqrestore(); 302 - local_paca->irq_happened = 0; 303 - 304 - trace_hardirqs_on(); 305 - irq_soft_mask_set(IRQS_ENABLED); 306 - __hard_irq_enable(); 307 - preempt_enable(); 308 - } 309 - EXPORT_SYMBOL(arch_local_irq_restore); 310 - 311 - /* 312 - * This is a helper to use when about to go into idle low-power 313 - * when the latter has the side effect of re-enabling interrupts 314 - * (such as calling H_CEDE under pHyp). 315 - * 316 - * You call this function with interrupts soft-disabled (this is 317 - * already the case when ppc_md.power_save is called). The function 318 - * will return whether to enter power save or just return. 319 - * 320 - * In the former case, it will have notified lockdep of interrupts 321 - * being re-enabled and generally sanitized the lazy irq state, 322 - * and in the latter case it will leave with interrupts hard 323 - * disabled and marked as such, so the local_irq_enable() call 324 - * in arch_cpu_idle() will properly re-enable everything. 325 - */ 326 - bool prep_irq_for_idle(void) 327 - { 328 - /* 329 - * First we need to hard disable to ensure no interrupt 330 - * occurs before we effectively enter the low power state 331 - */ 332 - __hard_irq_disable(); 333 - local_paca->irq_happened |= PACA_IRQ_HARD_DIS; 334 - 335 - /* 336 - * If anything happened while we were soft-disabled, 337 - * we return now and do not enter the low power state. 338 - */ 339 - if (lazy_irq_pending()) 340 - return false; 341 - 342 - /* Tell lockdep we are about to re-enable */ 343 - trace_hardirqs_on(); 344 - 345 - /* 346 - * Mark interrupts as soft-enabled and clear the 347 - * PACA_IRQ_HARD_DIS from the pending mask since we 348 - * are about to hard enable as well as a side effect 349 - * of entering the low power state. 350 - */ 351 - local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; 352 - irq_soft_mask_set(IRQS_ENABLED); 353 - 354 - /* Tell the caller to enter the low power state */ 355 - return true; 356 - } 357 - 358 - #ifdef CONFIG_PPC_BOOK3S 359 - /* 360 - * This is for idle sequences that return with IRQs off, but the 361 - * idle state itself wakes on interrupt. Tell the irq tracer that 362 - * IRQs are enabled for the duration of idle so it does not get long 363 - * off times. Must be paired with fini_irq_for_idle_irqsoff. 364 - */ 365 - bool prep_irq_for_idle_irqsoff(void) 366 - { 367 - WARN_ON(!irqs_disabled()); 368 - 369 - /* 370 - * First we need to hard disable to ensure no interrupt 371 - * occurs before we effectively enter the low power state 372 - */ 373 - __hard_irq_disable(); 374 - local_paca->irq_happened |= PACA_IRQ_HARD_DIS; 375 - 376 - /* 377 - * If anything happened while we were soft-disabled, 378 - * we return now and do not enter the low power state. 379 - */ 380 - if (lazy_irq_pending()) 381 - return false; 382 - 383 - /* Tell lockdep we are about to re-enable */ 384 - trace_hardirqs_on(); 385 - 386 - return true; 387 - } 388 - 389 - /* 390 - * Take the SRR1 wakeup reason, index into this table to find the 391 - * appropriate irq_happened bit. 392 - * 393 - * Sytem reset exceptions taken in idle state also come through here, 394 - * but they are NMI interrupts so do not need to wait for IRQs to be 395 - * restored, and should be taken as early as practical. These are marked 396 - * with 0xff in the table. The Power ISA specifies 0100b as the system 397 - * reset interrupt reason. 398 - */ 399 - #define IRQ_SYSTEM_RESET 0xff 400 - 401 - static const u8 srr1_to_lazyirq[0x10] = { 402 - 0, 0, 0, 403 - PACA_IRQ_DBELL, 404 - IRQ_SYSTEM_RESET, 405 - PACA_IRQ_DBELL, 406 - PACA_IRQ_DEC, 407 - 0, 408 - PACA_IRQ_EE, 409 - PACA_IRQ_EE, 410 - PACA_IRQ_HMI, 411 - 0, 0, 0, 0, 0 }; 412 - 413 - void replay_system_reset(void) 414 - { 415 - struct pt_regs regs; 416 - 417 - ppc_save_regs(&regs); 418 - regs.trap = 0x100; 419 - get_paca()->in_nmi = 1; 420 - system_reset_exception(&regs); 421 - get_paca()->in_nmi = 0; 422 - } 423 - EXPORT_SYMBOL_GPL(replay_system_reset); 424 - 425 - void irq_set_pending_from_srr1(unsigned long srr1) 426 - { 427 - unsigned int idx = (srr1 & SRR1_WAKEMASK_P8) >> 18; 428 - u8 reason = srr1_to_lazyirq[idx]; 429 - 430 - /* 431 - * Take the system reset now, which is immediately after registers 432 - * are restored from idle. It's an NMI, so interrupts need not be 433 - * re-enabled before it is taken. 434 - */ 435 - if (unlikely(reason == IRQ_SYSTEM_RESET)) { 436 - replay_system_reset(); 437 - return; 438 - } 439 - 440 - if (reason == PACA_IRQ_DBELL) { 441 - /* 442 - * When doorbell triggers a system reset wakeup, the message 443 - * is not cleared, so if the doorbell interrupt is replayed 444 - * and the IPI handled, the doorbell interrupt would still 445 - * fire when EE is enabled. 446 - * 447 - * To avoid taking the superfluous doorbell interrupt, 448 - * execute a msgclr here before the interrupt is replayed. 449 - */ 450 - ppc_msgclr(PPC_DBELL_MSGTYPE); 451 - } 452 - 453 - /* 454 - * The 0 index (SRR1[42:45]=b0000) must always evaluate to 0, 455 - * so this can be called unconditionally with the SRR1 wake 456 - * reason as returned by the idle code, which uses 0 to mean no 457 - * interrupt. 458 - * 459 - * If a future CPU was to designate this as an interrupt reason, 460 - * then a new index for no interrupt must be assigned. 461 - */ 462 - local_paca->irq_happened |= reason; 463 - } 464 - #endif /* CONFIG_PPC_BOOK3S */ 465 - 466 - /* 467 - * Force a replay of the external interrupt handler on this CPU. 468 - */ 469 - void force_external_irq_replay(void) 470 - { 471 - /* 472 - * This must only be called with interrupts soft-disabled, 473 - * the replay will happen when re-enabling. 474 - */ 475 - WARN_ON(!arch_irqs_disabled()); 476 - 477 - /* 478 - * Interrupts must always be hard disabled before irq_happened is 479 - * modified (to prevent lost update in case of interrupt between 480 - * load and store). 481 - */ 482 - __hard_irq_disable(); 483 - local_paca->irq_happened |= PACA_IRQ_HARD_DIS; 484 - 485 - /* Indicate in the PACA that we have an interrupt to replay */ 486 - local_paca->irq_happened |= PACA_IRQ_EE; 487 - } 488 - 489 - #endif /* CONFIG_PPC64 */ 490 90 491 91 int arch_show_interrupts(struct seq_file *p, int prec) 492 92 { ··· 185 595 return sum; 186 596 } 187 597 188 - static inline void check_stack_overflow(void) 598 + static inline void check_stack_overflow(unsigned long sp) 189 599 { 190 - long sp; 191 - 192 600 if (!IS_ENABLED(CONFIG_DEBUG_STACKOVERFLOW)) 193 601 return; 194 602 195 - sp = current_stack_pointer & (THREAD_SIZE - 1); 603 + sp &= THREAD_SIZE - 1; 196 604 197 - /* check for stack overflow: is there less than 2KB free? */ 198 - if (unlikely(sp < 2048)) { 605 + /* check for stack overflow: is there less than 1/4th free? */ 606 + if (unlikely(sp < THREAD_SIZE / 4)) { 199 607 pr_err("do_IRQ: stack overflow: %ld\n", sp); 200 608 dump_stack(); 201 609 } ··· 220 632 } 221 633 #endif 222 634 223 - static __always_inline void call_do_irq(struct pt_regs *regs, void *sp) 224 - { 225 - register unsigned long r3 asm("r3") = (unsigned long)regs; 226 - 227 - /* Temporarily switch r1 to sp, call __do_irq() then restore r1. */ 228 - asm volatile ( 229 - PPC_STLU " %%r1, %[offset](%[sp]) ;" 230 - "mr %%r1, %[sp] ;" 231 - "bl %[callee] ;" 232 - PPC_LL " %%r1, 0(%%r1) ;" 233 - : // Outputs 234 - "+r" (r3) 235 - : // Inputs 236 - [sp] "b" (sp), [offset] "i" (THREAD_SIZE - STACK_FRAME_OVERHEAD), 237 - [callee] "i" (__do_irq) 238 - : // Clobbers 239 - "lr", "xer", "ctr", "memory", "cr0", "cr1", "cr5", "cr6", 240 - "cr7", "r0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 241 - "r11", "r12" 242 - ); 243 - } 244 - 245 635 DEFINE_STATIC_CALL_RET0(ppc_get_irq, *ppc_md.get_irq); 246 636 247 - void __do_irq(struct pt_regs *regs) 637 + static void __do_irq(struct pt_regs *regs, unsigned long oldsp) 248 638 { 249 639 unsigned int irq; 250 640 251 641 trace_irq_entry(regs); 642 + 643 + check_stack_overflow(oldsp); 252 644 253 645 /* 254 646 * Query the platform PIC for the interrupt & ack it. ··· 250 682 trace_irq_exit(regs); 251 683 } 252 684 685 + static __always_inline void call_do_irq(struct pt_regs *regs, void *sp) 686 + { 687 + register unsigned long r3 asm("r3") = (unsigned long)regs; 688 + 689 + /* Temporarily switch r1 to sp, call __do_irq() then restore r1. */ 690 + asm volatile ( 691 + PPC_STLU " %%r1, %[offset](%[sp]) ;" 692 + "mr %%r4, %%r1 ;" 693 + "mr %%r1, %[sp] ;" 694 + "bl %[callee] ;" 695 + PPC_LL " %%r1, 0(%%r1) ;" 696 + : // Outputs 697 + "+r" (r3) 698 + : // Inputs 699 + [sp] "b" (sp), [offset] "i" (THREAD_SIZE - STACK_FRAME_OVERHEAD), 700 + [callee] "i" (__do_irq) 701 + : // Clobbers 702 + "lr", "xer", "ctr", "memory", "cr0", "cr1", "cr5", "cr6", 703 + "cr7", "r0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 704 + "r11", "r12" 705 + ); 706 + } 707 + 253 708 void __do_IRQ(struct pt_regs *regs) 254 709 { 255 710 struct pt_regs *old_regs = set_irq_regs(regs); ··· 283 692 irqsp = hardirq_ctx[raw_smp_processor_id()]; 284 693 sirqsp = softirq_ctx[raw_smp_processor_id()]; 285 694 286 - check_stack_overflow(); 287 - 288 - /* Already there ? */ 289 - if (unlikely(cursp == irqsp || cursp == sirqsp)) { 290 - __do_irq(regs); 291 - set_irq_regs(old_regs); 292 - return; 293 - } 294 - /* Switch stack and call */ 295 - call_do_irq(regs, irqsp); 695 + /* Already there ? If not switch stack and call */ 696 + if (unlikely(cursp == irqsp || cursp == sirqsp)) 697 + __do_irq(regs, current_stack_pointer); 698 + else 699 + call_do_irq(regs, irqsp); 296 700 297 701 set_irq_regs(old_regs); 298 702 } ··· 384 798 return hard_smp_processor_id(); 385 799 } 386 800 #endif 387 - 388 - #ifdef CONFIG_PPC64 389 - static int __init setup_noirqdistrib(char *str) 390 - { 391 - distribute_irqs = 0; 392 - return 1; 393 - } 394 - 395 - __setup("noirqdistrib", setup_noirqdistrib); 396 - #endif /* CONFIG_PPC64 */
+466
arch/powerpc/kernel/irq_64.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Derived from arch/i386/kernel/irq.c 4 + * Copyright (C) 1992 Linus Torvalds 5 + * Adapted from arch/i386 by Gary Thomas 6 + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 7 + * Updated and modified by Cort Dougan <cort@fsmlabs.com> 8 + * Copyright (C) 1996-2001 Cort Dougan 9 + * Adapted for Power Macintosh by Paul Mackerras 10 + * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) 11 + * 12 + * This file contains the code used by various IRQ handling routines: 13 + * asking for different IRQ's should be done through these routines 14 + * instead of just grabbing them. Thus setups with different IRQ numbers 15 + * shouldn't result in any weird surprises, and installing new handlers 16 + * should be easier. 17 + */ 18 + 19 + #undef DEBUG 20 + 21 + #include <linux/export.h> 22 + #include <linux/threads.h> 23 + #include <linux/kernel_stat.h> 24 + #include <linux/signal.h> 25 + #include <linux/sched.h> 26 + #include <linux/ptrace.h> 27 + #include <linux/ioport.h> 28 + #include <linux/interrupt.h> 29 + #include <linux/timex.h> 30 + #include <linux/init.h> 31 + #include <linux/slab.h> 32 + #include <linux/delay.h> 33 + #include <linux/irq.h> 34 + #include <linux/seq_file.h> 35 + #include <linux/cpumask.h> 36 + #include <linux/profile.h> 37 + #include <linux/bitops.h> 38 + #include <linux/list.h> 39 + #include <linux/radix-tree.h> 40 + #include <linux/mutex.h> 41 + #include <linux/pci.h> 42 + #include <linux/debugfs.h> 43 + #include <linux/of.h> 44 + #include <linux/of_irq.h> 45 + #include <linux/vmalloc.h> 46 + #include <linux/pgtable.h> 47 + #include <linux/static_call.h> 48 + 49 + #include <linux/uaccess.h> 50 + #include <asm/interrupt.h> 51 + #include <asm/io.h> 52 + #include <asm/irq.h> 53 + #include <asm/cache.h> 54 + #include <asm/ptrace.h> 55 + #include <asm/machdep.h> 56 + #include <asm/udbg.h> 57 + #include <asm/smp.h> 58 + #include <asm/hw_irq.h> 59 + #include <asm/softirq_stack.h> 60 + #include <asm/ppc_asm.h> 61 + 62 + #include <asm/paca.h> 63 + #include <asm/firmware.h> 64 + #include <asm/lv1call.h> 65 + #include <asm/dbell.h> 66 + #include <asm/trace.h> 67 + #include <asm/cpu_has_feature.h> 68 + 69 + int distribute_irqs = 1; 70 + 71 + void replay_soft_interrupts(void) 72 + { 73 + struct pt_regs regs; 74 + 75 + /* 76 + * Be careful here, calling these interrupt handlers can cause 77 + * softirqs to be raised, which they may run when calling irq_exit, 78 + * which will cause local_irq_enable() to be run, which can then 79 + * recurse into this function. Don't keep any state across 80 + * interrupt handler calls which may change underneath us. 81 + * 82 + * We use local_paca rather than get_paca() to avoid all the 83 + * debug_smp_processor_id() business in this low level function. 84 + */ 85 + 86 + ppc_save_regs(&regs); 87 + regs.softe = IRQS_ENABLED; 88 + regs.msr |= MSR_EE; 89 + 90 + again: 91 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 92 + WARN_ON_ONCE(mfmsr() & MSR_EE); 93 + 94 + /* 95 + * Force the delivery of pending soft-disabled interrupts on PS3. 96 + * Any HV call will have this side effect. 97 + */ 98 + if (firmware_has_feature(FW_FEATURE_PS3_LV1)) { 99 + u64 tmp, tmp2; 100 + lv1_get_version_info(&tmp, &tmp2); 101 + } 102 + 103 + /* 104 + * Check if an hypervisor Maintenance interrupt happened. 105 + * This is a higher priority interrupt than the others, so 106 + * replay it first. 107 + */ 108 + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_HMI)) { 109 + local_paca->irq_happened &= ~PACA_IRQ_HMI; 110 + regs.trap = INTERRUPT_HMI; 111 + handle_hmi_exception(&regs); 112 + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 113 + hard_irq_disable(); 114 + } 115 + 116 + if (local_paca->irq_happened & PACA_IRQ_DEC) { 117 + local_paca->irq_happened &= ~PACA_IRQ_DEC; 118 + regs.trap = INTERRUPT_DECREMENTER; 119 + timer_interrupt(&regs); 120 + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 121 + hard_irq_disable(); 122 + } 123 + 124 + if (local_paca->irq_happened & PACA_IRQ_EE) { 125 + local_paca->irq_happened &= ~PACA_IRQ_EE; 126 + regs.trap = INTERRUPT_EXTERNAL; 127 + do_IRQ(&regs); 128 + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 129 + hard_irq_disable(); 130 + } 131 + 132 + if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (local_paca->irq_happened & PACA_IRQ_DBELL)) { 133 + local_paca->irq_happened &= ~PACA_IRQ_DBELL; 134 + regs.trap = INTERRUPT_DOORBELL; 135 + doorbell_exception(&regs); 136 + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 137 + hard_irq_disable(); 138 + } 139 + 140 + /* Book3E does not support soft-masking PMI interrupts */ 141 + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_PMI)) { 142 + local_paca->irq_happened &= ~PACA_IRQ_PMI; 143 + regs.trap = INTERRUPT_PERFMON; 144 + performance_monitor_exception(&regs); 145 + if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 146 + hard_irq_disable(); 147 + } 148 + 149 + if (local_paca->irq_happened & ~PACA_IRQ_HARD_DIS) { 150 + /* 151 + * We are responding to the next interrupt, so interrupt-off 152 + * latencies should be reset here. 153 + */ 154 + trace_hardirqs_on(); 155 + trace_hardirqs_off(); 156 + goto again; 157 + } 158 + } 159 + 160 + #if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_KUAP) 161 + static inline void replay_soft_interrupts_irqrestore(void) 162 + { 163 + unsigned long kuap_state = get_kuap(); 164 + 165 + /* 166 + * Check if anything calls local_irq_enable/restore() when KUAP is 167 + * disabled (user access enabled). We handle that case here by saving 168 + * and re-locking AMR but we shouldn't get here in the first place, 169 + * hence the warning. 170 + */ 171 + kuap_assert_locked(); 172 + 173 + if (kuap_state != AMR_KUAP_BLOCKED) 174 + set_kuap(AMR_KUAP_BLOCKED); 175 + 176 + replay_soft_interrupts(); 177 + 178 + if (kuap_state != AMR_KUAP_BLOCKED) 179 + set_kuap(kuap_state); 180 + } 181 + #else 182 + #define replay_soft_interrupts_irqrestore() replay_soft_interrupts() 183 + #endif 184 + 185 + notrace void arch_local_irq_restore(unsigned long mask) 186 + { 187 + unsigned char irq_happened; 188 + 189 + /* Write the new soft-enabled value if it is a disable */ 190 + if (mask) { 191 + irq_soft_mask_set(mask); 192 + return; 193 + } 194 + 195 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 196 + WARN_ON_ONCE(in_nmi() || in_hardirq()); 197 + 198 + /* 199 + * After the stb, interrupts are unmasked and there are no interrupts 200 + * pending replay. The restart sequence makes this atomic with 201 + * respect to soft-masked interrupts. If this was just a simple code 202 + * sequence, a soft-masked interrupt could become pending right after 203 + * the comparison and before the stb. 204 + * 205 + * This allows interrupts to be unmasked without hard disabling, and 206 + * also without new hard interrupts coming in ahead of pending ones. 207 + */ 208 + asm_volatile_goto( 209 + "1: \n" 210 + " lbz 9,%0(13) \n" 211 + " cmpwi 9,0 \n" 212 + " bne %l[happened] \n" 213 + " stb 9,%1(13) \n" 214 + "2: \n" 215 + RESTART_TABLE(1b, 2b, 1b) 216 + : : "i" (offsetof(struct paca_struct, irq_happened)), 217 + "i" (offsetof(struct paca_struct, irq_soft_mask)) 218 + : "cr0", "r9" 219 + : happened); 220 + 221 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 222 + WARN_ON_ONCE(!(mfmsr() & MSR_EE)); 223 + 224 + return; 225 + 226 + happened: 227 + irq_happened = READ_ONCE(local_paca->irq_happened); 228 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 229 + WARN_ON_ONCE(!irq_happened); 230 + 231 + if (irq_happened == PACA_IRQ_HARD_DIS) { 232 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 233 + WARN_ON_ONCE(mfmsr() & MSR_EE); 234 + irq_soft_mask_set(IRQS_ENABLED); 235 + local_paca->irq_happened = 0; 236 + __hard_irq_enable(); 237 + return; 238 + } 239 + 240 + /* Have interrupts to replay, need to hard disable first */ 241 + if (!(irq_happened & PACA_IRQ_HARD_DIS)) { 242 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) { 243 + if (!(mfmsr() & MSR_EE)) { 244 + /* 245 + * An interrupt could have come in and cleared 246 + * MSR[EE] and set IRQ_HARD_DIS, so check 247 + * IRQ_HARD_DIS again and warn if it is still 248 + * clear. 249 + */ 250 + irq_happened = READ_ONCE(local_paca->irq_happened); 251 + WARN_ON_ONCE(!(irq_happened & PACA_IRQ_HARD_DIS)); 252 + } 253 + } 254 + __hard_irq_disable(); 255 + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; 256 + } else { 257 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) { 258 + if (WARN_ON_ONCE(mfmsr() & MSR_EE)) 259 + __hard_irq_disable(); 260 + } 261 + } 262 + 263 + /* 264 + * Disable preempt here, so that the below preempt_enable will 265 + * perform resched if required (a replayed interrupt may set 266 + * need_resched). 267 + */ 268 + preempt_disable(); 269 + irq_soft_mask_set(IRQS_ALL_DISABLED); 270 + trace_hardirqs_off(); 271 + 272 + replay_soft_interrupts_irqrestore(); 273 + local_paca->irq_happened = 0; 274 + 275 + trace_hardirqs_on(); 276 + irq_soft_mask_set(IRQS_ENABLED); 277 + __hard_irq_enable(); 278 + preempt_enable(); 279 + } 280 + EXPORT_SYMBOL(arch_local_irq_restore); 281 + 282 + /* 283 + * This is a helper to use when about to go into idle low-power 284 + * when the latter has the side effect of re-enabling interrupts 285 + * (such as calling H_CEDE under pHyp). 286 + * 287 + * You call this function with interrupts soft-disabled (this is 288 + * already the case when ppc_md.power_save is called). The function 289 + * will return whether to enter power save or just return. 290 + * 291 + * In the former case, it will have notified lockdep of interrupts 292 + * being re-enabled and generally sanitized the lazy irq state, 293 + * and in the latter case it will leave with interrupts hard 294 + * disabled and marked as such, so the local_irq_enable() call 295 + * in arch_cpu_idle() will properly re-enable everything. 296 + */ 297 + bool prep_irq_for_idle(void) 298 + { 299 + /* 300 + * First we need to hard disable to ensure no interrupt 301 + * occurs before we effectively enter the low power state 302 + */ 303 + __hard_irq_disable(); 304 + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; 305 + 306 + /* 307 + * If anything happened while we were soft-disabled, 308 + * we return now and do not enter the low power state. 309 + */ 310 + if (lazy_irq_pending()) 311 + return false; 312 + 313 + /* Tell lockdep we are about to re-enable */ 314 + trace_hardirqs_on(); 315 + 316 + /* 317 + * Mark interrupts as soft-enabled and clear the 318 + * PACA_IRQ_HARD_DIS from the pending mask since we 319 + * are about to hard enable as well as a side effect 320 + * of entering the low power state. 321 + */ 322 + local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; 323 + irq_soft_mask_set(IRQS_ENABLED); 324 + 325 + /* Tell the caller to enter the low power state */ 326 + return true; 327 + } 328 + 329 + #ifdef CONFIG_PPC_BOOK3S 330 + /* 331 + * This is for idle sequences that return with IRQs off, but the 332 + * idle state itself wakes on interrupt. Tell the irq tracer that 333 + * IRQs are enabled for the duration of idle so it does not get long 334 + * off times. Must be paired with fini_irq_for_idle_irqsoff. 335 + */ 336 + bool prep_irq_for_idle_irqsoff(void) 337 + { 338 + WARN_ON(!irqs_disabled()); 339 + 340 + /* 341 + * First we need to hard disable to ensure no interrupt 342 + * occurs before we effectively enter the low power state 343 + */ 344 + __hard_irq_disable(); 345 + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; 346 + 347 + /* 348 + * If anything happened while we were soft-disabled, 349 + * we return now and do not enter the low power state. 350 + */ 351 + if (lazy_irq_pending()) 352 + return false; 353 + 354 + /* Tell lockdep we are about to re-enable */ 355 + trace_hardirqs_on(); 356 + 357 + return true; 358 + } 359 + 360 + /* 361 + * Take the SRR1 wakeup reason, index into this table to find the 362 + * appropriate irq_happened bit. 363 + * 364 + * Sytem reset exceptions taken in idle state also come through here, 365 + * but they are NMI interrupts so do not need to wait for IRQs to be 366 + * restored, and should be taken as early as practical. These are marked 367 + * with 0xff in the table. The Power ISA specifies 0100b as the system 368 + * reset interrupt reason. 369 + */ 370 + #define IRQ_SYSTEM_RESET 0xff 371 + 372 + static const u8 srr1_to_lazyirq[0x10] = { 373 + 0, 0, 0, 374 + PACA_IRQ_DBELL, 375 + IRQ_SYSTEM_RESET, 376 + PACA_IRQ_DBELL, 377 + PACA_IRQ_DEC, 378 + 0, 379 + PACA_IRQ_EE, 380 + PACA_IRQ_EE, 381 + PACA_IRQ_HMI, 382 + 0, 0, 0, 0, 0 }; 383 + 384 + void replay_system_reset(void) 385 + { 386 + struct pt_regs regs; 387 + 388 + ppc_save_regs(&regs); 389 + regs.trap = 0x100; 390 + get_paca()->in_nmi = 1; 391 + system_reset_exception(&regs); 392 + get_paca()->in_nmi = 0; 393 + } 394 + EXPORT_SYMBOL_GPL(replay_system_reset); 395 + 396 + void irq_set_pending_from_srr1(unsigned long srr1) 397 + { 398 + unsigned int idx = (srr1 & SRR1_WAKEMASK_P8) >> 18; 399 + u8 reason = srr1_to_lazyirq[idx]; 400 + 401 + /* 402 + * Take the system reset now, which is immediately after registers 403 + * are restored from idle. It's an NMI, so interrupts need not be 404 + * re-enabled before it is taken. 405 + */ 406 + if (unlikely(reason == IRQ_SYSTEM_RESET)) { 407 + replay_system_reset(); 408 + return; 409 + } 410 + 411 + if (reason == PACA_IRQ_DBELL) { 412 + /* 413 + * When doorbell triggers a system reset wakeup, the message 414 + * is not cleared, so if the doorbell interrupt is replayed 415 + * and the IPI handled, the doorbell interrupt would still 416 + * fire when EE is enabled. 417 + * 418 + * To avoid taking the superfluous doorbell interrupt, 419 + * execute a msgclr here before the interrupt is replayed. 420 + */ 421 + ppc_msgclr(PPC_DBELL_MSGTYPE); 422 + } 423 + 424 + /* 425 + * The 0 index (SRR1[42:45]=b0000) must always evaluate to 0, 426 + * so this can be called unconditionally with the SRR1 wake 427 + * reason as returned by the idle code, which uses 0 to mean no 428 + * interrupt. 429 + * 430 + * If a future CPU was to designate this as an interrupt reason, 431 + * then a new index for no interrupt must be assigned. 432 + */ 433 + local_paca->irq_happened |= reason; 434 + } 435 + #endif /* CONFIG_PPC_BOOK3S */ 436 + 437 + /* 438 + * Force a replay of the external interrupt handler on this CPU. 439 + */ 440 + void force_external_irq_replay(void) 441 + { 442 + /* 443 + * This must only be called with interrupts soft-disabled, 444 + * the replay will happen when re-enabling. 445 + */ 446 + WARN_ON(!arch_irqs_disabled()); 447 + 448 + /* 449 + * Interrupts must always be hard disabled before irq_happened is 450 + * modified (to prevent lost update in case of interrupt between 451 + * load and store). 452 + */ 453 + __hard_irq_disable(); 454 + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; 455 + 456 + /* Indicate in the PACA that we have an interrupt to replay */ 457 + local_paca->irq_happened |= PACA_IRQ_EE; 458 + } 459 + 460 + static int __init setup_noirqdistrib(char *str) 461 + { 462 + distribute_irqs = 0; 463 + return 1; 464 + } 465 + 466 + __setup("noirqdistrib", setup_noirqdistrib);
+1 -1
arch/powerpc/kernel/kprobes.c
··· 269 269 * So, we should never get here... but, its still 270 270 * good to catch them, just in case... 271 271 */ 272 - printk("Can't step on instruction %s\n", ppc_inst_as_str(insn)); 272 + printk("Can't step on instruction %08lx\n", ppc_inst_as_ulong(insn)); 273 273 BUG(); 274 274 } else { 275 275 /*
+1 -1
arch/powerpc/kernel/mce.c
··· 756 756 mce_info = memblock_alloc_try_nid(sizeof(*mce_info), 757 757 __alignof__(*mce_info), 758 758 MEMBLOCK_LOW_LIMIT, 759 - limit, cpu_to_node(i)); 759 + limit, early_cpu_to_node(i)); 760 760 if (!mce_info) 761 761 goto err; 762 762 paca_ptrs[i]->mce_info = mce_info;
+23 -9
arch/powerpc/kernel/pci-common.c
··· 39 39 #include <asm/machdep.h> 40 40 #include <asm/ppc-pci.h> 41 41 #include <asm/eeh.h> 42 + #include <asm/setup.h> 42 43 43 44 #include "../../../drivers/pci/pci.h" 44 45 ··· 75 74 static int get_phb_number(struct device_node *dn) 76 75 { 77 76 int ret, phb_id = -1; 78 - u32 prop_32; 79 77 u64 prop; 80 78 81 79 /* 82 80 * Try fixed PHB numbering first, by checking archs and reading 83 - * the respective device-tree properties. Firstly, try powernv by 84 - * reading "ibm,opal-phbid", only present in OPAL environment. 81 + * the respective device-tree properties. Firstly, try reading 82 + * standard "linux,pci-domain", then try reading "ibm,opal-phbid" 83 + * (only present in powernv OPAL environment), then try device-tree 84 + * alias and as the last try to use lower bits of "reg" property. 85 85 */ 86 - ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop); 86 + ret = of_get_pci_domain_nr(dn); 87 + if (ret >= 0) { 88 + prop = ret; 89 + ret = 0; 90 + } 91 + if (ret) 92 + ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop); 93 + 87 94 if (ret) { 95 + ret = of_alias_get_id(dn, "pci"); 96 + if (ret >= 0) { 97 + prop = ret; 98 + ret = 0; 99 + } 100 + } 101 + if (ret) { 102 + u32 prop_32; 88 103 ret = of_property_read_u32_index(dn, "reg", 1, &prop_32); 89 104 prop = prop_32; 90 105 } ··· 112 95 if ((phb_id >= 0) && !test_and_set_bit(phb_id, phb_bitmap)) 113 96 return phb_id; 114 97 115 - /* 116 - * If not pseries nor powernv, or if fixed PHB numbering tried to add 117 - * the same PHB number twice, then fallback to dynamic PHB numbering. 118 - */ 98 + /* If everything fails then fallback to dynamic PHB numbering. */ 119 99 phb_id = find_first_zero_bit(phb_bitmap, MAX_PHBS); 120 100 BUG_ON(phb_id >= MAX_PHBS); 121 101 set_bit(phb_id, phb_bitmap); ··· 1101 1087 */ 1102 1088 pci_read_bridge_bases(bus); 1103 1089 1104 - /* Now fixup the bus bus */ 1090 + /* Now fixup the bus */ 1105 1091 pcibios_setup_bus_self(bus); 1106 1092 } 1107 1093 EXPORT_SYMBOL(pcibios_fixup_bus);
+21 -6
arch/powerpc/kernel/pci_32.c
··· 36 36 EXPORT_SYMBOL(isa_io_base); 37 37 EXPORT_SYMBOL(pci_dram_offset); 38 38 39 - void __init pcibios_make_OF_bus_map(void); 40 - 41 39 static void fixup_cpc710_pci64(struct pci_dev* dev); 42 - static u8* pci_to_OF_bus_map; 43 40 44 41 /* By default, we don't re-assign bus numbers. We do this only on 45 42 * some pmacs 46 43 */ 47 44 static int pci_assign_all_buses; 48 - 49 - static int pci_bus_count; 50 45 51 46 /* This will remain NULL for now, until isa-bridge.c is made common 52 47 * to both 32-bit and 64-bit. ··· 61 66 dev->resource[1].flags = 0; 62 67 } 63 68 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64); 69 + 70 + #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_CHRP) 71 + 72 + static u8* pci_to_OF_bus_map; 73 + static int pci_bus_count; 64 74 65 75 /* 66 76 * Functions below are used on OpenFirmware machines. ··· 108 108 } 109 109 } 110 110 111 - void __init 111 + static void __init 112 112 pcibios_make_OF_bus_map(void) 113 113 { 114 114 int i; ··· 154 154 } 155 155 156 156 157 + #ifdef CONFIG_PPC_PMAC 157 158 /* 158 159 * Returns the PCI device matching a given OF node 159 160 */ ··· 194 193 return -ENODEV; 195 194 } 196 195 EXPORT_SYMBOL(pci_device_from_OF_node); 196 + #endif 197 197 198 + #ifdef CONFIG_PPC_CHRP 198 199 /* We create the "pci-OF-bus-map" property now so it appears in the 199 200 * /proc device tree 200 201 */ ··· 221 218 of_node_put(dn); 222 219 } 223 220 } 221 + #endif 222 + 223 + #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_CHRP) */ 224 224 225 225 void pcibios_setup_phb_io_space(struct pci_controller *hose) 226 226 { ··· 239 233 static int __init pcibios_init(void) 240 234 { 241 235 struct pci_controller *hose, *tmp; 236 + #ifndef CONFIG_PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT 242 237 int next_busno = 0; 238 + #endif 243 239 244 240 printk(KERN_INFO "PCI: Probing PCI hardware\n"); 245 241 ··· 250 242 251 243 /* Scan all of the recorded PCI controllers. */ 252 244 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 245 + #ifndef CONFIG_PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT 253 246 if (pci_assign_all_buses) 254 247 hose->first_busno = next_busno; 248 + #endif 255 249 hose->last_busno = 0xff; 256 250 pcibios_scan_phb(hose); 257 251 pci_bus_add_devices(hose->bus); 252 + #ifndef CONFIG_PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT 258 253 if (pci_assign_all_buses || next_busno <= hose->last_busno) 259 254 next_busno = hose->last_busno + pcibios_assign_bus_offset; 255 + #endif 260 256 } 257 + 258 + #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_CHRP) 261 259 pci_bus_count = next_busno; 262 260 263 261 /* OpenFirmware based machines need a map of OF bus ··· 272 258 */ 273 259 if (pci_assign_all_buses) 274 260 pcibios_make_OF_bus_map(); 261 + #endif 275 262 276 263 /* Call common code to handle resource allocation */ 277 264 pcibios_resource_survey();
+2
arch/powerpc/kernel/pci_64.c
··· 286 286 EXPORT_SYMBOL(pcibus_to_node); 287 287 #endif 288 288 289 + #ifdef CONFIG_PPC_PMAC 289 290 int pci_device_from_OF_node(struct device_node *np, u8 *bus, u8 *devfn) 290 291 { 291 292 if (!PCI_DN(np)) ··· 295 294 *devfn = PCI_DN(np)->devfn; 296 295 return 0; 297 296 } 297 + #endif
+1 -1
arch/powerpc/kernel/pci_dn.c
··· 259 259 if (edev) { 260 260 /* 261 261 * We allocate pci_dn's for the totalvfs count, 262 - * but only only the vfs that were activated 262 + * but only the vfs that were activated 263 263 * have a configured PE. 264 264 */ 265 265 if (edev->pe)
+9 -1
arch/powerpc/kernel/prom.c
··· 44 44 #include <asm/iommu.h> 45 45 #include <asm/btext.h> 46 46 #include <asm/sections.h> 47 - #include <asm/machdep.h> 47 + #include <asm/setup.h> 48 48 #include <asm/pci-bridge.h> 49 49 #include <asm/kexec.h> 50 50 #include <asm/opal.h> ··· 54 54 #include <asm/dt_cpu_ftrs.h> 55 55 #include <asm/drmem.h> 56 56 #include <asm/ultravisor.h> 57 + #include <asm/prom.h> 57 58 58 59 #include <mm/mmu_decl.h> 59 60 ··· 752 751 early_init_dt_scan_root(); 753 752 early_init_dt_scan_memory_ppc(); 754 753 754 + /* 755 + * As generic code authors expect to be able to use static keys 756 + * in early_param() handlers, we initialize the static keys just 757 + * before parsing early params (it's fine to call jump_label_init() 758 + * more than once). 759 + */ 760 + jump_label_init(); 755 761 parse_early_param(); 756 762 757 763 /* make sure we've parsed cmdline for mem= before this */
+1 -1
arch/powerpc/kernel/prom_init.c
··· 42 42 #include <asm/iommu.h> 43 43 #include <asm/btext.h> 44 44 #include <asm/sections.h> 45 - #include <asm/machdep.h> 45 + #include <asm/setup.h> 46 46 #include <asm/asm-prototypes.h> 47 47 #include <asm/ultravisor-api.h> 48 48
+1 -1
arch/powerpc/kernel/ptrace/ptrace-vsx.c
··· 71 71 } 72 72 73 73 /* 74 - * Currently to set and and get all the vsx state, you need to call 74 + * Currently to set and get all the vsx state, you need to call 75 75 * the fp and VMX calls as well. This only get/sets the lower 32 76 76 * 128bit VSX registers. 77 77 */
-1
arch/powerpc/kernel/setup_64.c
··· 113 113 * Should we panic instead? 114 114 */ 115 115 WARN_ONCE(smt_enabled_at_boot >= 2 && 116 - !mmu_has_feature(MMU_FTR_USE_TLBRSRV) && 117 116 book3e_htw_mode != PPC_HTW_E6500, 118 117 "%s: unsupported MMU configuration\n", __func__); 119 118 }
+6 -3
arch/powerpc/kernel/signal_64.c
··· 377 377 unsafe_get_user(set->sig[0], &sc->oldmask, efault_out); 378 378 379 379 /* 380 - * Force reload of FP/VEC. 381 - * This has to be done before copying stuff into tsk->thread.fpr/vr 382 - * for the reasons explained in the previous comment. 380 + * Force reload of FP/VEC/VSX so userspace sees any changes. 381 + * Clear these bits from the user process' MSR before copying into the 382 + * thread struct. If we are rescheduled or preempted and another task 383 + * uses FP/VEC/VSX, and this process has the MSR bits set, then the 384 + * context switch code will save the current CPU state into the 385 + * thread_struct - possibly overwriting the data we are updating here. 383 386 */ 384 387 regs_set_return_msr(regs, regs->msr & ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC | MSR_VSX)); 385 388
+9 -20
arch/powerpc/kernel/smp.c
··· 35 35 #include <linux/stackprotector.h> 36 36 #include <linux/pgtable.h> 37 37 #include <linux/clockchips.h> 38 + #include <linux/kexec.h> 38 39 39 40 #include <asm/ptrace.h> 40 41 #include <linux/atomic.h> ··· 56 55 #endif 57 56 #include <asm/vdso.h> 58 57 #include <asm/debug.h> 59 - #include <asm/kexec.h> 60 58 #include <asm/cpu_has_feature.h> 61 59 #include <asm/ftrace.h> 62 60 #include <asm/kup.h> ··· 619 619 } 620 620 #endif 621 621 622 - #ifdef CONFIG_NMI_IPI 623 - static void crash_stop_this_cpu(struct pt_regs *regs) 624 - #else 625 - static void crash_stop_this_cpu(void *dummy) 626 - #endif 627 - { 628 - /* 629 - * Just busy wait here and avoid marking CPU as offline to ensure 630 - * register data is captured appropriately. 631 - */ 632 - while (1) 633 - cpu_relax(); 634 - } 635 - 636 622 void crash_smp_send_stop(void) 637 623 { 638 624 static bool stopped = false; ··· 637 651 638 652 stopped = true; 639 653 640 - #ifdef CONFIG_NMI_IPI 641 - smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 1000000); 642 - #else 643 - smp_call_function(crash_stop_this_cpu, NULL, 0); 644 - #endif /* CONFIG_NMI_IPI */ 654 + #ifdef CONFIG_KEXEC_CORE 655 + if (kexec_crash_image) { 656 + crash_kexec_prepare(); 657 + return; 658 + } 659 + #endif 660 + 661 + smp_send_stop(); 645 662 } 646 663 647 664 #ifdef CONFIG_NMI_IPI
+190
arch/powerpc/kernel/syscall.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + #include <linux/compat.h> 4 + #include <linux/context_tracking.h> 5 + #include <linux/randomize_kstack.h> 6 + 7 + #include <asm/interrupt.h> 8 + #include <asm/kup.h> 9 + #include <asm/syscall.h> 10 + #include <asm/time.h> 11 + #include <asm/tm.h> 12 + #include <asm/unistd.h> 13 + 14 + 15 + typedef long (*syscall_fn)(long, long, long, long, long, long); 16 + 17 + /* Has to run notrace because it is entered not completely "reconciled" */ 18 + notrace long system_call_exception(long r3, long r4, long r5, 19 + long r6, long r7, long r8, 20 + unsigned long r0, struct pt_regs *regs) 21 + { 22 + long ret; 23 + syscall_fn f; 24 + 25 + kuap_lock(); 26 + 27 + add_random_kstack_offset(); 28 + regs->orig_gpr3 = r3; 29 + 30 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 31 + BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED); 32 + 33 + trace_hardirqs_off(); /* finish reconciling */ 34 + 35 + CT_WARN_ON(ct_state() == CONTEXT_KERNEL); 36 + user_exit_irqoff(); 37 + 38 + BUG_ON(regs_is_unrecoverable(regs)); 39 + BUG_ON(!(regs->msr & MSR_PR)); 40 + BUG_ON(arch_irq_disabled_regs(regs)); 41 + 42 + #ifdef CONFIG_PPC_PKEY 43 + if (mmu_has_feature(MMU_FTR_PKEY)) { 44 + unsigned long amr, iamr; 45 + bool flush_needed = false; 46 + /* 47 + * When entering from userspace we mostly have the AMR/IAMR 48 + * different from kernel default values. Hence don't compare. 49 + */ 50 + amr = mfspr(SPRN_AMR); 51 + iamr = mfspr(SPRN_IAMR); 52 + regs->amr = amr; 53 + regs->iamr = iamr; 54 + if (mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) { 55 + mtspr(SPRN_AMR, AMR_KUAP_BLOCKED); 56 + flush_needed = true; 57 + } 58 + if (mmu_has_feature(MMU_FTR_BOOK3S_KUEP)) { 59 + mtspr(SPRN_IAMR, AMR_KUEP_BLOCKED); 60 + flush_needed = true; 61 + } 62 + if (flush_needed) 63 + isync(); 64 + } else 65 + #endif 66 + kuap_assert_locked(); 67 + 68 + booke_restore_dbcr0(); 69 + 70 + account_cpu_user_entry(); 71 + 72 + account_stolen_time(); 73 + 74 + /* 75 + * This is not required for the syscall exit path, but makes the 76 + * stack frame look nicer. If this was initialised in the first stack 77 + * frame, or if the unwinder was taught the first stack frame always 78 + * returns to user with IRQS_ENABLED, this store could be avoided! 79 + */ 80 + irq_soft_mask_regs_set_state(regs, IRQS_ENABLED); 81 + 82 + /* 83 + * If system call is called with TM active, set _TIF_RESTOREALL to 84 + * prevent RFSCV being used to return to userspace, because POWER9 85 + * TM implementation has problems with this instruction returning to 86 + * transactional state. Final register values are not relevant because 87 + * the transaction will be aborted upon return anyway. Or in the case 88 + * of unsupported_scv SIGILL fault, the return state does not much 89 + * matter because it's an edge case. 90 + */ 91 + if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && 92 + unlikely(MSR_TM_TRANSACTIONAL(regs->msr))) 93 + set_bits(_TIF_RESTOREALL, &current_thread_info()->flags); 94 + 95 + /* 96 + * If the system call was made with a transaction active, doom it and 97 + * return without performing the system call. Unless it was an 98 + * unsupported scv vector, in which case it's treated like an illegal 99 + * instruction. 100 + */ 101 + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 102 + if (unlikely(MSR_TM_TRANSACTIONAL(regs->msr)) && 103 + !trap_is_unsupported_scv(regs)) { 104 + /* Enable TM in the kernel, and disable EE (for scv) */ 105 + hard_irq_disable(); 106 + mtmsr(mfmsr() | MSR_TM); 107 + 108 + /* tabort, this dooms the transaction, nothing else */ 109 + asm volatile(".long 0x7c00071d | ((%0) << 16)" 110 + :: "r"(TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)); 111 + 112 + /* 113 + * Userspace will never see the return value. Execution will 114 + * resume after the tbegin. of the aborted transaction with the 115 + * checkpointed register state. A context switch could occur 116 + * or signal delivered to the process before resuming the 117 + * doomed transaction context, but that should all be handled 118 + * as expected. 119 + */ 120 + return -ENOSYS; 121 + } 122 + #endif // CONFIG_PPC_TRANSACTIONAL_MEM 123 + 124 + local_irq_enable(); 125 + 126 + if (unlikely(read_thread_flags() & _TIF_SYSCALL_DOTRACE)) { 127 + if (unlikely(trap_is_unsupported_scv(regs))) { 128 + /* Unsupported scv vector */ 129 + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); 130 + return regs->gpr[3]; 131 + } 132 + /* 133 + * We use the return value of do_syscall_trace_enter() as the 134 + * syscall number. If the syscall was rejected for any reason 135 + * do_syscall_trace_enter() returns an invalid syscall number 136 + * and the test against NR_syscalls will fail and the return 137 + * value to be used is in regs->gpr[3]. 138 + */ 139 + r0 = do_syscall_trace_enter(regs); 140 + if (unlikely(r0 >= NR_syscalls)) 141 + return regs->gpr[3]; 142 + r3 = regs->gpr[3]; 143 + r4 = regs->gpr[4]; 144 + r5 = regs->gpr[5]; 145 + r6 = regs->gpr[6]; 146 + r7 = regs->gpr[7]; 147 + r8 = regs->gpr[8]; 148 + 149 + } else if (unlikely(r0 >= NR_syscalls)) { 150 + if (unlikely(trap_is_unsupported_scv(regs))) { 151 + /* Unsupported scv vector */ 152 + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); 153 + return regs->gpr[3]; 154 + } 155 + return -ENOSYS; 156 + } 157 + 158 + /* May be faster to do array_index_nospec? */ 159 + barrier_nospec(); 160 + 161 + if (unlikely(is_compat_task())) { 162 + f = (void *)compat_sys_call_table[r0]; 163 + 164 + r3 &= 0x00000000ffffffffULL; 165 + r4 &= 0x00000000ffffffffULL; 166 + r5 &= 0x00000000ffffffffULL; 167 + r6 &= 0x00000000ffffffffULL; 168 + r7 &= 0x00000000ffffffffULL; 169 + r8 &= 0x00000000ffffffffULL; 170 + 171 + } else { 172 + f = (void *)sys_call_table[r0]; 173 + } 174 + 175 + ret = f(r3, r4, r5, r6, r7, r8); 176 + 177 + /* 178 + * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), 179 + * so the maximum stack offset is 1k bytes (10 bits). 180 + * 181 + * The actual entropy will be further reduced by the compiler when 182 + * applying stack alignment constraints: the powerpc architecture 183 + * may have two kinds of stack alignment (16-bytes and 8-bytes). 184 + * 185 + * So the resulting 6 or 7 bits of entropy is seen in SP[9:4] or SP[9:3]. 186 + */ 187 + choose_random_kstack_offset(mftb()); 188 + 189 + return ret; 190 + }
+16 -14
arch/powerpc/kernel/trace/ftrace.c
··· 69 69 70 70 /* Make sure it is what we expect it to be */ 71 71 if (!ppc_inst_equal(replaced, old)) { 72 - pr_err("%p: replaced (%s) != old (%s)", 73 - (void *)ip, ppc_inst_as_str(replaced), ppc_inst_as_str(old)); 72 + pr_err("%p: replaced (%08lx) != old (%08lx)", (void *)ip, 73 + ppc_inst_as_ulong(replaced), ppc_inst_as_ulong(old)); 74 74 return -EINVAL; 75 75 } 76 76 ··· 125 125 return -EFAULT; 126 126 } 127 127 128 - /* Make sure that that this is still a 24bit jump */ 128 + /* Make sure that this is still a 24bit jump */ 129 129 if (!is_bl_op(op)) { 130 - pr_err("Not expected bl: opcode is %s\n", ppc_inst_as_str(op)); 130 + pr_err("Not expected bl: opcode is %08lx\n", ppc_inst_as_ulong(op)); 131 131 return -EINVAL; 132 132 } 133 133 ··· 159 159 /* We expect either a mflr r0, or a std r0, LRSAVE(r1) */ 160 160 if (!ppc_inst_equal(op, ppc_inst(PPC_RAW_MFLR(_R0))) && 161 161 !ppc_inst_equal(op, ppc_inst(PPC_INST_STD_LR))) { 162 - pr_err("Unexpected instruction %s around bl _mcount\n", 163 - ppc_inst_as_str(op)); 162 + pr_err("Unexpected instruction %08lx around bl _mcount\n", 163 + ppc_inst_as_ulong(op)); 164 164 return -EINVAL; 165 165 } 166 166 } else if (IS_ENABLED(CONFIG_PPC64)) { ··· 174 174 } 175 175 176 176 if (!ppc_inst_equal(op, ppc_inst(PPC_INST_LD_TOC))) { 177 - pr_err("Expected %08lx found %s\n", PPC_INST_LD_TOC, ppc_inst_as_str(op)); 177 + pr_err("Expected %08lx found %08lx\n", PPC_INST_LD_TOC, 178 + ppc_inst_as_ulong(op)); 178 179 return -EINVAL; 179 180 } 180 181 } ··· 311 310 return -EFAULT; 312 311 } 313 312 314 - /* Make sure that that this is still a 24bit jump */ 313 + /* Make sure that this is still a 24bit jump */ 315 314 if (!is_bl_op(op)) { 316 - pr_err("Not expected bl: opcode is %s\n", ppc_inst_as_str(op)); 315 + pr_err("Not expected bl: opcode is %08lx\n", ppc_inst_as_ulong(op)); 317 316 return -EINVAL; 318 317 } 319 318 ··· 417 416 return -EFAULT; 418 417 419 418 if (!expected_nop_sequence(ip, op[0], op[1])) { 420 - pr_err("Unexpected call sequence at %p: %s %s\n", 421 - ip, ppc_inst_as_str(op[0]), ppc_inst_as_str(op[1])); 419 + pr_err("Unexpected call sequence at %p: %08lx %08lx\n", ip, 420 + ppc_inst_as_ulong(op[0]), ppc_inst_as_ulong(op[1])); 422 421 return -EINVAL; 423 422 } 424 423 ··· 487 486 } 488 487 489 488 if (!ppc_inst_equal(op, ppc_inst(PPC_RAW_NOP()))) { 490 - pr_err("Unexpected call sequence at %p: %s\n", ip, ppc_inst_as_str(op)); 489 + pr_err("Unexpected call sequence at %p: %08lx\n", 490 + ip, ppc_inst_as_ulong(op)); 491 491 return -EINVAL; 492 492 } 493 493 ··· 564 562 return -EFAULT; 565 563 } 566 564 567 - /* Make sure that that this is still a 24bit jump */ 565 + /* Make sure that this is still a 24bit jump */ 568 566 if (!is_bl_op(op)) { 569 - pr_err("Not expected bl: opcode is %s\n", ppc_inst_as_str(op)); 567 + pr_err("Not expected bl: opcode is %08lx\n", ppc_inst_as_ulong(op)); 570 568 return -EINVAL; 571 569 } 572 570
+1 -1
arch/powerpc/kernel/traps.c
··· 1676 1676 die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT); 1677 1677 } 1678 1678 1679 - #ifdef CONFIG_PPC64 1679 + #ifdef CONFIG_PPC_BOOK3S_64 1680 1680 static void tm_unavailable(struct pt_regs *regs) 1681 1681 { 1682 1682 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+1
arch/powerpc/kernel/vdso/cacheflush.S
··· 91 91 3: 92 92 crclr cr0*4+so 93 93 sync 94 + icbi 0,r1 94 95 isync 95 96 li r3,0 96 97 blr
+21 -2
arch/powerpc/kernel/watchdog.c
··· 91 91 static cpumask_t wd_smp_cpus_stuck; 92 92 static u64 wd_smp_last_reset_tb; 93 93 94 + #ifdef CONFIG_PPC_PSERIES 95 + static u64 wd_timeout_pct; 96 + #endif 97 + 94 98 /* 95 99 * Try to take the exclusive watchdog action / NMI IPI / printing lock. 96 100 * wd_smp_lock must be held. If this fails, we should return and wait ··· 357 353 if (__wd_nmi_output && xchg(&__wd_nmi_output, 0)) { 358 354 /* 359 355 * Something has called printk from NMI context. It might be 360 - * stuck, so this this triggers a flush that will get that 356 + * stuck, so this triggers a flush that will get that 361 357 * printk output to the console. 362 358 * 363 359 * See wd_lockup_ipi. ··· 531 527 532 528 static void watchdog_calc_timeouts(void) 533 529 { 534 - wd_panic_timeout_tb = watchdog_thresh * ppc_tb_freq; 530 + u64 threshold = watchdog_thresh; 531 + 532 + #ifdef CONFIG_PPC_PSERIES 533 + threshold += (READ_ONCE(wd_timeout_pct) * threshold) / 100; 534 + #endif 535 + 536 + wd_panic_timeout_tb = threshold * ppc_tb_freq; 535 537 536 538 /* Have the SMP detector trigger a bit later */ 537 539 wd_smp_panic_timeout_tb = wd_panic_timeout_tb * 3 / 2; ··· 580 570 } 581 571 return 0; 582 572 } 573 + 574 + #ifdef CONFIG_PPC_PSERIES 575 + void watchdog_nmi_set_timeout_pct(u64 pct) 576 + { 577 + pr_info("Set the NMI watchdog timeout factor to %llu%%\n", pct); 578 + WRITE_ONCE(wd_timeout_pct, pct); 579 + lockup_detector_reconfigure(); 580 + } 581 + #endif
+2
arch/powerpc/kexec/core.c
··· 19 19 #include <asm/machdep.h> 20 20 #include <asm/pgalloc.h> 21 21 #include <asm/sections.h> 22 + #include <asm/setup.h> 23 + #include <asm/firmware.h> 22 24 23 25 void machine_kexec_mask_interrupts(void) { 24 26 unsigned int i;
+47 -30
arch/powerpc/kexec/crash.c
··· 40 40 #define REAL_MODE_TIMEOUT 10000 41 41 42 42 static int time_to_dump; 43 + 44 + /* 45 + * In case of system reset, secondary CPUs enter crash_kexec_secondary with out 46 + * having to send an IPI explicitly. So, indicate if the crash is via 47 + * system reset to avoid sending another IPI. 48 + */ 49 + static int is_via_system_reset; 50 + 43 51 /* 44 52 * crash_wake_offline should be set to 1 by platforms that intend to wake 45 53 * up offline cpus prior to jumping to a kdump kernel. Currently powernv ··· 109 101 /* NOTREACHED */ 110 102 } 111 103 112 - static void crash_kexec_prepare_cpus(int cpu) 104 + static void crash_kexec_prepare_cpus(void) 113 105 { 114 106 unsigned int msecs; 115 107 volatile unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ ··· 121 113 if (crash_wake_offline) 122 114 ncpus = num_present_cpus() - 1; 123 115 124 - crash_send_ipi(crash_ipi_callback); 116 + /* 117 + * If we came in via system reset, secondaries enter via crash_kexec_secondary(). 118 + * So, wait a while for the secondary CPUs to enter for that case. 119 + * Else, send IPI to all other CPUs. 120 + */ 121 + if (is_via_system_reset) 122 + mdelay(PRIMARY_TIMEOUT); 123 + else 124 + crash_send_ipi(crash_ipi_callback); 125 125 smp_wmb(); 126 126 127 127 again: ··· 218 202 219 203 #else /* ! CONFIG_SMP */ 220 204 221 - static void crash_kexec_prepare_cpus(int cpu) 205 + static void crash_kexec_prepare_cpus(void) 222 206 { 223 207 /* 224 208 * move the secondaries to us so that we can copy ··· 263 247 #else 264 248 static inline void crash_kexec_wait_realmode(int cpu) {} 265 249 #endif /* CONFIG_SMP && CONFIG_PPC64 */ 250 + 251 + void crash_kexec_prepare(void) 252 + { 253 + /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */ 254 + printk_deferred_enter(); 255 + 256 + /* 257 + * This function is only called after the system 258 + * has panicked or is otherwise in a critical state. 259 + * The minimum amount of code to allow a kexec'd kernel 260 + * to run successfully needs to happen here. 261 + * 262 + * In practice this means stopping other cpus in 263 + * an SMP system. 264 + * The kernel is broken so disable interrupts. 265 + */ 266 + hard_irq_disable(); 267 + 268 + /* 269 + * Make a note of crashing cpu. Will be used in machine_kexec 270 + * such that another IPI will not be sent. 271 + */ 272 + crashing_cpu = smp_processor_id(); 273 + 274 + crash_kexec_prepare_cpus(); 275 + } 266 276 267 277 /* 268 278 * Register a function to be called on shutdown. Only use this if you ··· 353 311 unsigned int i; 354 312 int (*old_handler)(struct pt_regs *regs); 355 313 356 - /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */ 357 - printk_deferred_enter(); 358 - 359 - /* 360 - * This function is only called after the system 361 - * has panicked or is otherwise in a critical state. 362 - * The minimum amount of code to allow a kexec'd kernel 363 - * to run successfully needs to happen here. 364 - * 365 - * In practice this means stopping other cpus in 366 - * an SMP system. 367 - * The kernel is broken so disable interrupts. 368 - */ 369 - hard_irq_disable(); 370 - 371 - /* 372 - * Make a note of crashing cpu. Will be used in machine_kexec 373 - * such that another IPI will not be sent. 374 - */ 375 - crashing_cpu = smp_processor_id(); 376 - 377 - /* 378 - * If we came in via system reset, wait a while for the secondary 379 - * CPUs to enter. 380 - */ 381 314 if (TRAP(regs) == INTERRUPT_SYSTEM_RESET) 382 - mdelay(PRIMARY_TIMEOUT); 315 + is_via_system_reset = 1; 383 316 384 - crash_kexec_prepare_cpus(crashing_cpu); 317 + crash_smp_send_stop(); 385 318 386 319 crash_save_cpu(regs, crashing_cpu); 387 320
+55
arch/powerpc/kexec/file_load_64.c
··· 23 23 #include <linux/vmalloc.h> 24 24 #include <asm/setup.h> 25 25 #include <asm/drmem.h> 26 + #include <asm/firmware.h> 26 27 #include <asm/kexec_ranges.h> 27 28 #include <asm/crashdump-ppc64.h> 28 29 ··· 1039 1038 return ret; 1040 1039 } 1041 1040 1041 + static int copy_property(void *fdt, int node_offset, const struct device_node *dn, 1042 + const char *propname) 1043 + { 1044 + const void *prop, *fdtprop; 1045 + int len = 0, fdtlen = 0, ret; 1046 + 1047 + prop = of_get_property(dn, propname, &len); 1048 + fdtprop = fdt_getprop(fdt, node_offset, propname, &fdtlen); 1049 + 1050 + if (fdtprop && !prop) 1051 + ret = fdt_delprop(fdt, node_offset, propname); 1052 + else if (prop) 1053 + ret = fdt_setprop(fdt, node_offset, propname, prop, len); 1054 + 1055 + return ret; 1056 + } 1057 + 1058 + static int update_pci_dma_nodes(void *fdt, const char *dmapropname) 1059 + { 1060 + struct device_node *dn; 1061 + int pci_offset, root_offset, ret = 0; 1062 + 1063 + if (!firmware_has_feature(FW_FEATURE_LPAR)) 1064 + return 0; 1065 + 1066 + root_offset = fdt_path_offset(fdt, "/"); 1067 + for_each_node_with_property(dn, dmapropname) { 1068 + pci_offset = fdt_subnode_offset(fdt, root_offset, of_node_full_name(dn)); 1069 + if (pci_offset < 0) 1070 + continue; 1071 + 1072 + ret = copy_property(fdt, pci_offset, dn, "ibm,dma-window"); 1073 + if (ret < 0) 1074 + break; 1075 + ret = copy_property(fdt, pci_offset, dn, dmapropname); 1076 + if (ret < 0) 1077 + break; 1078 + } 1079 + 1080 + return ret; 1081 + } 1082 + 1042 1083 /** 1043 1084 * setup_new_fdt_ppc64 - Update the flattend device-tree of the kernel 1044 1085 * being loaded. ··· 1141 1098 ret = update_cpus_node(fdt); 1142 1099 if (ret < 0) 1143 1100 goto out; 1101 + 1102 + #define DIRECT64_PROPNAME "linux,direct64-ddr-window-info" 1103 + #define DMA64_PROPNAME "linux,dma64-ddr-window-info" 1104 + ret = update_pci_dma_nodes(fdt, DIRECT64_PROPNAME); 1105 + if (ret < 0) 1106 + goto out; 1107 + 1108 + ret = update_pci_dma_nodes(fdt, DMA64_PROPNAME); 1109 + if (ret < 0) 1110 + goto out; 1111 + #undef DMA64_PROPNAME 1112 + #undef DIRECT64_PROPNAME 1144 1113 1145 1114 /* Update memory reserve map */ 1146 1115 ret = get_reserved_memory_ranges(&rmem);
+19 -2
arch/powerpc/kvm/Kconfig
··· 128 128 and system calls on the host. 129 129 130 130 config KVM_BOOK3S_HV_EXIT_TIMING 131 - bool "Detailed timing for hypervisor real-mode code" 131 + bool 132 + 133 + config KVM_BOOK3S_HV_P9_TIMING 134 + bool "Detailed timing for the P9 entry point" 135 + select KVM_BOOK3S_HV_EXIT_TIMING 132 136 depends on KVM_BOOK3S_HV_POSSIBLE && DEBUG_FS 137 + help 138 + Calculate time taken for each vcpu during vcpu entry and 139 + exit, time spent inside the guest and time spent handling 140 + hypercalls and page faults. The total, minimum and maximum 141 + times in nanoseconds together with the number of executions 142 + are reported in debugfs in kvm/vm#/vcpu#/timings. 143 + 144 + If unsure, say N. 145 + 146 + config KVM_BOOK3S_HV_P8_TIMING 147 + bool "Detailed timing for hypervisor real-mode code (for POWER8)" 148 + select KVM_BOOK3S_HV_EXIT_TIMING 149 + depends on KVM_BOOK3S_HV_POSSIBLE && DEBUG_FS && !KVM_BOOK3S_HV_P9_TIMING 133 150 help 134 151 Calculate time taken for each vcpu in the real-mode guest entry, 135 152 exit, and interrupt handling code, plus time spent in the guest ··· 166 149 Old nested HV capable Linux guests have a bug where they don't 167 150 reflect the PMU in-use status of their L2 guest to the L0 host 168 151 while the L2 PMU registers are live. This can result in loss 169 - of L2 PMU register state, causing perf to not work correctly in 152 + of L2 PMU register state, causing perf to not work correctly in 170 153 L2 guests. 171 154 172 155 Selecting this option for the L0 host implements a workaround for
+1
arch/powerpc/kvm/Makefile
··· 86 86 book3s_hv_rm_mmu.o \ 87 87 book3s_hv_ras.o \ 88 88 book3s_hv_builtin.o \ 89 + book3s_hv_p9_perf.o \ 89 90 $(kvm-book3s_64-builtin-tm-objs-y) \ 90 91 $(kvm-book3s_64-builtin-xics-objs-y) 91 92 endif
+1
arch/powerpc/kvm/book3s_64_mmu_radix.c
··· 22 22 #include <asm/ultravisor.h> 23 23 #include <asm/kvm_book3s_uvmem.h> 24 24 #include <asm/plpar_wrappers.h> 25 + #include <asm/firmware.h> 25 26 26 27 /* 27 28 * Supported radix tree geometry.
+1 -1
arch/powerpc/kvm/book3s_64_vio.c
··· 307 307 return ret; 308 308 309 309 ret = -ENOMEM; 310 - stt = kzalloc(struct_size(stt, pages, npages), GFP_KERNEL); 310 + stt = kzalloc(struct_size(stt, pages, npages), GFP_KERNEL | __GFP_NOWARN); 311 311 if (!stt) 312 312 goto fail_acct; 313 313
+25 -3
arch/powerpc/kvm/book3s_hv.c
··· 2660 2660 const char *name; 2661 2661 size_t offset; 2662 2662 } timings[] = { 2663 + #ifdef CONFIG_KVM_BOOK3S_HV_P9_TIMING 2664 + {"vcpu_entry", offsetof(struct kvm_vcpu, arch.vcpu_entry)}, 2665 + {"guest_entry", offsetof(struct kvm_vcpu, arch.guest_entry)}, 2666 + {"in_guest", offsetof(struct kvm_vcpu, arch.in_guest)}, 2667 + {"guest_exit", offsetof(struct kvm_vcpu, arch.guest_exit)}, 2668 + {"vcpu_exit", offsetof(struct kvm_vcpu, arch.vcpu_exit)}, 2669 + {"hypercall", offsetof(struct kvm_vcpu, arch.hcall)}, 2670 + {"page_fault", offsetof(struct kvm_vcpu, arch.pg_fault)}, 2671 + #else 2663 2672 {"rm_entry", offsetof(struct kvm_vcpu, arch.rm_entry)}, 2664 2673 {"rm_intr", offsetof(struct kvm_vcpu, arch.rm_intr)}, 2665 2674 {"rm_exit", offsetof(struct kvm_vcpu, arch.rm_exit)}, 2666 2675 {"guest", offsetof(struct kvm_vcpu, arch.guest_time)}, 2667 2676 {"cede", offsetof(struct kvm_vcpu, arch.cede_time)}, 2677 + #endif 2668 2678 }; 2669 2679 2670 2680 #define N_TIMINGS (ARRAY_SIZE(timings)) ··· 2793 2783 /* Create a debugfs directory for the vcpu */ 2794 2784 static int kvmppc_arch_create_vcpu_debugfs_hv(struct kvm_vcpu *vcpu, struct dentry *debugfs_dentry) 2795 2785 { 2796 - debugfs_create_file("timings", 0444, debugfs_dentry, vcpu, 2797 - &debugfs_timings_ops); 2786 + if (cpu_has_feature(CPU_FTR_ARCH_300) == IS_ENABLED(CONFIG_KVM_BOOK3S_HV_P9_TIMING)) 2787 + debugfs_create_file("timings", 0444, debugfs_dentry, vcpu, 2788 + &debugfs_timings_ops); 2798 2789 return 0; 2799 2790 } 2800 2791 ··· 4016 4005 mtspr(SPRN_DAR, vcpu->arch.shregs.dar); 4017 4006 mtspr(SPRN_DSISR, vcpu->arch.shregs.dsisr); 4018 4007 switch_pmu_to_guest(vcpu, &host_os_sprs); 4008 + accumulate_time(vcpu, &vcpu->arch.in_guest); 4019 4009 trap = plpar_hcall_norets(H_ENTER_NESTED, __pa(&hvregs), 4020 4010 __pa(&vcpu->arch.regs)); 4011 + accumulate_time(vcpu, &vcpu->arch.guest_exit); 4021 4012 kvmhv_restore_hv_return_state(vcpu, &hvregs); 4022 4013 switch_pmu_to_host(vcpu, &host_os_sprs); 4023 4014 vcpu->arch.shregs.msr = vcpu->arch.regs.msr; ··· 4707 4694 struct kvm *kvm; 4708 4695 unsigned long msr; 4709 4696 4697 + start_timing(vcpu, &vcpu->arch.vcpu_entry); 4698 + 4710 4699 if (!vcpu->arch.sane) { 4711 4700 run->exit_reason = KVM_EXIT_INTERNAL_ERROR; 4712 4701 return -EINVAL; ··· 4774 4759 vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST; 4775 4760 4776 4761 do { 4762 + accumulate_time(vcpu, &vcpu->arch.guest_entry); 4777 4763 if (cpu_has_feature(CPU_FTR_ARCH_300)) 4778 4764 r = kvmhv_run_single_vcpu(vcpu, ~(u64)0, 4779 4765 vcpu->arch.vcore->lpcr); ··· 4782 4766 r = kvmppc_run_vcpu(vcpu); 4783 4767 4784 4768 if (run->exit_reason == KVM_EXIT_PAPR_HCALL) { 4769 + accumulate_time(vcpu, &vcpu->arch.hcall); 4770 + 4785 4771 if (WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_PR)) { 4786 4772 /* 4787 4773 * These should have been caught reflected ··· 4799 4781 trace_kvm_hcall_exit(vcpu, r); 4800 4782 kvmppc_core_prepare_to_enter(vcpu); 4801 4783 } else if (r == RESUME_PAGE_FAULT) { 4784 + accumulate_time(vcpu, &vcpu->arch.pg_fault); 4802 4785 srcu_idx = srcu_read_lock(&kvm->srcu); 4803 4786 r = kvmppc_book3s_hv_page_fault(vcpu, 4804 4787 vcpu->arch.fault_dar, vcpu->arch.fault_dsisr); ··· 4811 4792 r = kvmppc_xics_rm_complete(vcpu, 0); 4812 4793 } 4813 4794 } while (is_kvmppc_resume_guest(r)); 4795 + accumulate_time(vcpu, &vcpu->arch.vcpu_exit); 4814 4796 4815 4797 vcpu->arch.state = KVMPPC_VCPU_NOTREADY; 4816 4798 atomic_dec(&kvm->arch.vcpus_running); 4817 4799 4818 4800 srr_regs_clobbered(); 4801 + 4802 + end_timing(vcpu); 4819 4803 4820 4804 return r; 4821 4805 } ··· 5665 5643 else 5666 5644 kvmppc_xics_clr_mapped(kvm, guest_gsi, pimap->mapped[i].r_hwirq); 5667 5645 5668 - /* invalidate the entry (what do do on error from the above ?) */ 5646 + /* invalidate the entry (what to do on error from the above ?) */ 5669 5647 pimap->mapped[i].r_hwirq = 0; 5670 5648 5671 5649 /*
+10
arch/powerpc/kvm/book3s_hv.h
··· 40 40 struct p9_host_os_sprs *host_os_sprs); 41 41 void switch_pmu_to_host(struct kvm_vcpu *vcpu, 42 42 struct p9_host_os_sprs *host_os_sprs); 43 + 44 + #ifdef CONFIG_KVM_BOOK3S_HV_P9_TIMING 45 + void accumulate_time(struct kvm_vcpu *vcpu, struct kvmhv_tb_accumulator *next); 46 + #define start_timing(vcpu, next) accumulate_time(vcpu, next) 47 + #define end_timing(vcpu) accumulate_time(vcpu, NULL) 48 + #else 49 + #define accumulate_time(vcpu, next) do {} while (0) 50 + #define start_timing(vcpu, next) do {} while (0) 51 + #define end_timing(vcpu) do {} while (0) 52 + #endif
+4 -21
arch/powerpc/kvm/book3s_hv_builtin.c
··· 19 19 #include <asm/interrupt.h> 20 20 #include <asm/kvm_ppc.h> 21 21 #include <asm/kvm_book3s.h> 22 - #include <asm/archrandom.h> 22 + #include <asm/machdep.h> 23 23 #include <asm/xics.h> 24 24 #include <asm/xive.h> 25 25 #include <asm/dbell.h> ··· 176 176 177 177 int kvmppc_hwrng_present(void) 178 178 { 179 - return powernv_hwrng_present(); 179 + return ppc_md.get_random_seed != NULL; 180 180 } 181 181 EXPORT_SYMBOL_GPL(kvmppc_hwrng_present); 182 182 183 183 long kvmppc_rm_h_random(struct kvm_vcpu *vcpu) 184 184 { 185 - if (powernv_get_random_real_mode(&vcpu->arch.regs.gpr[4])) 185 + if (ppc_md.get_random_seed && 186 + ppc_md.get_random_seed(&vcpu->arch.regs.gpr[4])) 186 187 return H_SUCCESS; 187 188 188 189 return H_HARDWARE; ··· 488 487 } 489 488 490 489 return kvmppc_check_passthru(xisr, xirr, again); 491 - } 492 - 493 - void kvmppc_bad_interrupt(struct pt_regs *regs) 494 - { 495 - /* 496 - * 100 could happen at any time, 200 can happen due to invalid real 497 - * address access for example (or any time due to a hardware problem). 498 - */ 499 - if (TRAP(regs) == 0x100) { 500 - get_paca()->in_nmi++; 501 - system_reset_exception(regs); 502 - get_paca()->in_nmi--; 503 - } else if (TRAP(regs) == 0x200) { 504 - machine_check_exception(regs); 505 - } else { 506 - die("Bad interrupt in KVM entry/exit code", regs, SIGABRT); 507 - } 508 - panic("Bad KVM trap"); 509 490 } 510 491 511 492 static void kvmppc_end_cede(struct kvm_vcpu *vcpu)
+1
arch/powerpc/kvm/book3s_hv_nested.c
··· 20 20 #include <asm/pte-walk.h> 21 21 #include <asm/reg.h> 22 22 #include <asm/plpar_wrappers.h> 23 + #include <asm/firmware.h> 23 24 24 25 static struct patb_entry *pseries_partition_tb; 25 26
+8 -251
arch/powerpc/kvm/book3s_hv_p9_entry.c
··· 3 3 #include <linux/kvm_host.h> 4 4 #include <asm/asm-prototypes.h> 5 5 #include <asm/dbell.h> 6 - #include <asm/kvm_ppc.h> 7 - #include <asm/pmc.h> 8 6 #include <asm/ppc-opcode.h> 9 7 10 8 #include "book3s_hv.h" 11 - 12 - static void freeze_pmu(unsigned long mmcr0, unsigned long mmcra) 13 - { 14 - if (!(mmcr0 & MMCR0_FC)) 15 - goto do_freeze; 16 - if (mmcra & MMCRA_SAMPLE_ENABLE) 17 - goto do_freeze; 18 - if (cpu_has_feature(CPU_FTR_ARCH_31)) { 19 - if (!(mmcr0 & MMCR0_PMCCEXT)) 20 - goto do_freeze; 21 - if (!(mmcra & MMCRA_BHRB_DISABLE)) 22 - goto do_freeze; 23 - } 24 - return; 25 - 26 - do_freeze: 27 - mmcr0 = MMCR0_FC; 28 - mmcra = 0; 29 - if (cpu_has_feature(CPU_FTR_ARCH_31)) { 30 - mmcr0 |= MMCR0_PMCCEXT; 31 - mmcra = MMCRA_BHRB_DISABLE; 32 - } 33 - 34 - mtspr(SPRN_MMCR0, mmcr0); 35 - mtspr(SPRN_MMCRA, mmcra); 36 - isync(); 37 - } 38 - 39 - void switch_pmu_to_guest(struct kvm_vcpu *vcpu, 40 - struct p9_host_os_sprs *host_os_sprs) 41 - { 42 - struct lppaca *lp; 43 - int load_pmu = 1; 44 - 45 - lp = vcpu->arch.vpa.pinned_addr; 46 - if (lp) 47 - load_pmu = lp->pmcregs_in_use; 48 - 49 - /* Save host */ 50 - if (ppc_get_pmu_inuse()) { 51 - /* 52 - * It might be better to put PMU handling (at least for the 53 - * host) in the perf subsystem because it knows more about what 54 - * is being used. 55 - */ 56 - 57 - /* POWER9, POWER10 do not implement HPMC or SPMC */ 58 - 59 - host_os_sprs->mmcr0 = mfspr(SPRN_MMCR0); 60 - host_os_sprs->mmcra = mfspr(SPRN_MMCRA); 61 - 62 - freeze_pmu(host_os_sprs->mmcr0, host_os_sprs->mmcra); 63 - 64 - host_os_sprs->pmc1 = mfspr(SPRN_PMC1); 65 - host_os_sprs->pmc2 = mfspr(SPRN_PMC2); 66 - host_os_sprs->pmc3 = mfspr(SPRN_PMC3); 67 - host_os_sprs->pmc4 = mfspr(SPRN_PMC4); 68 - host_os_sprs->pmc5 = mfspr(SPRN_PMC5); 69 - host_os_sprs->pmc6 = mfspr(SPRN_PMC6); 70 - host_os_sprs->mmcr1 = mfspr(SPRN_MMCR1); 71 - host_os_sprs->mmcr2 = mfspr(SPRN_MMCR2); 72 - host_os_sprs->sdar = mfspr(SPRN_SDAR); 73 - host_os_sprs->siar = mfspr(SPRN_SIAR); 74 - host_os_sprs->sier1 = mfspr(SPRN_SIER); 75 - 76 - if (cpu_has_feature(CPU_FTR_ARCH_31)) { 77 - host_os_sprs->mmcr3 = mfspr(SPRN_MMCR3); 78 - host_os_sprs->sier2 = mfspr(SPRN_SIER2); 79 - host_os_sprs->sier3 = mfspr(SPRN_SIER3); 80 - } 81 - } 82 - 83 - #ifdef CONFIG_PPC_PSERIES 84 - /* After saving PMU, before loading guest PMU, flip pmcregs_in_use */ 85 - if (kvmhv_on_pseries()) { 86 - barrier(); 87 - get_lppaca()->pmcregs_in_use = load_pmu; 88 - barrier(); 89 - } 90 - #endif 91 - 92 - /* 93 - * Load guest. If the VPA said the PMCs are not in use but the guest 94 - * tried to access them anyway, HFSCR[PM] will be set by the HFAC 95 - * fault so we can make forward progress. 96 - */ 97 - if (load_pmu || (vcpu->arch.hfscr & HFSCR_PM)) { 98 - mtspr(SPRN_PMC1, vcpu->arch.pmc[0]); 99 - mtspr(SPRN_PMC2, vcpu->arch.pmc[1]); 100 - mtspr(SPRN_PMC3, vcpu->arch.pmc[2]); 101 - mtspr(SPRN_PMC4, vcpu->arch.pmc[3]); 102 - mtspr(SPRN_PMC5, vcpu->arch.pmc[4]); 103 - mtspr(SPRN_PMC6, vcpu->arch.pmc[5]); 104 - mtspr(SPRN_MMCR1, vcpu->arch.mmcr[1]); 105 - mtspr(SPRN_MMCR2, vcpu->arch.mmcr[2]); 106 - mtspr(SPRN_SDAR, vcpu->arch.sdar); 107 - mtspr(SPRN_SIAR, vcpu->arch.siar); 108 - mtspr(SPRN_SIER, vcpu->arch.sier[0]); 109 - 110 - if (cpu_has_feature(CPU_FTR_ARCH_31)) { 111 - mtspr(SPRN_MMCR3, vcpu->arch.mmcr[3]); 112 - mtspr(SPRN_SIER2, vcpu->arch.sier[1]); 113 - mtspr(SPRN_SIER3, vcpu->arch.sier[2]); 114 - } 115 - 116 - /* Set MMCRA then MMCR0 last */ 117 - mtspr(SPRN_MMCRA, vcpu->arch.mmcra); 118 - mtspr(SPRN_MMCR0, vcpu->arch.mmcr[0]); 119 - /* No isync necessary because we're starting counters */ 120 - 121 - if (!vcpu->arch.nested && 122 - (vcpu->arch.hfscr_permitted & HFSCR_PM)) 123 - vcpu->arch.hfscr |= HFSCR_PM; 124 - } 125 - } 126 - EXPORT_SYMBOL_GPL(switch_pmu_to_guest); 127 - 128 - void switch_pmu_to_host(struct kvm_vcpu *vcpu, 129 - struct p9_host_os_sprs *host_os_sprs) 130 - { 131 - struct lppaca *lp; 132 - int save_pmu = 1; 133 - 134 - lp = vcpu->arch.vpa.pinned_addr; 135 - if (lp) 136 - save_pmu = lp->pmcregs_in_use; 137 - if (IS_ENABLED(CONFIG_KVM_BOOK3S_HV_NESTED_PMU_WORKAROUND)) { 138 - /* 139 - * Save pmu if this guest is capable of running nested guests. 140 - * This is option is for old L1s that do not set their 141 - * lppaca->pmcregs_in_use properly when entering their L2. 142 - */ 143 - save_pmu |= nesting_enabled(vcpu->kvm); 144 - } 145 - 146 - if (save_pmu) { 147 - vcpu->arch.mmcr[0] = mfspr(SPRN_MMCR0); 148 - vcpu->arch.mmcra = mfspr(SPRN_MMCRA); 149 - 150 - freeze_pmu(vcpu->arch.mmcr[0], vcpu->arch.mmcra); 151 - 152 - vcpu->arch.pmc[0] = mfspr(SPRN_PMC1); 153 - vcpu->arch.pmc[1] = mfspr(SPRN_PMC2); 154 - vcpu->arch.pmc[2] = mfspr(SPRN_PMC3); 155 - vcpu->arch.pmc[3] = mfspr(SPRN_PMC4); 156 - vcpu->arch.pmc[4] = mfspr(SPRN_PMC5); 157 - vcpu->arch.pmc[5] = mfspr(SPRN_PMC6); 158 - vcpu->arch.mmcr[1] = mfspr(SPRN_MMCR1); 159 - vcpu->arch.mmcr[2] = mfspr(SPRN_MMCR2); 160 - vcpu->arch.sdar = mfspr(SPRN_SDAR); 161 - vcpu->arch.siar = mfspr(SPRN_SIAR); 162 - vcpu->arch.sier[0] = mfspr(SPRN_SIER); 163 - 164 - if (cpu_has_feature(CPU_FTR_ARCH_31)) { 165 - vcpu->arch.mmcr[3] = mfspr(SPRN_MMCR3); 166 - vcpu->arch.sier[1] = mfspr(SPRN_SIER2); 167 - vcpu->arch.sier[2] = mfspr(SPRN_SIER3); 168 - } 169 - 170 - } else if (vcpu->arch.hfscr & HFSCR_PM) { 171 - /* 172 - * The guest accessed PMC SPRs without specifying they should 173 - * be preserved, or it cleared pmcregs_in_use after the last 174 - * access. Just ensure they are frozen. 175 - */ 176 - freeze_pmu(mfspr(SPRN_MMCR0), mfspr(SPRN_MMCRA)); 177 - 178 - /* 179 - * Demand-fault PMU register access in the guest. 180 - * 181 - * This is used to grab the guest's VPA pmcregs_in_use value 182 - * and reflect it into the host's VPA in the case of a nested 183 - * hypervisor. 184 - * 185 - * It also avoids having to zero-out SPRs after each guest 186 - * exit to avoid side-channels when. 187 - * 188 - * This is cleared here when we exit the guest, so later HFSCR 189 - * interrupt handling can add it back to run the guest with 190 - * PM enabled next time. 191 - */ 192 - if (!vcpu->arch.nested) 193 - vcpu->arch.hfscr &= ~HFSCR_PM; 194 - } /* otherwise the PMU should still be frozen */ 195 - 196 - #ifdef CONFIG_PPC_PSERIES 197 - if (kvmhv_on_pseries()) { 198 - barrier(); 199 - get_lppaca()->pmcregs_in_use = ppc_get_pmu_inuse(); 200 - barrier(); 201 - } 202 - #endif 203 - 204 - if (ppc_get_pmu_inuse()) { 205 - mtspr(SPRN_PMC1, host_os_sprs->pmc1); 206 - mtspr(SPRN_PMC2, host_os_sprs->pmc2); 207 - mtspr(SPRN_PMC3, host_os_sprs->pmc3); 208 - mtspr(SPRN_PMC4, host_os_sprs->pmc4); 209 - mtspr(SPRN_PMC5, host_os_sprs->pmc5); 210 - mtspr(SPRN_PMC6, host_os_sprs->pmc6); 211 - mtspr(SPRN_MMCR1, host_os_sprs->mmcr1); 212 - mtspr(SPRN_MMCR2, host_os_sprs->mmcr2); 213 - mtspr(SPRN_SDAR, host_os_sprs->sdar); 214 - mtspr(SPRN_SIAR, host_os_sprs->siar); 215 - mtspr(SPRN_SIER, host_os_sprs->sier1); 216 - 217 - if (cpu_has_feature(CPU_FTR_ARCH_31)) { 218 - mtspr(SPRN_MMCR3, host_os_sprs->mmcr3); 219 - mtspr(SPRN_SIER2, host_os_sprs->sier2); 220 - mtspr(SPRN_SIER3, host_os_sprs->sier3); 221 - } 222 - 223 - /* Set MMCRA then MMCR0 last */ 224 - mtspr(SPRN_MMCRA, host_os_sprs->mmcra); 225 - mtspr(SPRN_MMCR0, host_os_sprs->mmcr0); 226 - isync(); 227 - } 228 - } 229 - EXPORT_SYMBOL_GPL(switch_pmu_to_host); 230 9 231 10 static void load_spr_state(struct kvm_vcpu *vcpu, 232 11 struct p9_host_os_sprs *host_os_sprs) ··· 216 437 } 217 438 EXPORT_SYMBOL_GPL(restore_p9_host_os_sprs); 218 439 219 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 220 - static void __start_timing(struct kvm_vcpu *vcpu, struct kvmhv_tb_accumulator *next) 221 - { 222 - struct kvmppc_vcore *vc = vcpu->arch.vcore; 223 - u64 tb = mftb() - vc->tb_offset_applied; 224 - 225 - vcpu->arch.cur_activity = next; 226 - vcpu->arch.cur_tb_start = tb; 227 - } 228 - 229 - static void __accumulate_time(struct kvm_vcpu *vcpu, struct kvmhv_tb_accumulator *next) 440 + #ifdef CONFIG_KVM_BOOK3S_HV_P9_TIMING 441 + void accumulate_time(struct kvm_vcpu *vcpu, struct kvmhv_tb_accumulator *next) 230 442 { 231 443 struct kvmppc_vcore *vc = vcpu->arch.vcore; 232 444 struct kvmhv_tb_accumulator *curr; ··· 247 477 smp_wmb(); 248 478 curr->seqcount = seq + 2; 249 479 } 250 - 251 - #define start_timing(vcpu, next) __start_timing(vcpu, next) 252 - #define end_timing(vcpu) __start_timing(vcpu, NULL) 253 - #define accumulate_time(vcpu, next) __accumulate_time(vcpu, next) 254 - #else 255 - #define start_timing(vcpu, next) do {} while (0) 256 - #define end_timing(vcpu) do {} while (0) 257 - #define accumulate_time(vcpu, next) do {} while (0) 480 + EXPORT_SYMBOL_GPL(accumulate_time); 258 481 #endif 259 482 260 483 static inline u64 mfslbv(unsigned int idx) ··· 558 795 WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_HV); 559 796 WARN_ON_ONCE(!(vcpu->arch.shregs.msr & MSR_ME)); 560 797 561 - start_timing(vcpu, &vcpu->arch.rm_entry); 562 - 563 798 vcpu->arch.ceded = 0; 564 799 565 800 /* Save MSR for restore, with EE clear. */ ··· 718 957 mtspr(SPRN_SRR0, vcpu->arch.shregs.srr0); 719 958 mtspr(SPRN_SRR1, vcpu->arch.shregs.srr1); 720 959 721 - accumulate_time(vcpu, &vcpu->arch.guest_time); 722 - 723 960 switch_pmu_to_guest(vcpu, &host_os_sprs); 724 - kvmppc_p9_enter_guest(vcpu); 725 - switch_pmu_to_host(vcpu, &host_os_sprs); 961 + accumulate_time(vcpu, &vcpu->arch.in_guest); 726 962 727 - accumulate_time(vcpu, &vcpu->arch.rm_intr); 963 + kvmppc_p9_enter_guest(vcpu); 964 + 965 + accumulate_time(vcpu, &vcpu->arch.guest_exit); 966 + switch_pmu_to_host(vcpu, &host_os_sprs); 728 967 729 968 /* XXX: Could get these from r11/12 and paca exsave instead */ 730 969 vcpu->arch.shregs.srr0 = mfspr(SPRN_SRR0); ··· 818 1057 } 819 1058 #endif 820 1059 } 821 - 822 - accumulate_time(vcpu, &vcpu->arch.rm_exit); 823 1060 824 1061 /* Advance host PURR/SPURR by the amount used by guest */ 825 1062 purr = mfspr(SPRN_PURR); ··· 925 1166 asm volatile(PPC_CP_ABORT); 926 1167 927 1168 out: 928 - end_timing(vcpu); 929 - 930 1169 return trap; 931 1170 } 932 1171 EXPORT_SYMBOL_GPL(kvmhv_vcpu_entry_p9);
+219
arch/powerpc/kvm/book3s_hv_p9_perf.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #include <asm/kvm_ppc.h> 4 + #include <asm/pmc.h> 5 + 6 + #include "book3s_hv.h" 7 + 8 + static void freeze_pmu(unsigned long mmcr0, unsigned long mmcra) 9 + { 10 + if (!(mmcr0 & MMCR0_FC)) 11 + goto do_freeze; 12 + if (mmcra & MMCRA_SAMPLE_ENABLE) 13 + goto do_freeze; 14 + if (cpu_has_feature(CPU_FTR_ARCH_31)) { 15 + if (!(mmcr0 & MMCR0_PMCCEXT)) 16 + goto do_freeze; 17 + if (!(mmcra & MMCRA_BHRB_DISABLE)) 18 + goto do_freeze; 19 + } 20 + return; 21 + 22 + do_freeze: 23 + mmcr0 = MMCR0_FC; 24 + mmcra = 0; 25 + if (cpu_has_feature(CPU_FTR_ARCH_31)) { 26 + mmcr0 |= MMCR0_PMCCEXT; 27 + mmcra = MMCRA_BHRB_DISABLE; 28 + } 29 + 30 + mtspr(SPRN_MMCR0, mmcr0); 31 + mtspr(SPRN_MMCRA, mmcra); 32 + isync(); 33 + } 34 + 35 + void switch_pmu_to_guest(struct kvm_vcpu *vcpu, 36 + struct p9_host_os_sprs *host_os_sprs) 37 + { 38 + struct lppaca *lp; 39 + int load_pmu = 1; 40 + 41 + lp = vcpu->arch.vpa.pinned_addr; 42 + if (lp) 43 + load_pmu = lp->pmcregs_in_use; 44 + 45 + /* Save host */ 46 + if (ppc_get_pmu_inuse()) { 47 + /* POWER9, POWER10 do not implement HPMC or SPMC */ 48 + 49 + host_os_sprs->mmcr0 = mfspr(SPRN_MMCR0); 50 + host_os_sprs->mmcra = mfspr(SPRN_MMCRA); 51 + 52 + freeze_pmu(host_os_sprs->mmcr0, host_os_sprs->mmcra); 53 + 54 + host_os_sprs->pmc1 = mfspr(SPRN_PMC1); 55 + host_os_sprs->pmc2 = mfspr(SPRN_PMC2); 56 + host_os_sprs->pmc3 = mfspr(SPRN_PMC3); 57 + host_os_sprs->pmc4 = mfspr(SPRN_PMC4); 58 + host_os_sprs->pmc5 = mfspr(SPRN_PMC5); 59 + host_os_sprs->pmc6 = mfspr(SPRN_PMC6); 60 + host_os_sprs->mmcr1 = mfspr(SPRN_MMCR1); 61 + host_os_sprs->mmcr2 = mfspr(SPRN_MMCR2); 62 + host_os_sprs->sdar = mfspr(SPRN_SDAR); 63 + host_os_sprs->siar = mfspr(SPRN_SIAR); 64 + host_os_sprs->sier1 = mfspr(SPRN_SIER); 65 + 66 + if (cpu_has_feature(CPU_FTR_ARCH_31)) { 67 + host_os_sprs->mmcr3 = mfspr(SPRN_MMCR3); 68 + host_os_sprs->sier2 = mfspr(SPRN_SIER2); 69 + host_os_sprs->sier3 = mfspr(SPRN_SIER3); 70 + } 71 + } 72 + 73 + #ifdef CONFIG_PPC_PSERIES 74 + /* After saving PMU, before loading guest PMU, flip pmcregs_in_use */ 75 + if (kvmhv_on_pseries()) { 76 + barrier(); 77 + get_lppaca()->pmcregs_in_use = load_pmu; 78 + barrier(); 79 + } 80 + #endif 81 + 82 + /* 83 + * Load guest. If the VPA said the PMCs are not in use but the guest 84 + * tried to access them anyway, HFSCR[PM] will be set by the HFAC 85 + * fault so we can make forward progress. 86 + */ 87 + if (load_pmu || (vcpu->arch.hfscr & HFSCR_PM)) { 88 + mtspr(SPRN_PMC1, vcpu->arch.pmc[0]); 89 + mtspr(SPRN_PMC2, vcpu->arch.pmc[1]); 90 + mtspr(SPRN_PMC3, vcpu->arch.pmc[2]); 91 + mtspr(SPRN_PMC4, vcpu->arch.pmc[3]); 92 + mtspr(SPRN_PMC5, vcpu->arch.pmc[4]); 93 + mtspr(SPRN_PMC6, vcpu->arch.pmc[5]); 94 + mtspr(SPRN_MMCR1, vcpu->arch.mmcr[1]); 95 + mtspr(SPRN_MMCR2, vcpu->arch.mmcr[2]); 96 + mtspr(SPRN_SDAR, vcpu->arch.sdar); 97 + mtspr(SPRN_SIAR, vcpu->arch.siar); 98 + mtspr(SPRN_SIER, vcpu->arch.sier[0]); 99 + 100 + if (cpu_has_feature(CPU_FTR_ARCH_31)) { 101 + mtspr(SPRN_MMCR3, vcpu->arch.mmcr[3]); 102 + mtspr(SPRN_SIER2, vcpu->arch.sier[1]); 103 + mtspr(SPRN_SIER3, vcpu->arch.sier[2]); 104 + } 105 + 106 + /* Set MMCRA then MMCR0 last */ 107 + mtspr(SPRN_MMCRA, vcpu->arch.mmcra); 108 + mtspr(SPRN_MMCR0, vcpu->arch.mmcr[0]); 109 + /* No isync necessary because we're starting counters */ 110 + 111 + if (!vcpu->arch.nested && 112 + (vcpu->arch.hfscr_permitted & HFSCR_PM)) 113 + vcpu->arch.hfscr |= HFSCR_PM; 114 + } 115 + } 116 + EXPORT_SYMBOL_GPL(switch_pmu_to_guest); 117 + 118 + void switch_pmu_to_host(struct kvm_vcpu *vcpu, 119 + struct p9_host_os_sprs *host_os_sprs) 120 + { 121 + struct lppaca *lp; 122 + int save_pmu = 1; 123 + 124 + lp = vcpu->arch.vpa.pinned_addr; 125 + if (lp) 126 + save_pmu = lp->pmcregs_in_use; 127 + if (IS_ENABLED(CONFIG_KVM_BOOK3S_HV_NESTED_PMU_WORKAROUND)) { 128 + /* 129 + * Save pmu if this guest is capable of running nested guests. 130 + * This is option is for old L1s that do not set their 131 + * lppaca->pmcregs_in_use properly when entering their L2. 132 + */ 133 + save_pmu |= nesting_enabled(vcpu->kvm); 134 + } 135 + 136 + if (save_pmu) { 137 + vcpu->arch.mmcr[0] = mfspr(SPRN_MMCR0); 138 + vcpu->arch.mmcra = mfspr(SPRN_MMCRA); 139 + 140 + freeze_pmu(vcpu->arch.mmcr[0], vcpu->arch.mmcra); 141 + 142 + vcpu->arch.pmc[0] = mfspr(SPRN_PMC1); 143 + vcpu->arch.pmc[1] = mfspr(SPRN_PMC2); 144 + vcpu->arch.pmc[2] = mfspr(SPRN_PMC3); 145 + vcpu->arch.pmc[3] = mfspr(SPRN_PMC4); 146 + vcpu->arch.pmc[4] = mfspr(SPRN_PMC5); 147 + vcpu->arch.pmc[5] = mfspr(SPRN_PMC6); 148 + vcpu->arch.mmcr[1] = mfspr(SPRN_MMCR1); 149 + vcpu->arch.mmcr[2] = mfspr(SPRN_MMCR2); 150 + vcpu->arch.sdar = mfspr(SPRN_SDAR); 151 + vcpu->arch.siar = mfspr(SPRN_SIAR); 152 + vcpu->arch.sier[0] = mfspr(SPRN_SIER); 153 + 154 + if (cpu_has_feature(CPU_FTR_ARCH_31)) { 155 + vcpu->arch.mmcr[3] = mfspr(SPRN_MMCR3); 156 + vcpu->arch.sier[1] = mfspr(SPRN_SIER2); 157 + vcpu->arch.sier[2] = mfspr(SPRN_SIER3); 158 + } 159 + 160 + } else if (vcpu->arch.hfscr & HFSCR_PM) { 161 + /* 162 + * The guest accessed PMC SPRs without specifying they should 163 + * be preserved, or it cleared pmcregs_in_use after the last 164 + * access. Just ensure they are frozen. 165 + */ 166 + freeze_pmu(mfspr(SPRN_MMCR0), mfspr(SPRN_MMCRA)); 167 + 168 + /* 169 + * Demand-fault PMU register access in the guest. 170 + * 171 + * This is used to grab the guest's VPA pmcregs_in_use value 172 + * and reflect it into the host's VPA in the case of a nested 173 + * hypervisor. 174 + * 175 + * It also avoids having to zero-out SPRs after each guest 176 + * exit to avoid side-channels when. 177 + * 178 + * This is cleared here when we exit the guest, so later HFSCR 179 + * interrupt handling can add it back to run the guest with 180 + * PM enabled next time. 181 + */ 182 + if (!vcpu->arch.nested) 183 + vcpu->arch.hfscr &= ~HFSCR_PM; 184 + } /* otherwise the PMU should still be frozen */ 185 + 186 + #ifdef CONFIG_PPC_PSERIES 187 + if (kvmhv_on_pseries()) { 188 + barrier(); 189 + get_lppaca()->pmcregs_in_use = ppc_get_pmu_inuse(); 190 + barrier(); 191 + } 192 + #endif 193 + 194 + if (ppc_get_pmu_inuse()) { 195 + mtspr(SPRN_PMC1, host_os_sprs->pmc1); 196 + mtspr(SPRN_PMC2, host_os_sprs->pmc2); 197 + mtspr(SPRN_PMC3, host_os_sprs->pmc3); 198 + mtspr(SPRN_PMC4, host_os_sprs->pmc4); 199 + mtspr(SPRN_PMC5, host_os_sprs->pmc5); 200 + mtspr(SPRN_PMC6, host_os_sprs->pmc6); 201 + mtspr(SPRN_MMCR1, host_os_sprs->mmcr1); 202 + mtspr(SPRN_MMCR2, host_os_sprs->mmcr2); 203 + mtspr(SPRN_SDAR, host_os_sprs->sdar); 204 + mtspr(SPRN_SIAR, host_os_sprs->siar); 205 + mtspr(SPRN_SIER, host_os_sprs->sier1); 206 + 207 + if (cpu_has_feature(CPU_FTR_ARCH_31)) { 208 + mtspr(SPRN_MMCR3, host_os_sprs->mmcr3); 209 + mtspr(SPRN_SIER2, host_os_sprs->sier2); 210 + mtspr(SPRN_SIER3, host_os_sprs->sier3); 211 + } 212 + 213 + /* Set MMCRA then MMCR0 last */ 214 + mtspr(SPRN_MMCRA, host_os_sprs->mmcra); 215 + mtspr(SPRN_MMCR0, host_os_sprs->mmcr0); 216 + isync(); 217 + } 218 + } 219 + EXPORT_SYMBOL_GPL(switch_pmu_to_host);
+12 -12
arch/powerpc/kvm/book3s_hv_rmhandlers.S
··· 237 237 cmpdi r4, 0 238 238 beq kvmppc_primary_no_guest 239 239 240 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 240 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 241 241 addi r3, r4, VCPU_TB_RMENTRY 242 242 bl kvmhv_start_timing 243 243 #endif 244 244 b kvmppc_got_guest 245 245 246 246 kvm_novcpu_exit: 247 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 247 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 248 248 ld r4, HSTATE_KVM_VCPU(r13) 249 249 cmpdi r4, 0 250 250 beq 13f ··· 523 523 li r6, KVM_GUEST_MODE_HOST_HV 524 524 stb r6, HSTATE_IN_GUEST(r13) 525 525 526 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 526 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 527 527 /* Store initial timestamp */ 528 528 cmpdi r4, 0 529 529 beq 1f ··· 894 894 li r9, KVM_GUEST_MODE_GUEST_HV 895 895 stb r9, HSTATE_IN_GUEST(r13) 896 896 897 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 897 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 898 898 /* Accumulate timing */ 899 899 addi r3, r4, VCPU_TB_GUEST 900 900 bl kvmhv_accumulate_time ··· 945 945 cmpdi r4, 0 946 946 beq 11f 947 947 stw r12, VCPU_TRAP(r4) 948 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 948 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 949 949 addi r3, r4, VCPU_TB_RMEXIT 950 950 bl kvmhv_accumulate_time 951 951 #endif ··· 959 959 li r12, BOOK3S_INTERRUPT_HV_DECREMENTER 960 960 12: stw r12, VCPU_TRAP(r4) 961 961 mr r9, r4 962 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 962 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 963 963 addi r3, r4, VCPU_TB_RMEXIT 964 964 bl kvmhv_accumulate_time 965 965 #endif ··· 1056 1056 li r0, MSR_RI 1057 1057 mtmsrd r0, 1 1058 1058 1059 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 1059 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 1060 1060 addi r3, r9, VCPU_TB_RMINTR 1061 1061 mr r4, r9 1062 1062 bl kvmhv_accumulate_time ··· 1135 1135 1136 1136 guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */ 1137 1137 1138 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 1138 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 1139 1139 addi r3, r9, VCPU_TB_RMEXIT 1140 1140 mr r4, r9 1141 1141 bl kvmhv_accumulate_time ··· 1495 1495 mtspr SPRN_LPCR,r8 1496 1496 isync 1497 1497 1498 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 1498 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 1499 1499 /* Finish timing, if we have a vcpu */ 1500 1500 ld r4, HSTATE_KVM_VCPU(r13) 1501 1501 cmpdi r4, 0 ··· 2153 2153 ld r4, HSTATE_KVM_VCPU(r13) 2154 2154 std r3, VCPU_DEC_EXPIRES(r4) 2155 2155 2156 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 2156 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 2157 2157 ld r4, HSTATE_KVM_VCPU(r13) 2158 2158 addi r3, r4, VCPU_TB_CEDE 2159 2159 bl kvmhv_accumulate_time ··· 2221 2221 /* get vcpu pointer */ 2222 2222 ld r4, HSTATE_KVM_VCPU(r13) 2223 2223 2224 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 2224 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 2225 2225 addi r3, r4, VCPU_TB_RMINTR 2226 2226 bl kvmhv_accumulate_time 2227 2227 #endif ··· 2961 2961 isync 2962 2962 blr 2963 2963 2964 - #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING 2964 + #ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING 2965 2965 /* 2966 2966 * Start timing an activity 2967 2967 * r3 = pointer to time accumulation struct, r4 = vcpu
+1
arch/powerpc/kvm/book3s_xics.h
··· 143 143 } 144 144 145 145 extern unsigned long xics_rm_h_xirr(struct kvm_vcpu *vcpu); 146 + extern unsigned long xics_rm_h_xirr_x(struct kvm_vcpu *vcpu); 146 147 extern int xics_rm_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, 147 148 unsigned long mfrr); 148 149 extern int xics_rm_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr);
+1
arch/powerpc/kvm/powerpc.c
··· 33 33 #include <asm/plpar_wrappers.h> 34 34 #endif 35 35 #include <asm/ultravisor.h> 36 + #include <asm/setup.h> 36 37 37 38 #include "timing.h" 38 39 #include "irq.h"
+20 -1
arch/powerpc/kvm/trace_hv.h
··· 94 94 {H_GET_HCA_INFO, "H_GET_HCA_INFO"}, \ 95 95 {H_GET_PERF_COUNT, "H_GET_PERF_COUNT"}, \ 96 96 {H_MANAGE_TRACE, "H_MANAGE_TRACE"}, \ 97 + {H_GET_CPU_CHARACTERISTICS, "H_GET_CPU_CHARACTERISTICS"}, \ 97 98 {H_FREE_LOGICAL_LAN_BUFFER, "H_FREE_LOGICAL_LAN_BUFFER"}, \ 98 99 {H_QUERY_INT_STATE, "H_QUERY_INT_STATE"}, \ 99 100 {H_POLL_PENDING, "H_POLL_PENDING"}, \ ··· 126 125 {H_COP, "H_COP"}, \ 127 126 {H_GET_MPP_X, "H_GET_MPP_X"}, \ 128 127 {H_SET_MODE, "H_SET_MODE"}, \ 129 - {H_RTAS, "H_RTAS"} 128 + {H_REGISTER_PROC_TBL, "H_REGISTER_PROC_TBL"}, \ 129 + {H_QUERY_VAS_CAPABILITIES, "H_QUERY_VAS_CAPABILITIES"}, \ 130 + {H_INT_GET_SOURCE_INFO, "H_INT_GET_SOURCE_INFO"}, \ 131 + {H_INT_SET_SOURCE_CONFIG, "H_INT_SET_SOURCE_CONFIG"}, \ 132 + {H_INT_GET_QUEUE_INFO, "H_INT_GET_QUEUE_INFO"}, \ 133 + {H_INT_SET_QUEUE_CONFIG, "H_INT_SET_QUEUE_CONFIG"}, \ 134 + {H_INT_ESB, "H_INT_ESB"}, \ 135 + {H_INT_RESET, "H_INT_RESET"}, \ 136 + {H_RPT_INVALIDATE, "H_RPT_INVALIDATE"}, \ 137 + {H_RTAS, "H_RTAS"}, \ 138 + {H_LOGICAL_MEMOP, "H_LOGICAL_MEMOP"}, \ 139 + {H_CAS, "H_CAS"}, \ 140 + {H_UPDATE_DT, "H_UPDATE_DT"}, \ 141 + {H_GET_PERF_COUNTER_INFO, "H_GET_PERF_COUNTER_INFO"}, \ 142 + {H_SET_PARTITION_TABLE, "H_SET_PARTITION_TABLE"}, \ 143 + {H_ENTER_NESTED, "H_ENTER_NESTED"}, \ 144 + {H_TLB_INVALIDATE, "H_TLB_INVALIDATE"}, \ 145 + {H_COPY_TOFROM_GUEST, "H_COPY_TOFROM_GUEST"} 146 + 130 147 131 148 #define kvm_trace_symbol_kvmret \ 132 149 {RESUME_GUEST, "RESUME_GUEST"}, \
+6 -9
arch/powerpc/lib/test_emulate_step.c
··· 53 53 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \ 54 54 PPC_RAW_ADDI(t, a, i)) 55 55 56 - #define TEST_SETB(t, bfa) ppc_inst(PPC_INST_SETB | ___PPC_RT(t) | ___PPC_RA((bfa & 0x7) << 2)) 57 - 58 - 59 56 static void __init init_pt_regs(struct pt_regs *regs) 60 57 { 61 58 static unsigned long msr; ··· 932 935 .subtests = { 933 936 { 934 937 .descr = "BFA = 1, CR = GT", 935 - .instr = TEST_SETB(20, 1), 938 + .instr = ppc_inst(PPC_RAW_SETB(20, 1)), 936 939 .regs = { 937 940 .ccr = 0x4000000, 938 941 } 939 942 }, 940 943 { 941 944 .descr = "BFA = 4, CR = LT", 942 - .instr = TEST_SETB(20, 4), 945 + .instr = ppc_inst(PPC_RAW_SETB(20, 4)), 943 946 .regs = { 944 947 .ccr = 0x8000, 945 948 } 946 949 }, 947 950 { 948 951 .descr = "BFA = 5, CR = EQ", 949 - .instr = TEST_SETB(20, 5), 952 + .instr = ppc_inst(PPC_RAW_SETB(20, 5)), 950 953 .regs = { 951 954 .ccr = 0x200, 952 955 } ··· 1613 1616 if (analysed != 1 || GETTYPE(op.type) != COMPUTE) { 1614 1617 if (negative) 1615 1618 return -EFAULT; 1616 - pr_info("emulation failed, instruction = %s\n", ppc_inst_as_str(instr)); 1619 + pr_info("emulation failed, instruction = %08lx\n", ppc_inst_as_ulong(instr)); 1617 1620 return -EFAULT; 1618 1621 } 1619 1622 if (analysed == 1 && negative) 1620 - pr_info("negative test failed, instruction = %s\n", ppc_inst_as_str(instr)); 1623 + pr_info("negative test failed, instruction = %08lx\n", ppc_inst_as_ulong(instr)); 1621 1624 if (!negative) 1622 1625 emulate_update_regs(regs, &op); 1623 1626 return 0; ··· 1634 1637 /* Patch the NOP with the actual instruction */ 1635 1638 patch_instruction_site(&patch__exec_instr, instr); 1636 1639 if (exec_instr(regs)) { 1637 - pr_info("execution failed, instruction = %s\n", ppc_inst_as_str(instr)); 1640 + pr_info("execution failed, instruction = %08lx\n", ppc_inst_as_ulong(instr)); 1638 1641 return -EFAULT; 1639 1642 } 1640 1643
+5 -7
arch/powerpc/mm/book3s32/mmu.c
··· 159 159 { 160 160 unsigned long done; 161 161 unsigned long border = (unsigned long)__init_begin - PAGE_OFFSET; 162 + unsigned long size; 162 163 164 + size = roundup_pow_of_two((unsigned long)_einittext - PAGE_OFFSET); 165 + setibat(0, PAGE_OFFSET, 0, size, PAGE_KERNEL_X); 163 166 164 - if (debug_pagealloc_enabled_or_kfence() || __map_without_bats) { 167 + if (debug_pagealloc_enabled_or_kfence()) { 165 168 pr_debug_once("Read-Write memory mapped without BATs\n"); 166 169 if (base >= border) 167 170 return base; ··· 248 245 } 249 246 250 247 /* 251 - * Set up one of the I/D BAT (block address translation) register pairs. 248 + * Set up one of the D BAT (block address translation) register pairs. 252 249 * The parameters are not checked; in particular size must be a power 253 250 * of 2 between 128k and 256M. 254 - * On 603+, only set IBAT when _PAGE_EXEC is set 255 251 */ 256 252 void __init setbat(int index, unsigned long virt, phys_addr_t phys, 257 253 unsigned int size, pgprot_t prot) ··· 286 284 /* G bit must be zero in IBATs */ 287 285 flags &= ~_PAGE_EXEC; 288 286 } 289 - if (flags & _PAGE_EXEC) 290 - bat[0] = bat[1]; 291 - else 292 - bat[0].batu = bat[0].batl = 0; 293 287 294 288 bat_addrs[index].start = virt; 295 289 bat_addrs[index].limit = virt + ((bl + 1) << 17) - 1;
+1
arch/powerpc/mm/book3s64/hash_pgtable.c
··· 13 13 #include <asm/sections.h> 14 14 #include <asm/mmu.h> 15 15 #include <asm/tlb.h> 16 + #include <asm/firmware.h> 16 17 17 18 #include <mm/mmu_decl.h> 18 19
+1 -1
arch/powerpc/mm/book3s64/hash_utils.c
··· 408 408 ssize); 409 409 if (ret == -1) { 410 410 /* 411 - * Try to to keep bolted entries in primary. 411 + * Try to keep bolted entries in primary. 412 412 * Remove non bolted entries and try insert again 413 413 */ 414 414 ret = mmu_hash_ops.hpte_remove(hpteg);
+1
arch/powerpc/mm/book3s64/pkeys.c
··· 10 10 #include <asm/mmu.h> 11 11 #include <asm/setup.h> 12 12 #include <asm/smp.h> 13 + #include <asm/firmware.h> 13 14 14 15 #include <linux/pkeys.h> 15 16 #include <linux/of_fdt.h>
+6 -4
arch/powerpc/mm/book3s64/radix_hugetlbpage.c
··· 48 48 struct mm_struct *mm = vma->vm_mm; 49 49 50 50 /* 51 - * To avoid NMMU hang while relaxing access we need to flush the tlb before 52 - * we set the new value. 51 + * POWER9 NMMU must flush the TLB after clearing the PTE before 52 + * installing a PTE with more relaxed access permissions, see 53 + * radix__ptep_set_access_flags. 53 54 */ 54 - if (is_pte_rw_upgrade(pte_val(old_pte), pte_val(pte)) && 55 - (atomic_read(&mm->context.copros) > 0)) 55 + if (!cpu_has_feature(CPU_FTR_ARCH_31) && 56 + is_pte_rw_upgrade(pte_val(old_pte), pte_val(pte)) && 57 + atomic_read(&mm->context.copros) > 0) 56 58 radix__flush_hugetlb_page(vma, addr); 57 59 58 60 set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+22 -13
arch/powerpc/mm/book3s64/radix_pgtable.c
··· 1018 1018 1019 1019 unsigned long change = pte_val(entry) ^ pte_val(*ptep); 1020 1020 /* 1021 - * To avoid NMMU hang while relaxing access, we need mark 1022 - * the pte invalid in between. 1021 + * On POWER9, the NMMU is not able to relax PTE access permissions 1022 + * for a translation with a TLB. The PTE must be invalidated, TLB 1023 + * flushed before the new PTE is installed. 1024 + * 1025 + * This only needs to be done for radix, because hash translation does 1026 + * flush when updating the linux pte (and we don't support NMMU 1027 + * accelerators on HPT on POWER9 anyway XXX: do we?). 1028 + * 1029 + * POWER10 (and P9P) NMMU does behave as per ISA. 1023 1030 */ 1024 - if ((change & _PAGE_RW) && atomic_read(&mm->context.copros) > 0) { 1031 + if (!cpu_has_feature(CPU_FTR_ARCH_31) && (change & _PAGE_RW) && 1032 + atomic_read(&mm->context.copros) > 0) { 1025 1033 unsigned long old_pte, new_pte; 1026 1034 1027 1035 old_pte = __radix_pte_update(ptep, _PAGE_PRESENT, _PAGE_INVALID); 1028 - /* 1029 - * new value of pte 1030 - */ 1031 1036 new_pte = old_pte | set; 1032 1037 radix__flush_tlb_page_psize(mm, address, psize); 1033 1038 __radix_pte_update(ptep, _PAGE_INVALID, new_pte); ··· 1040 1035 __radix_pte_update(ptep, 0, set); 1041 1036 /* 1042 1037 * Book3S does not require a TLB flush when relaxing access 1043 - * restrictions when the address space is not attached to a 1044 - * NMMU, because the core MMU will reload the pte after taking 1045 - * an access fault, which is defined by the architecture. 1038 + * restrictions when the address space (modulo the POWER9 nest 1039 + * MMU issue above) because the MMU will reload the PTE after 1040 + * taking an access fault, as defined by the architecture. See 1041 + * "Setting a Reference or Change Bit or Upgrading Access 1042 + * Authority (PTE Subject to Atomic Hardware Updates)" in 1043 + * Power ISA Version 3.1B. 1046 1044 */ 1047 1045 } 1048 1046 /* See ptesync comment in radix__set_pte_at */ ··· 1058 1050 struct mm_struct *mm = vma->vm_mm; 1059 1051 1060 1052 /* 1061 - * To avoid NMMU hang while relaxing access we need to flush the tlb before 1062 - * we set the new value. We need to do this only for radix, because hash 1063 - * translation does flush when updating the linux pte. 1053 + * POWER9 NMMU must flush the TLB after clearing the PTE before 1054 + * installing a PTE with more relaxed access permissions, see 1055 + * radix__ptep_set_access_flags. 1064 1056 */ 1065 - if (is_pte_rw_upgrade(pte_val(old_pte), pte_val(pte)) && 1057 + if (!cpu_has_feature(CPU_FTR_ARCH_31) && 1058 + is_pte_rw_upgrade(pte_val(old_pte), pte_val(pte)) && 1066 1059 (atomic_read(&mm->context.copros) > 0)) 1067 1060 radix__flush_tlb_page(vma, addr); 1068 1061
+11 -3
arch/powerpc/mm/book3s64/radix_tlb.c
··· 755 755 static bool mm_needs_flush_escalation(struct mm_struct *mm) 756 756 { 757 757 /* 758 - * P9 nest MMU has issues with the page walk cache 759 - * caching PTEs and not flushing them properly when 760 - * RIC = 0 for a PID/LPID invalidate 758 + * The P9 nest MMU has issues with the page walk cache caching PTEs 759 + * and not flushing them when RIC = 0 for a PID/LPID invalidate. 760 + * 761 + * This may have been fixed in shipping firmware (by disabling PWC 762 + * or preventing it from caching PTEs), but until that is confirmed, 763 + * this workaround is required - escalate all RIC=0 IS=1/2/3 flushes 764 + * to RIC=2. 765 + * 766 + * POWER10 (and P9P) does not have this problem. 761 767 */ 768 + if (cpu_has_feature(CPU_FTR_ARCH_31)) 769 + return false; 762 770 if (atomic_read(&mm->context.copros) > 0) 763 771 return true; 764 772 return false;
+1
arch/powerpc/mm/hugetlbpage.c
··· 24 24 #include <asm/setup.h> 25 25 #include <asm/hugetlb.h> 26 26 #include <asm/pte-walk.h> 27 + #include <asm/firmware.h> 27 28 28 29 bool hugetlb_disabled = false; 29 30
-37
arch/powerpc/mm/init_32.c
··· 69 69 70 70 void MMU_init(void); 71 71 72 - /* 73 - * this tells the system to map all of ram with the segregs 74 - * (i.e. page tables) instead of the bats. 75 - * -- Cort 76 - */ 77 - int __map_without_bats; 78 - int __map_without_ltlbs; 79 - 80 72 /* max amount of low RAM to map in */ 81 73 unsigned long __max_low_memory = MAX_LOW_MEM; 82 - 83 - /* 84 - * Check for command-line options that affect what MMU_init will do. 85 - */ 86 - static void __init MMU_setup(void) 87 - { 88 - /* Check for nobats option (used in mapin_ram). */ 89 - if (strstr(boot_command_line, "nobats")) { 90 - __map_without_bats = 1; 91 - } 92 - 93 - if (strstr(boot_command_line, "noltlbs")) { 94 - __map_without_ltlbs = 1; 95 - } 96 - if (IS_ENABLED(CONFIG_PPC_8xx)) 97 - return; 98 - 99 - if (IS_ENABLED(CONFIG_KFENCE)) 100 - __map_without_ltlbs = 1; 101 - 102 - if (debug_pagealloc_enabled()) 103 - __map_without_ltlbs = 1; 104 - 105 - if (strict_kernel_rwx_enabled()) 106 - __map_without_ltlbs = 1; 107 - } 108 74 109 75 /* 110 76 * MMU_init sets up the basic memory mappings for the kernel, ··· 81 115 { 82 116 if (ppc_md.progress) 83 117 ppc_md.progress("MMU:enter", 0x111); 84 - 85 - /* parse args from command line */ 86 - MMU_setup(); 87 118 88 119 /* 89 120 * Reserve gigantic pages for hugetlb. This MUST occur before
+1
arch/powerpc/mm/kasan/Makefile
··· 6 6 obj-$(CONFIG_PPC_8xx) += 8xx.o 7 7 obj-$(CONFIG_PPC_BOOK3S_32) += book3s_32.o 8 8 obj-$(CONFIG_PPC_BOOK3S_64) += init_book3s_64.o 9 + obj-$(CONFIG_PPC_BOOK3E_64) += init_book3e_64.o
+1 -1
arch/powerpc/mm/kasan/init_32.c
··· 25 25 int i; 26 26 27 27 for (i = 0; i < PTRS_PER_PTE; i++, ptep++) 28 - __set_pte_at(&init_mm, va, ptep, pfn_pte(PHYS_PFN(pa), prot), 0); 28 + __set_pte_at(&init_mm, va, ptep, pfn_pte(PHYS_PFN(pa), prot), 1); 29 29 } 30 30 31 31 int __init kasan_init_shadow_page_tables(unsigned long k_start, unsigned long k_end)
+133
arch/powerpc/mm/kasan/init_book3e_64.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * KASAN for 64-bit Book3e powerpc 4 + * 5 + * Copyright 2022, Christophe Leroy, CS GROUP France 6 + */ 7 + 8 + #define DISABLE_BRANCH_PROFILING 9 + 10 + #include <linux/kasan.h> 11 + #include <linux/printk.h> 12 + #include <linux/memblock.h> 13 + #include <linux/set_memory.h> 14 + 15 + #include <asm/pgalloc.h> 16 + 17 + static inline bool kasan_pud_table(p4d_t p4d) 18 + { 19 + return p4d_page(p4d) == virt_to_page(lm_alias(kasan_early_shadow_pud)); 20 + } 21 + 22 + static inline bool kasan_pmd_table(pud_t pud) 23 + { 24 + return pud_page(pud) == virt_to_page(lm_alias(kasan_early_shadow_pmd)); 25 + } 26 + 27 + static inline bool kasan_pte_table(pmd_t pmd) 28 + { 29 + return pmd_page(pmd) == virt_to_page(lm_alias(kasan_early_shadow_pte)); 30 + } 31 + 32 + static int __init kasan_map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t prot) 33 + { 34 + pgd_t *pgdp; 35 + p4d_t *p4dp; 36 + pud_t *pudp; 37 + pmd_t *pmdp; 38 + pte_t *ptep; 39 + 40 + pgdp = pgd_offset_k(ea); 41 + p4dp = p4d_offset(pgdp, ea); 42 + if (kasan_pud_table(*p4dp)) { 43 + pudp = memblock_alloc(PUD_TABLE_SIZE, PUD_TABLE_SIZE); 44 + memcpy(pudp, kasan_early_shadow_pud, PUD_TABLE_SIZE); 45 + p4d_populate(&init_mm, p4dp, pudp); 46 + } 47 + pudp = pud_offset(p4dp, ea); 48 + if (kasan_pmd_table(*pudp)) { 49 + pmdp = memblock_alloc(PMD_TABLE_SIZE, PMD_TABLE_SIZE); 50 + memcpy(pmdp, kasan_early_shadow_pmd, PMD_TABLE_SIZE); 51 + pud_populate(&init_mm, pudp, pmdp); 52 + } 53 + pmdp = pmd_offset(pudp, ea); 54 + if (kasan_pte_table(*pmdp)) { 55 + ptep = memblock_alloc(PTE_TABLE_SIZE, PTE_TABLE_SIZE); 56 + memcpy(ptep, kasan_early_shadow_pte, PTE_TABLE_SIZE); 57 + pmd_populate_kernel(&init_mm, pmdp, ptep); 58 + } 59 + ptep = pte_offset_kernel(pmdp, ea); 60 + 61 + __set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, prot), 0); 62 + 63 + return 0; 64 + } 65 + 66 + static void __init kasan_init_phys_region(void *start, void *end) 67 + { 68 + unsigned long k_start, k_end, k_cur; 69 + void *va; 70 + 71 + if (start >= end) 72 + return; 73 + 74 + k_start = ALIGN_DOWN((unsigned long)kasan_mem_to_shadow(start), PAGE_SIZE); 75 + k_end = ALIGN((unsigned long)kasan_mem_to_shadow(end), PAGE_SIZE); 76 + 77 + va = memblock_alloc(k_end - k_start, PAGE_SIZE); 78 + for (k_cur = k_start; k_cur < k_end; k_cur += PAGE_SIZE, va += PAGE_SIZE) 79 + kasan_map_kernel_page(k_cur, __pa(va), PAGE_KERNEL); 80 + } 81 + 82 + void __init kasan_early_init(void) 83 + { 84 + int i; 85 + unsigned long addr; 86 + pgd_t *pgd = pgd_offset_k(KASAN_SHADOW_START); 87 + pte_t zero_pte = pfn_pte(virt_to_pfn(kasan_early_shadow_page), PAGE_KERNEL); 88 + 89 + BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE)); 90 + BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE)); 91 + 92 + for (i = 0; i < PTRS_PER_PTE; i++) 93 + __set_pte_at(&init_mm, (unsigned long)kasan_early_shadow_page, 94 + &kasan_early_shadow_pte[i], zero_pte, 0); 95 + 96 + for (i = 0; i < PTRS_PER_PMD; i++) 97 + pmd_populate_kernel(&init_mm, &kasan_early_shadow_pmd[i], 98 + kasan_early_shadow_pte); 99 + 100 + for (i = 0; i < PTRS_PER_PUD; i++) 101 + pud_populate(&init_mm, &kasan_early_shadow_pud[i], 102 + kasan_early_shadow_pmd); 103 + 104 + for (addr = KASAN_SHADOW_START; addr != KASAN_SHADOW_END; addr += PGDIR_SIZE) 105 + p4d_populate(&init_mm, p4d_offset(pgd++, addr), kasan_early_shadow_pud); 106 + } 107 + 108 + void __init kasan_init(void) 109 + { 110 + phys_addr_t start, end; 111 + u64 i; 112 + pte_t zero_pte = pfn_pte(virt_to_pfn(kasan_early_shadow_page), PAGE_KERNEL_RO); 113 + 114 + for_each_mem_range(i, &start, &end) 115 + kasan_init_phys_region((void *)start, (void *)end); 116 + 117 + if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) 118 + kasan_remove_zero_shadow((void *)VMALLOC_START, VMALLOC_SIZE); 119 + 120 + for (i = 0; i < PTRS_PER_PTE; i++) 121 + __set_pte_at(&init_mm, (unsigned long)kasan_early_shadow_page, 122 + &kasan_early_shadow_pte[i], zero_pte, 0); 123 + 124 + flush_tlb_kernel_range(KASAN_SHADOW_START, KASAN_SHADOW_END); 125 + 126 + memset(kasan_early_shadow_page, 0, PAGE_SIZE); 127 + 128 + /* Enable error messages */ 129 + init_task.kasan_depth = 0; 130 + pr_info("KASAN init done\n"); 131 + } 132 + 133 + void __init kasan_late_init(void) { }
+2
arch/powerpc/mm/kasan/init_book3s_64.c
··· 99 99 pr_info("KASAN init done\n"); 100 100 } 101 101 102 + void __init kasan_early_init(void) { } 103 + 102 104 void __init kasan_late_init(void) { }
+1
arch/powerpc/mm/mem.c
··· 25 25 #include <asm/mmzone.h> 26 26 #include <asm/ftrace.h> 27 27 #include <asm/code-patching.h> 28 + #include <asm/setup.h> 28 29 29 30 #include <mm/mmu_decl.h> 30 31
-1
arch/powerpc/mm/mmu_decl.h
··· 92 92 extern void setbat(int index, unsigned long virt, phys_addr_t phys, 93 93 unsigned int size, pgprot_t prot); 94 94 95 - extern int __map_without_bats; 96 95 extern unsigned int rtas_data, rtas_size; 97 96 98 97 struct hash_pte;
+7 -2
arch/powerpc/mm/nohash/40x.c
··· 43 43 44 44 #include <mm/mmu_decl.h> 45 45 46 - extern int __map_without_ltlbs; 47 46 /* 48 47 * MMU_init_hw does the chip-specific initialization of the MMU hardware. 49 48 */ ··· 93 94 p = 0; 94 95 s = total_lowmem; 95 96 96 - if (__map_without_ltlbs) 97 + if (IS_ENABLED(CONFIG_KFENCE)) 98 + return 0; 99 + 100 + if (debug_pagealloc_enabled()) 101 + return 0; 102 + 103 + if (strict_kernel_rwx_enabled()) 97 104 return 0; 98 105 99 106 while (s >= LARGE_PAGE_SIZE_16M) {
+2 -11
arch/powerpc/mm/nohash/8xx.c
··· 14 14 15 15 #define IMMR_SIZE (FIX_IMMR_SIZE << PAGE_SHIFT) 16 16 17 - extern int __map_without_ltlbs; 18 - 19 17 static unsigned long block_mapped_ram; 20 18 21 19 /* ··· 26 28 27 29 if (va >= VIRT_IMMR_BASE && va < VIRT_IMMR_BASE + IMMR_SIZE) 28 30 return p + va - VIRT_IMMR_BASE; 29 - if (__map_without_ltlbs) 30 - return 0; 31 31 if (va >= PAGE_OFFSET && va < PAGE_OFFSET + block_mapped_ram) 32 32 return __pa(va); 33 33 return 0; ··· 41 45 42 46 if (pa >= p && pa < p + IMMR_SIZE) 43 47 return VIRT_IMMR_BASE + pa - p; 44 - if (__map_without_ltlbs) 45 - return 0; 46 48 if (pa < block_mapped_ram) 47 49 return (unsigned long)__va(pa); 48 50 return 0; ··· 147 153 148 154 mmu_mapin_immr(); 149 155 150 - if (__map_without_ltlbs) 151 - return 0; 152 - 153 156 mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_TEXT, true); 154 157 if (debug_pagealloc_enabled_or_kfence()) { 155 158 top = boundary; ··· 170 179 unsigned long boundary = strict_kernel_rwx_enabled() ? sinittext : etext8; 171 180 unsigned long einittext8 = ALIGN(__pa(_einittext), SZ_8M); 172 181 173 - mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_TEXT, false); 174 - mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL, false); 182 + if (!debug_pagealloc_enabled_or_kfence()) 183 + mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL, false); 175 184 176 185 mmu_pin_tlb(block_mapped_ram, false); 177 186 }
+8 -22
arch/powerpc/mm/nohash/book3e_hugetlbpage.c
··· 103 103 int found = 0; 104 104 105 105 mtspr(SPRN_MAS6, pid << 16); 106 - if (mmu_has_feature(MMU_FTR_USE_TLBRSRV)) { 107 - asm volatile( 108 - "li %0,0\n" 109 - "tlbsx. 0,%1\n" 110 - "bne 1f\n" 111 - "li %0,1\n" 112 - "1:\n" 113 - : "=&r"(found) : "r"(ea)); 114 - } else { 115 - asm volatile( 116 - "tlbsx 0,%1\n" 117 - "mfspr %0,0x271\n" 118 - "srwi %0,%0,31\n" 119 - : "=&r"(found) : "r"(ea)); 120 - } 106 + asm volatile( 107 + "tlbsx 0,%1\n" 108 + "mfspr %0,0x271\n" 109 + "srwi %0,%0,31\n" 110 + : "=&r"(found) : "r"(ea)); 121 111 122 112 return found; 123 113 } ··· 159 169 mtspr(SPRN_MAS1, mas1); 160 170 mtspr(SPRN_MAS2, mas2); 161 171 162 - if (mmu_has_feature(MMU_FTR_USE_PAIRED_MAS)) { 163 - mtspr(SPRN_MAS7_MAS3, mas7_3); 164 - } else { 165 - if (mmu_has_feature(MMU_FTR_BIG_PHYS)) 166 - mtspr(SPRN_MAS7, upper_32_bits(mas7_3)); 167 - mtspr(SPRN_MAS3, lower_32_bits(mas7_3)); 168 - } 172 + if (mmu_has_feature(MMU_FTR_BIG_PHYS)) 173 + mtspr(SPRN_MAS7, upper_32_bits(mas7_3)); 174 + mtspr(SPRN_MAS3, lower_32_bits(mas7_3)); 169 175 170 176 asm volatile ("tlbwe"); 171 177
+2 -2
arch/powerpc/mm/nohash/tlb_low.S
··· 186 186 isync 187 187 PPC_TLBIVAX(0, R3) 188 188 isync 189 - eieio 189 + mbar 190 190 tlbsync 191 191 BEGIN_FTR_SECTION 192 192 b 1f ··· 355 355 rlwimi r4,r6,MAS6_SIND_SHIFT,MAS6_SIND 356 356 1: mtspr SPRN_MAS6,r4 /* assume AS=0 for now */ 357 357 PPC_TLBIVAX(0,R3) 358 - eieio 358 + mbar 359 359 tlbsync 360 360 sync 361 361 wrtee r10
+45 -102
arch/powerpc/mm/nohash/tlb_low_64e.S
··· 152 152 clrrdi r15,r15,3 153 153 beq tlb_miss_fault_bolted /* No PGDIR, bail */ 154 154 155 - BEGIN_MMU_FTR_SECTION 156 - /* Set the TLB reservation and search for existing entry. Then load 157 - * the entry. 158 - */ 159 - PPC_TLBSRX_DOT(0,R16) 160 155 ldx r14,r14,r15 /* grab pgd entry */ 161 - beq tlb_miss_done_bolted /* tlb exists already, bail */ 162 - MMU_FTR_SECTION_ELSE 163 - ldx r14,r14,r15 /* grab pgd entry */ 164 - ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV) 165 156 166 157 rldicl r15,r16,64-PUD_SHIFT+3,64-PUD_INDEX_SIZE-3 167 158 clrrdi r15,r15,3 ··· 213 222 tlb_miss_kernel_bolted: 214 223 mfspr r10,SPRN_MAS1 215 224 ld r14,PACA_KERNELPGD(r13) 216 - cmpldi cr0,r15,8 /* Check for vmalloc region */ 225 + srdi r15,r16,44 /* get kernel region */ 226 + andi. r15,r15,1 /* Check for vmalloc region */ 217 227 rlwinm r10,r10,0,16,1 /* Clear TID */ 218 228 mtspr SPRN_MAS1,r10 219 - beq+ tlb_miss_common_bolted 229 + bne+ tlb_miss_common_bolted 220 230 221 231 tlb_miss_fault_bolted: 222 232 /* We need to check if it was an instruction miss */ ··· 499 507 500 508 tlb_miss_kernel_e6500: 501 509 ld r14,PACA_KERNELPGD(r13) 502 - cmpldi cr1,r15,8 /* Check for vmalloc region */ 510 + srdi r15,r16,44 /* get kernel region */ 511 + xoris r15,r15,0xc /* Check for vmalloc region */ 512 + cmplwi cr1,r15,1 503 513 beq+ cr1,tlb_miss_common_e6500 504 514 505 515 tlb_miss_fault_e6500: ··· 535 541 */ 536 542 mfspr r14,SPRN_ESR 537 543 mfspr r16,SPRN_DEAR /* get faulting address */ 538 - srdi r15,r16,60 /* get region */ 539 - cmpldi cr0,r15,0xc /* linear mapping ? */ 544 + srdi r15,r16,44 /* get region */ 545 + xoris r15,r15,0xc 546 + cmpldi cr0,r15,0 /* linear mapping ? */ 540 547 beq tlb_load_linear /* yes -> go to linear map load */ 548 + cmpldi cr1,r15,1 /* vmalloc mapping ? */ 541 549 542 550 /* The page tables are mapped virtually linear. At this point, though, 543 551 * we don't know whether we are trying to fault in a first level 544 552 * virtual address or a virtual page table address. We can get that 545 553 * from bit 0x1 of the region ID which we have set for a page table 546 554 */ 547 - andi. r10,r15,0x1 555 + andis. r10,r15,0x1 548 556 bne- virt_page_table_tlb_miss 549 557 550 558 std r14,EX_TLB_ESR(r12); /* save ESR */ ··· 558 562 559 563 /* We do the user/kernel test for the PID here along with the RW test 560 564 */ 561 - cmpldi cr0,r15,0 /* Check for user region */ 565 + srdi. r15,r16,60 /* Check for user region */ 562 566 563 567 /* We pre-test some combination of permissions to avoid double 564 568 * faults: ··· 579 583 */ 580 584 rlwimi r11,r14,32-19,27,27 581 585 rlwimi r11,r14,32-16,19,19 582 - beq normal_tlb_miss 586 + beq normal_tlb_miss_user 583 587 /* XXX replace the RMW cycles with immediate loads + writes */ 584 588 1: mfspr r10,SPRN_MAS1 585 - cmpldi cr0,r15,8 /* Check for vmalloc region */ 586 589 rlwinm r10,r10,0,16,1 /* Clear TID */ 587 590 mtspr SPRN_MAS1,r10 588 - beq+ normal_tlb_miss 591 + beq+ cr1,normal_tlb_miss 589 592 590 593 /* We got a crappy address, just fault with whatever DEAR and ESR 591 594 * are here ··· 610 615 * 611 616 * Faulting address is SRR0 which is already in r16 612 617 */ 613 - srdi r15,r16,60 /* get region */ 614 - cmpldi cr0,r15,0xc /* linear mapping ? */ 618 + srdi r15,r16,44 /* get region */ 619 + xoris r15,r15,0xc 620 + cmpldi cr0,r15,0 /* linear mapping ? */ 615 621 beq tlb_load_linear /* yes -> go to linear map load */ 622 + cmpldi cr1,r15,1 /* vmalloc mapping ? */ 616 623 617 624 /* We do the user/kernel test for the PID here along with the RW test 618 625 */ 619 626 li r11,_PAGE_PRESENT|_PAGE_BAP_UX /* Base perm */ 620 627 oris r11,r11,_PAGE_ACCESSED@h 621 628 622 - cmpldi cr0,r15,0 /* Check for user region */ 629 + srdi. r15,r16,60 /* Check for user region */ 623 630 std r14,EX_TLB_ESR(r12) /* write crazy -1 to frame */ 624 - beq normal_tlb_miss 631 + beq normal_tlb_miss_user 625 632 626 633 li r11,_PAGE_PRESENT|_PAGE_BAP_SX /* Base perm */ 627 634 oris r11,r11,_PAGE_ACCESSED@h 628 635 /* XXX replace the RMW cycles with immediate loads + writes */ 629 636 mfspr r10,SPRN_MAS1 630 - cmpldi cr0,r15,8 /* Check for vmalloc region */ 631 637 rlwinm r10,r10,0,16,1 /* Clear TID */ 632 638 mtspr SPRN_MAS1,r10 633 - beq+ normal_tlb_miss 639 + beq+ cr1,normal_tlb_miss 634 640 635 641 /* We got a crappy address, just fault */ 636 642 TLB_MISS_EPILOG_ERROR ··· 649 653 * r11 = PTE permission mask 650 654 * r10 = crap (free to use) 651 655 */ 656 + normal_tlb_miss_user: 657 + #ifdef CONFIG_PPC_KUAP 658 + mfspr r14,SPRN_MAS1 659 + rlwinm. r14,r14,0,0x3fff0000 660 + beq- normal_tlb_miss_access_fault /* KUAP fault */ 661 + #endif 652 662 normal_tlb_miss: 653 663 /* So we first construct the page table address. We do that by 654 664 * shifting the bottom of the address (not the region ID) by ··· 664 662 * NOTE: For 64K pages, we do things slightly differently in 665 663 * order to handle the weird page table format used by linux 666 664 */ 667 - ori r10,r15,0x1 665 + srdi r15,r16,44 666 + oris r10,r15,0x1 668 667 rldicl r14,r16,64-(PAGE_SHIFT-3),PAGE_SHIFT-3+4 669 - sldi r15,r10,60 670 - clrrdi r14,r14,3 668 + sldi r15,r10,44 669 + clrrdi r14,r14,19 671 670 or r10,r15,r14 672 671 673 - BEGIN_MMU_FTR_SECTION 674 - /* Set the TLB reservation and search for existing entry. Then load 675 - * the entry. 676 - */ 677 - PPC_TLBSRX_DOT(0,R16) 678 672 ld r14,0(r10) 679 - beq normal_tlb_miss_done 680 - MMU_FTR_SECTION_ELSE 681 - ld r14,0(r10) 682 - ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV) 683 673 684 674 finish_normal_tlb_miss: 685 675 /* Check if required permissions are met */ 686 676 andc. r15,r11,r14 687 677 bne- normal_tlb_miss_access_fault 688 - #ifdef CONFIG_PPC_KUAP 689 - mfspr r11,SPRN_MAS1 690 - rlwinm. r10,r11,0,0x3fff0000 691 - beq- normal_tlb_miss_access_fault /* KUAP fault */ 692 - #endif 693 678 694 679 /* Now we build the MAS: 695 680 * ··· 698 709 rldicl r10,r14,64-8,64-8 699 710 cmpldi cr0,r10,BOOK3E_PAGESZ_4K 700 711 beq- 1f 701 - #ifndef CONFIG_PPC_KUAP 702 712 mfspr r11,SPRN_MAS1 703 - #endif 704 713 rlwimi r11,r14,31,21,24 705 714 rlwinm r11,r11,0,21,19 706 715 mtspr SPRN_MAS1,r11 ··· 715 728 li r11,MAS3_SW|MAS3_UW 716 729 andc r15,r15,r11 717 730 1: 718 - BEGIN_MMU_FTR_SECTION 719 731 srdi r16,r15,32 720 732 mtspr SPRN_MAS3,r15 721 733 mtspr SPRN_MAS7,r16 722 - MMU_FTR_SECTION_ELSE 723 - mtspr SPRN_MAS7_MAS3,r15 724 - ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS) 725 734 726 735 tlbwe 727 736 ··· 769 786 */ 770 787 virt_page_table_tlb_miss: 771 788 /* Are we hitting a kernel page table ? */ 789 + srdi r15,r16,60 772 790 andi. r10,r15,0x8 773 791 774 792 /* The cool thing now is that r10 contains 0 for user and 8 for kernel, ··· 794 810 #else 795 811 1: 796 812 #endif 797 - BEGIN_MMU_FTR_SECTION 798 - /* Search if we already have a TLB entry for that virtual address, and 799 - * if we do, bail out. 800 - */ 801 - PPC_TLBSRX_DOT(0,R16) 802 - beq virt_page_table_tlb_miss_done 803 - END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV) 804 813 805 814 /* Now, we need to walk the page tables. First check if we are in 806 815 * range. 807 816 */ 808 - rldicl. r10,r16,64-(VPTE_INDEX_SIZE+3),VPTE_INDEX_SIZE+3+4 817 + rldicl r10,r16,64-(VPTE_INDEX_SIZE+3),VPTE_INDEX_SIZE+3+4 818 + cmpldi r10,0x80 809 819 bne- virt_page_table_tlb_miss_fault 810 820 811 821 /* Get the PGD pointer */ ··· 845 867 clrldi r11,r15,4 /* remove region ID from RPN */ 846 868 ori r10,r11,1 /* Or-in SR */ 847 869 848 - BEGIN_MMU_FTR_SECTION 849 870 srdi r16,r10,32 850 871 mtspr SPRN_MAS3,r10 851 872 mtspr SPRN_MAS7,r16 852 - MMU_FTR_SECTION_ELSE 853 - mtspr SPRN_MAS7_MAS3,r10 854 - ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS) 855 873 856 874 tlbwe 857 875 858 - BEGIN_MMU_FTR_SECTION 859 - virt_page_table_tlb_miss_done: 860 - 861 - /* We have overridden MAS2:EPN but currently our primary TLB miss 862 - * handler will always restore it so that should not be an issue, 863 - * if we ever optimize the primary handler to not write MAS2 on 864 - * some cases, we'll have to restore MAS2:EPN here based on the 865 - * original fault's DEAR. If we do that we have to modify the 866 - * ITLB miss handler to also store SRR0 in the exception frame 867 - * as DEAR. 868 - * 869 - * However, one nasty thing we did is we cleared the reservation 870 - * (well, potentially we did). We do a trick here thus if we 871 - * are not a level 0 exception (we interrupted the TLB miss) we 872 - * offset the return address by -4 in order to replay the tlbsrx 873 - * instruction there 874 - */ 875 - subf r10,r13,r12 876 - cmpldi cr0,r10,PACA_EXTLB+EX_TLB_SIZE 877 - bne- 1f 878 - ld r11,PACA_EXTLB+EX_TLB_SIZE+EX_TLB_SRR0(r13) 879 - addi r10,r11,-4 880 - std r10,PACA_EXTLB+EX_TLB_SIZE+EX_TLB_SRR0(r13) 881 - 1: 882 - END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV) 883 876 /* Return to caller, normal case */ 884 877 TLB_MISS_EPILOG_SUCCESS 885 878 rfi ··· 918 969 */ 919 970 mfspr r14,SPRN_ESR 920 971 mfspr r16,SPRN_DEAR /* get faulting address */ 921 - srdi r11,r16,60 /* get region */ 922 - cmpldi cr0,r11,0xc /* linear mapping ? */ 972 + srdi r11,r16,44 /* get region */ 973 + xoris r11,r11,0xc 974 + cmpldi cr0,r11,0 /* linear mapping ? */ 923 975 beq tlb_load_linear /* yes -> go to linear map load */ 976 + cmpldi cr1,r11,1 /* vmalloc mapping ? */ 924 977 925 978 /* We do the user/kernel test for the PID here along with the RW test 926 979 */ 927 - cmpldi cr0,r11,0 /* Check for user region */ 980 + srdi. r11,r16,60 /* Check for user region */ 928 981 ld r15,PACAPGD(r13) /* Load user pgdir */ 929 982 beq htw_tlb_miss 930 983 931 984 /* XXX replace the RMW cycles with immediate loads + writes */ 932 985 1: mfspr r10,SPRN_MAS1 933 - cmpldi cr0,r11,8 /* Check for vmalloc region */ 934 986 rlwinm r10,r10,0,16,1 /* Clear TID */ 935 987 mtspr SPRN_MAS1,r10 936 988 ld r15,PACA_KERNELPGD(r13) /* Load kernel pgdir */ 937 - beq+ htw_tlb_miss 989 + beq+ cr1,htw_tlb_miss 938 990 939 991 /* We got a crappy address, just fault with whatever DEAR and ESR 940 992 * are here ··· 961 1011 * 962 1012 * Faulting address is SRR0 which is already in r16 963 1013 */ 964 - srdi r11,r16,60 /* get region */ 965 - cmpldi cr0,r11,0xc /* linear mapping ? */ 1014 + srdi r11,r16,44 /* get region */ 1015 + xoris r11,r11,0xc 1016 + cmpldi cr0,r11,0 /* linear mapping ? */ 966 1017 beq tlb_load_linear /* yes -> go to linear map load */ 1018 + cmpldi cr1,r11,1 /* vmalloc mapping ? */ 967 1019 968 1020 /* We do the user/kernel test for the PID here along with the RW test 969 1021 */ 970 - cmpldi cr0,r11,0 /* Check for user region */ 1022 + srdi. r11,r16,60 /* Check for user region */ 971 1023 ld r15,PACAPGD(r13) /* Load user pgdir */ 972 1024 beq htw_tlb_miss 973 1025 974 1026 /* XXX replace the RMW cycles with immediate loads + writes */ 975 1027 1: mfspr r10,SPRN_MAS1 976 - cmpldi cr0,r11,8 /* Check for vmalloc region */ 977 1028 rlwinm r10,r10,0,16,1 /* Clear TID */ 978 1029 mtspr SPRN_MAS1,r10 979 1030 ld r15,PACA_KERNELPGD(r13) /* Load kernel pgdir */ ··· 1067 1116 */ 1068 1117 ori r10,r15,(BOOK3E_PAGESZ_4K << MAS3_SPSIZE_SHIFT) 1069 1118 1070 - BEGIN_MMU_FTR_SECTION 1071 1119 srdi r16,r10,32 1072 1120 mtspr SPRN_MAS3,r10 1073 1121 mtspr SPRN_MAS7,r16 1074 - MMU_FTR_SECTION_ELSE 1075 - mtspr SPRN_MAS7_MAS3,r10 1076 - ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS) 1077 1122 1078 1123 tlbwe 1079 1124 ··· 1150 1203 clrldi r10,r10,4 /* clear region bits */ 1151 1204 ori r10,r10,MAS3_SR|MAS3_SW|MAS3_SX 1152 1205 1153 - BEGIN_MMU_FTR_SECTION 1154 1206 srdi r16,r10,32 1155 1207 mtspr SPRN_MAS3,r10 1156 1208 mtspr SPRN_MAS7,r16 1157 - MMU_FTR_SECTION_ELSE 1158 - mtspr SPRN_MAS7_MAS3,r10 1159 - ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS) 1160 1209 1161 1210 tlbwe 1162 1211
+3 -3
arch/powerpc/mm/pgtable_32.c
··· 135 135 unsigned long numpages = PFN_UP((unsigned long)_einittext) - 136 136 PFN_DOWN((unsigned long)_sinittext); 137 137 138 - if (v_block_mapped((unsigned long)_sinittext)) { 139 - mmu_mark_initmem_nx(); 140 - } else { 138 + mmu_mark_initmem_nx(); 139 + 140 + if (!v_block_mapped((unsigned long)_sinittext)) { 141 141 set_memory_nx((unsigned long)_sinittext, numpages); 142 142 set_memory_rw((unsigned long)_sinittext, numpages); 143 143 }
+3 -3
arch/powerpc/mm/ptdump/shared.c
··· 17 17 .clear = " ", 18 18 }, { 19 19 .mask = _PAGE_RW, 20 - .val = _PAGE_RW, 21 - .set = "rw", 22 - .clear = "r ", 20 + .val = 0, 21 + .set = "r ", 22 + .clear = "rw", 23 23 }, { 24 24 .mask = _PAGE_EXEC, 25 25 .val = _PAGE_EXEC,
+60 -12
arch/powerpc/net/bpf_jit_comp32.c
··· 294 294 u32 dst_reg_h = dst_reg - 1; 295 295 u32 src_reg = bpf_to_ppc(insn[i].src_reg); 296 296 u32 src_reg_h = src_reg - 1; 297 + u32 ax_reg = bpf_to_ppc(BPF_REG_AX); 297 298 u32 tmp_reg = bpf_to_ppc(TMP_REG); 298 299 u32 size = BPF_SIZE(code); 300 + u32 save_reg, ret_reg; 299 301 s16 off = insn[i].off; 300 302 s32 imm = insn[i].imm; 301 303 bool func_addr_fixed; ··· 800 798 * BPF_STX ATOMIC (atomic ops) 801 799 */ 802 800 case BPF_STX | BPF_ATOMIC | BPF_W: 803 - if (imm != BPF_ADD) { 804 - pr_err_ratelimited("eBPF filter atomic op code %02x (@%d) unsupported\n", 805 - code, i); 806 - return -ENOTSUPP; 807 - } 808 - 809 - /* *(u32 *)(dst + off) += src */ 801 + save_reg = _R0; 802 + ret_reg = src_reg; 810 803 811 804 bpf_set_seen_register(ctx, tmp_reg); 805 + bpf_set_seen_register(ctx, ax_reg); 806 + 812 807 /* Get offset into TMP_REG */ 813 808 EMIT(PPC_RAW_LI(tmp_reg, off)); 809 + tmp_idx = ctx->idx * 4; 814 810 /* load value from memory into r0 */ 815 811 EMIT(PPC_RAW_LWARX(_R0, tmp_reg, dst_reg, 0)); 816 - /* add value from src_reg into this */ 817 - EMIT(PPC_RAW_ADD(_R0, _R0, src_reg)); 818 - /* store result back */ 819 - EMIT(PPC_RAW_STWCX(_R0, tmp_reg, dst_reg)); 812 + 813 + /* Save old value in BPF_REG_AX */ 814 + if (imm & BPF_FETCH) 815 + EMIT(PPC_RAW_MR(ax_reg, _R0)); 816 + 817 + switch (imm) { 818 + case BPF_ADD: 819 + case BPF_ADD | BPF_FETCH: 820 + EMIT(PPC_RAW_ADD(_R0, _R0, src_reg)); 821 + break; 822 + case BPF_AND: 823 + case BPF_AND | BPF_FETCH: 824 + EMIT(PPC_RAW_AND(_R0, _R0, src_reg)); 825 + break; 826 + case BPF_OR: 827 + case BPF_OR | BPF_FETCH: 828 + EMIT(PPC_RAW_OR(_R0, _R0, src_reg)); 829 + break; 830 + case BPF_XOR: 831 + case BPF_XOR | BPF_FETCH: 832 + EMIT(PPC_RAW_XOR(_R0, _R0, src_reg)); 833 + break; 834 + case BPF_CMPXCHG: 835 + /* 836 + * Return old value in BPF_REG_0 for BPF_CMPXCHG & 837 + * in src_reg for other cases. 838 + */ 839 + ret_reg = bpf_to_ppc(BPF_REG_0); 840 + 841 + /* Compare with old value in BPF_REG_0 */ 842 + EMIT(PPC_RAW_CMPW(bpf_to_ppc(BPF_REG_0), _R0)); 843 + /* Don't set if different from old value */ 844 + PPC_BCC_SHORT(COND_NE, (ctx->idx + 3) * 4); 845 + fallthrough; 846 + case BPF_XCHG: 847 + save_reg = src_reg; 848 + break; 849 + default: 850 + pr_err_ratelimited("eBPF filter atomic op code %02x (@%d) unsupported\n", 851 + code, i); 852 + return -EOPNOTSUPP; 853 + } 854 + 855 + /* store new value */ 856 + EMIT(PPC_RAW_STWCX(save_reg, tmp_reg, dst_reg)); 820 857 /* we're done if this succeeded */ 821 - PPC_BCC_SHORT(COND_NE, (ctx->idx - 3) * 4); 858 + PPC_BCC_SHORT(COND_NE, tmp_idx); 859 + 860 + /* For the BPF_FETCH variant, get old data into src_reg */ 861 + if (imm & BPF_FETCH) { 862 + EMIT(PPC_RAW_MR(ret_reg, ax_reg)); 863 + if (!fp->aux->verifier_zext) 864 + EMIT(PPC_RAW_LI(ret_reg - 1, 0)); /* higher 32-bit */ 865 + } 822 866 break; 823 867 824 868 case BPF_STX | BPF_ATOMIC | BPF_DW: /* *(u64 *)(dst + off) += src */
+69 -27
arch/powerpc/net/bpf_jit_comp64.c
··· 360 360 u32 size = BPF_SIZE(code); 361 361 u32 tmp1_reg = bpf_to_ppc(TMP_REG_1); 362 362 u32 tmp2_reg = bpf_to_ppc(TMP_REG_2); 363 + u32 save_reg, ret_reg; 363 364 s16 off = insn[i].off; 364 365 s32 imm = insn[i].imm; 365 366 bool func_addr_fixed; ··· 778 777 * BPF_STX ATOMIC (atomic ops) 779 778 */ 780 779 case BPF_STX | BPF_ATOMIC | BPF_W: 781 - if (imm != BPF_ADD) { 782 - pr_err_ratelimited( 783 - "eBPF filter atomic op code %02x (@%d) unsupported\n", 784 - code, i); 785 - return -ENOTSUPP; 786 - } 780 + case BPF_STX | BPF_ATOMIC | BPF_DW: 781 + save_reg = tmp2_reg; 782 + ret_reg = src_reg; 787 783 788 - /* *(u32 *)(dst + off) += src */ 789 - 790 - /* Get EA into TMP_REG_1 */ 791 - EMIT(PPC_RAW_ADDI(tmp1_reg, dst_reg, off)); 784 + /* Get offset into TMP_REG_1 */ 785 + EMIT(PPC_RAW_LI(tmp1_reg, off)); 792 786 tmp_idx = ctx->idx * 4; 793 787 /* load value from memory into TMP_REG_2 */ 794 - EMIT(PPC_RAW_LWARX(tmp2_reg, 0, tmp1_reg, 0)); 795 - /* add value from src_reg into this */ 796 - EMIT(PPC_RAW_ADD(tmp2_reg, tmp2_reg, src_reg)); 797 - /* store result back */ 798 - EMIT(PPC_RAW_STWCX(tmp2_reg, 0, tmp1_reg)); 799 - /* we're done if this succeeded */ 800 - PPC_BCC_SHORT(COND_NE, tmp_idx); 801 - break; 802 - case BPF_STX | BPF_ATOMIC | BPF_DW: 803 - if (imm != BPF_ADD) { 788 + if (size == BPF_DW) 789 + EMIT(PPC_RAW_LDARX(tmp2_reg, tmp1_reg, dst_reg, 0)); 790 + else 791 + EMIT(PPC_RAW_LWARX(tmp2_reg, tmp1_reg, dst_reg, 0)); 792 + 793 + /* Save old value in _R0 */ 794 + if (imm & BPF_FETCH) 795 + EMIT(PPC_RAW_MR(_R0, tmp2_reg)); 796 + 797 + switch (imm) { 798 + case BPF_ADD: 799 + case BPF_ADD | BPF_FETCH: 800 + EMIT(PPC_RAW_ADD(tmp2_reg, tmp2_reg, src_reg)); 801 + break; 802 + case BPF_AND: 803 + case BPF_AND | BPF_FETCH: 804 + EMIT(PPC_RAW_AND(tmp2_reg, tmp2_reg, src_reg)); 805 + break; 806 + case BPF_OR: 807 + case BPF_OR | BPF_FETCH: 808 + EMIT(PPC_RAW_OR(tmp2_reg, tmp2_reg, src_reg)); 809 + break; 810 + case BPF_XOR: 811 + case BPF_XOR | BPF_FETCH: 812 + EMIT(PPC_RAW_XOR(tmp2_reg, tmp2_reg, src_reg)); 813 + break; 814 + case BPF_CMPXCHG: 815 + /* 816 + * Return old value in BPF_REG_0 for BPF_CMPXCHG & 817 + * in src_reg for other cases. 818 + */ 819 + ret_reg = bpf_to_ppc(BPF_REG_0); 820 + 821 + /* Compare with old value in BPF_R0 */ 822 + if (size == BPF_DW) 823 + EMIT(PPC_RAW_CMPD(bpf_to_ppc(BPF_REG_0), tmp2_reg)); 824 + else 825 + EMIT(PPC_RAW_CMPW(bpf_to_ppc(BPF_REG_0), tmp2_reg)); 826 + /* Don't set if different from old value */ 827 + PPC_BCC_SHORT(COND_NE, (ctx->idx + 3) * 4); 828 + fallthrough; 829 + case BPF_XCHG: 830 + save_reg = src_reg; 831 + break; 832 + default: 804 833 pr_err_ratelimited( 805 834 "eBPF filter atomic op code %02x (@%d) unsupported\n", 806 835 code, i); 807 - return -ENOTSUPP; 836 + return -EOPNOTSUPP; 808 837 } 809 - /* *(u64 *)(dst + off) += src */ 810 838 811 - EMIT(PPC_RAW_ADDI(tmp1_reg, dst_reg, off)); 812 - tmp_idx = ctx->idx * 4; 813 - EMIT(PPC_RAW_LDARX(tmp2_reg, 0, tmp1_reg, 0)); 814 - EMIT(PPC_RAW_ADD(tmp2_reg, tmp2_reg, src_reg)); 815 - EMIT(PPC_RAW_STDCX(tmp2_reg, 0, tmp1_reg)); 839 + /* store new value */ 840 + if (size == BPF_DW) 841 + EMIT(PPC_RAW_STDCX(save_reg, tmp1_reg, dst_reg)); 842 + else 843 + EMIT(PPC_RAW_STWCX(save_reg, tmp1_reg, dst_reg)); 844 + /* we're done if this succeeded */ 816 845 PPC_BCC_SHORT(COND_NE, tmp_idx); 846 + 847 + if (imm & BPF_FETCH) { 848 + EMIT(PPC_RAW_MR(ret_reg, _R0)); 849 + /* 850 + * Skip unnecessary zero-extension for 32-bit cmpxchg. 851 + * For context, see commit 39491867ace5. 852 + */ 853 + if (size != BPF_DW && imm == BPF_CMPXCHG && 854 + insn_is_zext(&insn[i + 1])) 855 + addrs[++i] = ctx->idx * 4; 856 + } 817 857 break; 818 858 819 859 /*
+46 -20
arch/powerpc/perf/core-book3s.c
··· 1349 1349 * a PMI happens during interrupt replay and perf counter 1350 1350 * values are cleared by PMU callbacks before replay. 1351 1351 * 1352 - * If any PMC corresponding to the active PMU events are 1353 - * overflown, disable the interrupt by clearing the paca 1354 - * bit for PMI since we are disabling the PMU now. 1355 - * Otherwise provide a warning if there is PMI pending, but 1356 - * no counter is found overflown. 1352 + * Disable the interrupt by clearing the paca bit for PMI 1353 + * since we are disabling the PMU now. Otherwise provide a 1354 + * warning if there is PMI pending, but no counter is found 1355 + * overflown. 1356 + * 1357 + * Since power_pmu_disable runs under local_irq_save, it 1358 + * could happen that code hits a PMC overflow without PMI 1359 + * pending in paca. Hence only clear PMI pending if it was 1360 + * set. 1361 + * 1362 + * If a PMI is pending, then MSR[EE] must be disabled (because 1363 + * the masked PMI handler disabling EE). So it is safe to 1364 + * call clear_pmi_irq_pending(). 1357 1365 */ 1358 - if (any_pmc_overflown(cpuhw)) { 1359 - /* 1360 - * Since power_pmu_disable runs under local_irq_save, it 1361 - * could happen that code hits a PMC overflow without PMI 1362 - * pending in paca. Hence only clear PMI pending if it was 1363 - * set. 1364 - * 1365 - * If a PMI is pending, then MSR[EE] must be disabled (because 1366 - * the masked PMI handler disabling EE). So it is safe to 1367 - * call clear_pmi_irq_pending(). 1368 - */ 1369 - if (pmi_irq_pending()) 1370 - clear_pmi_irq_pending(); 1371 - } else 1372 - WARN_ON(pmi_irq_pending()); 1366 + if (pmi_irq_pending()) 1367 + clear_pmi_irq_pending(); 1373 1368 1374 1369 val = mmcra = cpuhw->mmcr.mmcra; 1375 1370 ··· 2483 2488 return 0; 2484 2489 } 2485 2490 2491 + static ssize_t pmu_name_show(struct device *cdev, 2492 + struct device_attribute *attr, 2493 + char *buf) 2494 + { 2495 + if (ppmu) 2496 + return sysfs_emit(buf, "%s", ppmu->name); 2497 + 2498 + return 0; 2499 + } 2500 + 2501 + static DEVICE_ATTR_RO(pmu_name); 2502 + 2503 + static struct attribute *pmu_caps_attrs[] = { 2504 + &dev_attr_pmu_name.attr, 2505 + NULL 2506 + }; 2507 + 2508 + static const struct attribute_group pmu_caps_group = { 2509 + .name = "caps", 2510 + .attrs = pmu_caps_attrs, 2511 + }; 2512 + 2513 + static const struct attribute_group *pmu_caps_groups[] = { 2514 + &pmu_caps_group, 2515 + NULL, 2516 + }; 2517 + 2486 2518 int __init register_power_pmu(struct power_pmu *pmu) 2487 2519 { 2488 2520 if (ppmu) ··· 2520 2498 pmu->name); 2521 2499 2522 2500 power_pmu.attr_groups = ppmu->attr_groups; 2501 + 2502 + if (ppmu->flags & PPMU_ARCH_207S) 2503 + power_pmu.attr_update = pmu_caps_groups; 2504 + 2523 2505 power_pmu.capabilities |= (ppmu->capabilities & PERF_PMU_CAP_EXTENDED_REGS); 2524 2506 2525 2507 #ifdef MSR_HV
+5 -4
arch/powerpc/perf/e500-pmu.c
··· 118 118 119 119 static int init_e500_pmu(void) 120 120 { 121 - if (!cur_cpu_spec->oprofile_cpu_type) 122 - return -ENODEV; 121 + unsigned int pvr = mfspr(SPRN_PVR); 123 122 124 - if (!strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/e500mc")) 123 + /* ec500mc */ 124 + if (PVR_VER(pvr) == PVR_VER_E500MC || PVR_VER(pvr) == PVR_VER_E5500) 125 125 num_events = 256; 126 - else if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/e500")) 126 + /* e500 */ 127 + else if (PVR_VER(pvr) != PVR_VER_E500V1 && PVR_VER(pvr) != PVR_VER_E500V2) 127 128 return -ENODEV; 128 129 129 130 return register_fsl_emb_pmu(&e500_pmu);
+3 -2
arch/powerpc/perf/e6500-pmu.c
··· 107 107 108 108 static int init_e6500_pmu(void) 109 109 { 110 - if (!cur_cpu_spec->oprofile_cpu_type || 111 - strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/e6500")) 110 + unsigned int pvr = mfspr(SPRN_PVR); 111 + 112 + if (PVR_VER(pvr) != PVR_VER_E6500) 112 113 return -ENODEV; 113 114 114 115 return register_fsl_emb_pmu(&e6500_pmu);
+11 -1
arch/powerpc/perf/generic-compat-pmu.c
··· 151 151 .attrs = generic_compat_pmu_format_attr, 152 152 }; 153 153 154 + static struct attribute *generic_compat_pmu_caps_attrs[] = { 155 + NULL 156 + }; 157 + 158 + static struct attribute_group generic_compat_pmu_caps_group = { 159 + .name = "caps", 160 + .attrs = generic_compat_pmu_caps_attrs, 161 + }; 162 + 154 163 static const struct attribute_group *generic_compat_pmu_attr_groups[] = { 155 164 &generic_compat_pmu_format_group, 156 165 &generic_compat_pmu_events_group, 166 + &generic_compat_pmu_caps_group, 157 167 NULL, 158 168 }; 159 169 ··· 302 292 } 303 293 304 294 static struct power_pmu generic_compat_pmu = { 305 - .name = "GENERIC_COMPAT", 295 + .name = "ISAv3", 306 296 .n_counter = MAX_PMU_COUNTERS, 307 297 .add_fields = ISA207_ADD_FIELDS, 308 298 .test_adder = ISA207_TEST_ADDER,
+3 -3
arch/powerpc/perf/hv-24x7.c
··· 1718 1718 { 1719 1719 int r; 1720 1720 unsigned long hret; 1721 + unsigned int pvr = mfspr(SPRN_PVR); 1721 1722 struct hv_perf_caps caps; 1722 1723 1723 1724 if (!firmware_has_feature(FW_FEATURE_LPAR)) { 1724 1725 pr_debug("not a virtualized system, not enabling\n"); 1725 1726 return -ENODEV; 1726 - } else if (!cur_cpu_spec->oprofile_cpu_type) 1727 - return -ENODEV; 1727 + } 1728 1728 1729 1729 /* POWER8 only supports v1, while POWER9 only supports v2. */ 1730 - if (!strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power8")) 1730 + if (PVR_VER(pvr) == PVR_POWER8) 1731 1731 interface_version = 1; 1732 1732 else { 1733 1733 interface_version = 2;
+3
arch/powerpc/perf/isa207-common.c
··· 686 686 mmcr2 |= MMCR2_FCS(pmc); 687 687 } 688 688 689 + if (pevents[i]->attr.exclude_idle) 690 + mmcr2 |= MMCR2_FCWAIT(pmc); 691 + 689 692 if (cpu_has_feature(CPU_FTR_ARCH_31)) { 690 693 if (pmc <= 4) { 691 694 val = (event[i] >> p10_EVENT_MMCR3_SHIFT) &
+1
arch/powerpc/perf/isa207-common.h
··· 249 249 /* Bits in MMCR2 for PowerISA v2.07 */ 250 250 #define MMCR2_FCS(pmc) (1ull << (63 - (((pmc) - 1) * 9))) 251 251 #define MMCR2_FCP(pmc) (1ull << (62 - (((pmc) - 1) * 9))) 252 + #define MMCR2_FCWAIT(pmc) (1ull << (58 - (((pmc) - 1) * 9))) 252 253 #define MMCR2_FCH(pmc) (1ull << (57 - (((pmc) - 1) * 9))) 253 254 254 255 #define MAX_ALT 2
+3 -2
arch/powerpc/perf/mpc7450-pmu.c
··· 417 417 418 418 static int __init init_mpc7450_pmu(void) 419 419 { 420 - if (!cur_cpu_spec->oprofile_cpu_type || 421 - strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/7450")) 420 + unsigned int pvr = mfspr(SPRN_PVR); 421 + 422 + if (PVR_VER(pvr) != PVR_7450) 422 423 return -ENODEV; 423 424 424 425 return register_power_pmu(&mpc7450_pmu);
+13 -4
arch/powerpc/perf/power10-pmu.c
··· 258 258 .attrs = power10_pmu_format_attr, 259 259 }; 260 260 261 + static struct attribute *power10_pmu_caps_attrs[] = { 262 + NULL 263 + }; 264 + 265 + static struct attribute_group power10_pmu_caps_group = { 266 + .name = "caps", 267 + .attrs = power10_pmu_caps_attrs, 268 + }; 269 + 261 270 static const struct attribute_group *power10_pmu_attr_groups_dd1[] = { 262 271 &power10_pmu_format_group, 263 272 &power10_pmu_events_group_dd1, 273 + &power10_pmu_caps_group, 264 274 NULL, 265 275 }; 266 276 267 277 static const struct attribute_group *power10_pmu_attr_groups[] = { 268 278 &power10_pmu_format_group, 269 279 &power10_pmu_events_group, 280 + &power10_pmu_caps_group, 270 281 NULL, 271 282 }; 272 283 ··· 608 597 unsigned int pvr; 609 598 int rc; 610 599 611 - /* Comes from cpu_specs[] */ 612 - if (!cur_cpu_spec->oprofile_cpu_type || 613 - strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power10")) 600 + pvr = mfspr(SPRN_PVR); 601 + if (PVR_VER(pvr) != PVR_POWER10) 614 602 return -ENODEV; 615 603 616 - pvr = mfspr(SPRN_PVR); 617 604 /* Add the ppmu flag for power10 DD1 */ 618 605 if ((PVR_CFG(pvr) == 1)) 619 606 power10_pmu.flags |= PPMU_P10_DD1;
+3 -3
arch/powerpc/perf/power5+-pmu.c
··· 679 679 680 680 int __init init_power5p_pmu(void) 681 681 { 682 - if (!cur_cpu_spec->oprofile_cpu_type || 683 - (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5+") 684 - && strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5++"))) 682 + unsigned int pvr = mfspr(SPRN_PVR); 683 + 684 + if (PVR_VER(pvr) != PVR_POWER5p) 685 685 return -ENODEV; 686 686 687 687 return register_power_pmu(&power5p_pmu);
+3 -2
arch/powerpc/perf/power5-pmu.c
··· 620 620 621 621 int __init init_power5_pmu(void) 622 622 { 623 - if (!cur_cpu_spec->oprofile_cpu_type || 624 - strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5")) 623 + unsigned int pvr = mfspr(SPRN_PVR); 624 + 625 + if (PVR_VER(pvr) != PVR_POWER5) 625 626 return -ENODEV; 626 627 627 628 return register_power_pmu(&power5_pmu);
+3 -2
arch/powerpc/perf/power6-pmu.c
··· 541 541 542 542 int __init init_power6_pmu(void) 543 543 { 544 - if (!cur_cpu_spec->oprofile_cpu_type || 545 - strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power6")) 544 + unsigned int pvr = mfspr(SPRN_PVR); 545 + 546 + if (PVR_VER(pvr) != PVR_POWER6) 546 547 return -ENODEV; 547 548 548 549 return register_power_pmu(&power6_pmu);
+4 -3
arch/powerpc/perf/power7-pmu.c
··· 447 447 448 448 int __init init_power7_pmu(void) 449 449 { 450 - if (!cur_cpu_spec->oprofile_cpu_type || 451 - strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power7")) 450 + unsigned int pvr = mfspr(SPRN_PVR); 451 + 452 + if (PVR_VER(pvr) != PVR_POWER7 && PVR_VER(pvr) != PVR_POWER7p) 452 453 return -ENODEV; 453 454 454 - if (pvr_version_is(PVR_POWER7p)) 455 + if (PVR_VER(pvr) == PVR_POWER7p) 455 456 power7_pmu.flags |= PPMU_SIAR_VALID; 456 457 457 458 return register_power_pmu(&power7_pmu);
+13 -2
arch/powerpc/perf/power8-pmu.c
··· 187 187 .attrs = power8_events_attr, 188 188 }; 189 189 190 + static struct attribute *power8_pmu_caps_attrs[] = { 191 + NULL 192 + }; 193 + 194 + static struct attribute_group power8_pmu_caps_group = { 195 + .name = "caps", 196 + .attrs = power8_pmu_caps_attrs, 197 + }; 198 + 190 199 static const struct attribute_group *power8_pmu_attr_groups[] = { 191 200 &isa207_pmu_format_group, 192 201 &power8_pmu_events_group, 202 + &power8_pmu_caps_group, 193 203 NULL, 194 204 }; 195 205 ··· 391 381 int __init init_power8_pmu(void) 392 382 { 393 383 int rc; 384 + unsigned int pvr = mfspr(SPRN_PVR); 394 385 395 - if (!cur_cpu_spec->oprofile_cpu_type || 396 - strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power8")) 386 + if (PVR_VER(pvr) != PVR_POWER8E && PVR_VER(pvr) != PVR_POWER8NVL && 387 + PVR_VER(pvr) != PVR_POWER8) 397 388 return -ENODEV; 398 389 399 390 rc = register_power_pmu(&power8_pmu);
+11 -3
arch/powerpc/perf/power9-pmu.c
··· 258 258 .attrs = power9_pmu_format_attr, 259 259 }; 260 260 261 + static struct attribute *power9_pmu_caps_attrs[] = { 262 + NULL 263 + }; 264 + 265 + static struct attribute_group power9_pmu_caps_group = { 266 + .name = "caps", 267 + .attrs = power9_pmu_caps_attrs, 268 + }; 269 + 261 270 static const struct attribute_group *power9_pmu_attr_groups[] = { 262 271 &power9_pmu_format_group, 263 272 &power9_pmu_events_group, 273 + &power9_pmu_caps_group, 264 274 NULL, 265 275 }; 266 276 ··· 467 457 int rc = 0; 468 458 unsigned int pvr = mfspr(SPRN_PVR); 469 459 470 - /* Comes from cpu_specs[] */ 471 - if (!cur_cpu_spec->oprofile_cpu_type || 472 - strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power9")) 460 + if (PVR_VER(pvr) != PVR_POWER9) 473 461 return -ENODEV; 474 462 475 463 /* Blacklist events */
+4 -3
arch/powerpc/perf/ppc970-pmu.c
··· 491 491 492 492 int __init init_ppc970_pmu(void) 493 493 { 494 - if (!cur_cpu_spec->oprofile_cpu_type || 495 - (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970") 496 - && strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970MP"))) 494 + unsigned int pvr = mfspr(SPRN_PVR); 495 + 496 + if (PVR_VER(pvr) != PVR_970 && PVR_VER(pvr) != PVR_970MP && 497 + PVR_VER(pvr) != PVR_970FX && PVR_VER(pvr) != PVR_970GX) 497 498 return -ENODEV; 498 499 499 500 return register_power_pmu(&ppc970_pmu);
+1 -1
arch/powerpc/platforms/4xx/cpm.c
··· 63 63 * known as class 1, 2 and 3. For class 1 units, they are 64 64 * unconditionally put to sleep when the corresponding CPM bit is 65 65 * set. For class 2 and 3 units this is not case; if they can be 66 - * put to to sleep, they will. Here we do not verify, we just 66 + * put to sleep, they will. Here we do not verify, we just 67 67 * set them and expect them to eventually go off when they can. 68 68 */ 69 69 value = dcr_read(cpm.dcr_host, cpm.dcr_offset[cpm_reg]);
-37
arch/powerpc/platforms/52xx/mpc52xx_common.c
··· 204 204 EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv); 205 205 206 206 /** 207 - * mpc52xx_get_xtal_freq - Get SYS_XTAL_IN frequency for a device 208 - * 209 - * @node: device node 210 - * 211 - * Returns the frequency of the external oscillator clock connected 212 - * to the SYS_XTAL_IN pin, or 0 if it cannot be determined. 213 - */ 214 - unsigned int mpc52xx_get_xtal_freq(struct device_node *node) 215 - { 216 - u32 val; 217 - unsigned int freq; 218 - 219 - if (!mpc52xx_cdm) 220 - return 0; 221 - 222 - freq = mpc5xxx_get_bus_frequency(node); 223 - if (!freq) 224 - return 0; 225 - 226 - if (in_8(&mpc52xx_cdm->ipb_clk_sel) & 0x1) 227 - freq *= 2; 228 - 229 - val = in_be32(&mpc52xx_cdm->rstcfg); 230 - if (val & (1 << 5)) 231 - freq *= 8; 232 - else 233 - freq *= 4; 234 - if (val & (1 << 6)) 235 - freq /= 12; 236 - else 237 - freq /= 16; 238 - 239 - return freq; 240 - } 241 - EXPORT_SYMBOL(mpc52xx_get_xtal_freq); 242 - 243 - /** 244 207 * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer 245 208 */ 246 209 void __noreturn mpc52xx_restart(char *cmd)
+10 -17
arch/powerpc/platforms/52xx/mpc52xx_gpt.c
··· 60 60 #include <linux/of_platform.h> 61 61 #include <linux/of_gpio.h> 62 62 #include <linux/kernel.h> 63 + #include <linux/property.h> 63 64 #include <linux/slab.h> 64 65 #include <linux/fs.h> 65 66 #include <linux/watchdog.h> ··· 317 316 return 0; 318 317 } 319 318 320 - static void 321 - mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) 319 + static void mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt) 322 320 { 323 321 int rc; 324 322 325 - /* Only setup GPIO if the device tree claims the GPT is 326 - * a GPIO controller */ 327 - if (!of_find_property(node, "gpio-controller", NULL)) 323 + /* Only setup GPIO if the device claims the GPT is a GPIO controller */ 324 + if (!device_property_present(gpt->dev, "gpio-controller")) 328 325 return; 329 326 330 - gpt->gc.label = kasprintf(GFP_KERNEL, "%pOF", node); 327 + gpt->gc.label = kasprintf(GFP_KERNEL, "%pfw", dev_fwnode(gpt->dev)); 331 328 if (!gpt->gc.label) { 332 329 dev_err(gpt->dev, "out of memory\n"); 333 330 return; ··· 337 338 gpt->gc.get = mpc52xx_gpt_gpio_get; 338 339 gpt->gc.set = mpc52xx_gpt_gpio_set; 339 340 gpt->gc.base = -1; 340 - gpt->gc.of_node = node; 341 + gpt->gc.parent = gpt->dev; 341 342 342 343 /* Setup external pin in GPIO mode */ 343 344 clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, ··· 350 351 dev_dbg(gpt->dev, "%s() complete.\n", __func__); 351 352 } 352 353 #else /* defined(CONFIG_GPIOLIB) */ 353 - static void 354 - mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *p, struct device_node *np) { } 354 + static void mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt) { } 355 355 #endif /* defined(CONFIG_GPIOLIB) */ 356 356 357 357 /*********************************************************************** ··· 720 722 721 723 raw_spin_lock_init(&gpt->lock); 722 724 gpt->dev = &ofdev->dev; 723 - gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); 725 + gpt->ipb_freq = mpc5xxx_get_bus_frequency(&ofdev->dev); 724 726 gpt->regs = of_iomap(ofdev->dev.of_node, 0); 725 727 if (!gpt->regs) 726 728 return -ENOMEM; 727 729 728 730 dev_set_drvdata(&ofdev->dev, gpt); 729 731 730 - mpc52xx_gpt_gpio_setup(gpt, ofdev->dev.of_node); 732 + mpc52xx_gpt_gpio_setup(gpt); 731 733 mpc52xx_gpt_irq_setup(gpt, ofdev->dev.of_node); 732 734 733 735 mutex_lock(&mpc52xx_gpt_list_mutex); ··· 753 755 return 0; 754 756 } 755 757 756 - static int mpc52xx_gpt_remove(struct platform_device *ofdev) 757 - { 758 - return -EBUSY; 759 - } 760 - 761 758 static const struct of_device_id mpc52xx_gpt_match[] = { 762 759 { .compatible = "fsl,mpc5200-gpt", }, 763 760 ··· 765 772 static struct platform_driver mpc52xx_gpt_driver = { 766 773 .driver = { 767 774 .name = "mpc52xx-gpt", 775 + .suppress_bind_attrs = true, 768 776 .of_match_table = mpc52xx_gpt_match, 769 777 }, 770 778 .probe = mpc52xx_gpt_probe, 771 - .remove = mpc52xx_gpt_remove, 772 779 }; 773 780 774 781 static int __init mpc52xx_gpt_init(void)
+6 -8
arch/powerpc/platforms/83xx/misc.c
··· 121 121 122 122 void __init mpc83xx_setup_arch(void) 123 123 { 124 + phys_addr_t immrbase = get_immrbase(); 125 + int immrsize = IS_ALIGNED(immrbase, SZ_2M) ? SZ_2M : SZ_1M; 126 + unsigned long va = fix_to_virt(FIX_IMMR_BASE); 127 + 124 128 if (ppc_md.progress) 125 129 ppc_md.progress("mpc83xx_setup_arch()", 0); 126 130 127 - if (!__map_without_bats) { 128 - phys_addr_t immrbase = get_immrbase(); 129 - int immrsize = IS_ALIGNED(immrbase, SZ_2M) ? SZ_2M : SZ_1M; 130 - unsigned long va = fix_to_virt(FIX_IMMR_BASE); 131 - 132 - setbat(-1, va, immrbase, immrsize, PAGE_KERNEL_NCG); 133 - update_bats(); 134 - } 131 + setbat(-1, va, immrbase, immrsize, PAGE_KERNEL_NCG); 132 + update_bats(); 135 133 } 136 134 137 135 int machine_check_83xx(struct pt_regs *regs)
+22 -30
arch/powerpc/platforms/83xx/suspend.c
··· 100 100 int has_deep_sleep; 101 101 }; 102 102 103 - static struct platform_device *pmc_dev; 104 103 static int has_deep_sleep, deep_sleeping; 105 104 static int pmc_irq; 106 105 static struct mpc83xx_pmc __iomem *pmc_regs; ··· 318 319 .end = mpc83xx_suspend_end, 319 320 }; 320 321 321 - static const struct of_device_id pmc_match[]; 322 + static struct pmc_type pmc_types[] = { 323 + { 324 + .has_deep_sleep = 1, 325 + }, 326 + { 327 + .has_deep_sleep = 0, 328 + } 329 + }; 330 + 331 + static const struct of_device_id pmc_match[] = { 332 + { 333 + .compatible = "fsl,mpc8313-pmc", 334 + .data = &pmc_types[0], 335 + }, 336 + { 337 + .compatible = "fsl,mpc8349-pmc", 338 + .data = &pmc_types[1], 339 + }, 340 + {} 341 + }; 342 + 322 343 static int pmc_probe(struct platform_device *ofdev) 323 344 { 324 345 struct device_node *np = ofdev->dev.of_node; ··· 355 336 356 337 has_deep_sleep = type->has_deep_sleep; 357 338 immrbase = get_immrbase(); 358 - pmc_dev = ofdev; 359 339 360 340 is_pci_agent = mpc83xx_is_pci_agent(); 361 341 if (is_pci_agent < 0) ··· 419 401 return ret; 420 402 } 421 403 422 - static int pmc_remove(struct platform_device *ofdev) 423 - { 424 - return -EPERM; 425 - }; 426 - 427 - static struct pmc_type pmc_types[] = { 428 - { 429 - .has_deep_sleep = 1, 430 - }, 431 - { 432 - .has_deep_sleep = 0, 433 - } 434 - }; 435 - 436 - static const struct of_device_id pmc_match[] = { 437 - { 438 - .compatible = "fsl,mpc8313-pmc", 439 - .data = &pmc_types[0], 440 - }, 441 - { 442 - .compatible = "fsl,mpc8349-pmc", 443 - .data = &pmc_types[1], 444 - }, 445 - {} 446 - }; 447 - 448 404 static struct platform_driver pmc_driver = { 449 405 .driver = { 450 406 .name = "mpc83xx-pmc", 451 407 .of_match_table = pmc_match, 408 + .suppress_bind_attrs = true, 452 409 }, 453 410 .probe = pmc_probe, 454 - .remove = pmc_remove 455 411 }; 456 412 457 413 builtin_platform_driver(pmc_driver);
+10 -8
arch/powerpc/platforms/85xx/Kconfig
··· 62 62 This option enables support for the MPC85xx CDS board 63 63 64 64 config MPC85xx_MDS 65 - bool "Freescale MPC85xx MDS" 65 + bool "Freescale MPC8568 MDS / MPC8569 MDS / P1021 MDS" 66 66 select DEFAULT_UIMAGE 67 67 select PHYLIB if NETDEVICES 68 68 select HAVE_RAPIDIO 69 69 select SWIOTLB 70 70 help 71 - This option enables support for the MPC85xx MDS board 71 + This option enables support for the MPC8568 MDS, MPC8569 MDS and P1021 MDS boards 72 72 73 73 config MPC8536_DS 74 74 bool "Freescale MPC8536 DS" ··· 78 78 This option enables support for the MPC8536 DS board 79 79 80 80 config MPC85xx_DS 81 - bool "Freescale MPC85xx DS" 81 + bool "Freescale MPC8544 DS / MPC8572 DS / P2020 DS" 82 82 select PPC_I8259 83 83 select DEFAULT_UIMAGE 84 84 select FSL_ULI1575 if PCI 85 85 select SWIOTLB 86 86 help 87 - This option enables support for the MPC85xx DS (MPC8544 DS) board 87 + This option enables support for the MPC8544 DS, MPC8572 DS and P2020 DS boards 88 88 89 89 config MPC85xx_RDB 90 - bool "Freescale MPC85xx RDB" 90 + bool "Freescale P102x MBG/UTM/RDB and P2020 RDB" 91 91 select PPC_I8259 92 92 select DEFAULT_UIMAGE 93 93 select FSL_ULI1575 if PCI 94 94 select SWIOTLB 95 95 help 96 - This option enables support for the MPC85xx RDB (P2020 RDB) board 96 + This option enables support for the P1020 MBG PC, P1020 UTM PC, 97 + P1020 RDB PC, P1020 RDB PD, P1020 RDB, P1021 RDB PC, P1024 RDB, 98 + P1025 RDB, P2020 RDB and P2020 RDB PC boards 97 99 98 100 config P1010_RDB 99 - bool "Freescale P1010RDB" 101 + bool "Freescale P1010 RDB" 100 102 select DEFAULT_UIMAGE 101 103 help 102 - This option enables support for the MPC85xx RDB (P1010 RDB) board 104 + This option enables support for the P1010 RDB board 103 105 104 106 P1010RDB contains P1010Si, which provides CPU performance up to 800 105 107 MHz and 1600 DMIPS, additional functionality and faster interfaces
+47 -13
arch/powerpc/platforms/Kconfig.cputype
··· 2 2 config PPC32 3 3 bool 4 4 default y if !PPC64 5 - select KASAN_VMALLOC if KASAN && MODULES 6 5 7 6 config PPC64 8 7 bool "64-bit kernel" ··· 126 127 127 128 config GENERIC_CPU 128 129 bool "Generic (POWER4 and above)" 129 - depends on PPC64 && !CPU_LITTLE_ENDIAN 130 - select PPC_64S_HASH_MMU if PPC_BOOK3S_64 131 - 132 - config GENERIC_CPU 133 - bool "Generic (POWER8 and above)" 134 - depends on PPC64 && CPU_LITTLE_ENDIAN 135 - select ARCH_HAS_FAST_MULTIPLIER 130 + depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN 136 131 select PPC_64S_HASH_MMU 137 132 138 133 config GENERIC_CPU 134 + bool "Generic (POWER8 and above)" 135 + depends on PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN 136 + select ARCH_HAS_FAST_MULTIPLIER 137 + select PPC_64S_HASH_MMU 138 + 139 + config POWERPC_CPU 139 140 bool "Generic 32 bits powerpc" 140 - depends on PPC32 && !PPC_8xx 141 + depends on PPC_BOOK3S_32 141 142 142 143 config CELL_CPU 143 144 bool "Cell Broadband Engine" ··· 173 174 174 175 config E5500_CPU 175 176 bool "Freescale e5500" 176 - depends on E500 177 + depends on PPC64 && E500 177 178 178 179 config E6500_CPU 179 180 bool "Freescale e6500" 180 - depends on E500 181 + depends on PPC64 && E500 182 + 183 + config 405_CPU 184 + bool "40x family" 185 + depends on 40x 186 + 187 + config 440_CPU 188 + bool "440 (44x family)" 189 + depends on 44x 190 + 191 + config 464_CPU 192 + bool "464 (44x family)" 193 + depends on 44x 194 + 195 + config 476_CPU 196 + bool "476 (47x family)" 197 + depends on PPC_47x 181 198 182 199 config 860_CPU 183 200 bool "8xx family" ··· 212 197 depends on PPC_BOOK3S_32 213 198 select ALTIVEC 214 199 200 + config E500_CPU 201 + bool "e500 (8540)" 202 + depends on PPC_85xx && !PPC_E500MC 203 + 204 + config E500MC_CPU 205 + bool "e500mc" 206 + depends on PPC_85xx && PPC_E500MC 207 + 208 + config TOOLCHAIN_DEFAULT_CPU 209 + bool "Rely on the toolchain's implicit default CPU" 210 + depends on PPC32 211 + 215 212 endchoice 216 213 217 214 config TARGET_CPU_BOOL 218 215 bool 219 - default !GENERIC_CPU 216 + default !GENERIC_CPU && !TOOLCHAIN_DEFAULT_CPU 220 217 221 218 config TARGET_CPU 222 219 string ··· 239 212 default "power7" if POWER7_CPU 240 213 default "power8" if POWER8_CPU 241 214 default "power9" if POWER9_CPU 215 + default "405" if 405_CPU 216 + default "440" if 440_CPU 217 + default "464" if 464_CPU 218 + default "476" if 476_CPU 242 219 default "860" if 860_CPU 243 220 default "e300c2" if E300C2_CPU 244 221 default "e300c3" if E300C3_CPU 245 222 default "G4" if G4_CPU 223 + default "8540" if E500_CPU 224 + default "e500mc" if E500MC_CPU 225 + default "powerpc" if POWERPC_CPU 246 226 247 227 config PPC_BOOK3S 248 228 def_bool y ··· 358 324 359 325 config ALTIVEC 360 326 bool "AltiVec Support" 361 - depends on PPC_BOOK3S_32 || PPC_BOOK3S_64 || (PPC_E500MC && PPC64) 327 + depends on PPC_BOOK3S || (PPC_E500MC && PPC64 && !E5500_CPU) 362 328 select PPC_FPU 363 329 help 364 330 This option enables kernel support for the Altivec extensions to the
+1
arch/powerpc/platforms/cell/axon_msi.c
··· 223 223 if (!prop) { 224 224 dev_dbg(&dev->dev, 225 225 "axon_msi: no msi-address-(32|64) properties found\n"); 226 + of_node_put(dn); 226 227 return -ENOENT; 227 228 } 228 229
+1
arch/powerpc/platforms/cell/spufs/inode.c
··· 660 660 return; 661 661 662 662 loader = of_get_property(dn, "loader", &size); 663 + of_node_put(dn); 663 664 if (!loader) 664 665 return; 665 666
+1 -1
arch/powerpc/platforms/cell/spufs/spufs.h
··· 76 76 struct address_space *mss; /* 'mss' area mappings. */ 77 77 struct address_space *psmap; /* 'psmap' area mappings. */ 78 78 struct mutex mapping_lock; 79 - u64 object_id; /* user space pointer for oprofile */ 79 + u64 object_id; /* user space pointer for GNU Debugger */ 80 80 81 81 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; 82 82 struct mutex state_mutex;
-7
arch/powerpc/platforms/powermac/setup.c
··· 320 320 #endif /* CONFIG_ADB */ 321 321 } 322 322 323 - #ifdef CONFIG_SCSI 324 - void note_scsi_host(struct device_node *node, void *host) 325 - { 326 - } 327 - EXPORT_SYMBOL(note_scsi_host); 328 - #endif 329 - 330 323 static int initializing = 1; 331 324 332 325 static int pmac_late_init(void)
+1 -1
arch/powerpc/platforms/powernv/Kconfig
··· 19 19 default y 20 20 21 21 config OPAL_PRD 22 - tristate 'OPAL PRD driver' 22 + tristate "OPAL PRD driver" 23 23 depends on PPC_POWERNV 24 24 help 25 25 This enables the opal-prd driver, a facility to run processor
+2
arch/powerpc/platforms/powernv/pci-ioda.c
··· 1609 1609 tbl->it_ops = &pnv_ioda1_iommu_ops; 1610 1610 pe->table_group.tce32_start = tbl->it_offset << tbl->it_page_shift; 1611 1611 pe->table_group.tce32_size = tbl->it_size << tbl->it_page_shift; 1612 + tbl->it_index = (phb->hose->global_number << 16) | pe->pe_number; 1612 1613 if (!iommu_init_table(tbl, phb->hose->node, 0, 0)) 1613 1614 panic("Failed to initialize iommu table"); 1614 1615 ··· 1780 1779 res_end = min(window_size, SZ_4G) >> tbl->it_page_shift; 1781 1780 } 1782 1781 1782 + tbl->it_index = (pe->phb->hose->global_number << 16) | pe->pe_number; 1783 1783 if (iommu_init_table(tbl, pe->phb->hose->node, res_start, res_end)) 1784 1784 rc = pnv_pci_ioda2_set_window(&pe->table_group, 0, tbl); 1785 1785 else
+23 -41
arch/powerpc/platforms/powernv/rng.c
··· 21 21 22 22 #define DARN_ERR 0xFFFFFFFFFFFFFFFFul 23 23 24 - struct powernv_rng { 24 + struct pnv_rng { 25 25 void __iomem *regs; 26 26 void __iomem *regs_real; 27 27 unsigned long mask; 28 28 }; 29 29 30 - static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng); 30 + static DEFINE_PER_CPU(struct pnv_rng *, pnv_rng); 31 31 32 - int powernv_hwrng_present(void) 33 - { 34 - struct powernv_rng *rng; 35 - 36 - rng = get_cpu_var(powernv_rng); 37 - put_cpu_var(rng); 38 - return rng != NULL; 39 - } 40 - 41 - static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val) 32 + static unsigned long rng_whiten(struct pnv_rng *rng, unsigned long val) 42 33 { 43 34 unsigned long parity; 44 35 ··· 49 58 return val; 50 59 } 51 60 52 - int powernv_get_random_real_mode(unsigned long *v) 53 - { 54 - struct powernv_rng *rng; 55 - 56 - rng = raw_cpu_read(powernv_rng); 57 - 58 - *v = rng_whiten(rng, __raw_rm_readq(rng->regs_real)); 59 - 60 - return 1; 61 - } 62 - 63 - static int powernv_get_random_darn(unsigned long *v) 61 + static int pnv_get_random_darn(unsigned long *v) 64 62 { 65 63 unsigned long val; 66 64 ··· 73 93 return -ENODEV; 74 94 75 95 for (i = 0; i < 10; i++) { 76 - if (powernv_get_random_darn(&val)) { 77 - ppc_md.get_random_seed = powernv_get_random_darn; 96 + if (pnv_get_random_darn(&val)) { 97 + ppc_md.get_random_seed = pnv_get_random_darn; 78 98 return 0; 79 99 } 80 100 } 81 101 return -EIO; 82 102 } 83 103 84 - int powernv_get_random_long(unsigned long *v) 104 + int pnv_get_random_long(unsigned long *v) 85 105 { 86 - struct powernv_rng *rng; 106 + struct pnv_rng *rng; 87 107 88 - rng = get_cpu_var(powernv_rng); 89 - 90 - *v = rng_whiten(rng, in_be64(rng->regs)); 91 - 92 - put_cpu_var(rng); 93 - 108 + if (mfmsr() & MSR_DR) { 109 + rng = get_cpu_var(pnv_rng); 110 + *v = rng_whiten(rng, in_be64(rng->regs)); 111 + put_cpu_var(rng); 112 + } else { 113 + rng = raw_cpu_read(pnv_rng); 114 + *v = rng_whiten(rng, __raw_rm_readq(rng->regs_real)); 115 + } 94 116 return 1; 95 117 } 96 - EXPORT_SYMBOL_GPL(powernv_get_random_long); 118 + EXPORT_SYMBOL_GPL(pnv_get_random_long); 97 119 98 - static __init void rng_init_per_cpu(struct powernv_rng *rng, 120 + static __init void rng_init_per_cpu(struct pnv_rng *rng, 99 121 struct device_node *dn) 100 122 { 101 123 int chip_id, cpu; ··· 107 125 pr_warn("No ibm,chip-id found for %pOF.\n", dn); 108 126 109 127 for_each_possible_cpu(cpu) { 110 - if (per_cpu(powernv_rng, cpu) == NULL || 128 + if (per_cpu(pnv_rng, cpu) == NULL || 111 129 cpu_to_chip_id(cpu) == chip_id) { 112 - per_cpu(powernv_rng, cpu) = rng; 130 + per_cpu(pnv_rng, cpu) = rng; 113 131 } 114 132 } 115 133 } 116 134 117 135 static __init int rng_create(struct device_node *dn) 118 136 { 119 - struct powernv_rng *rng; 137 + struct pnv_rng *rng; 120 138 struct resource res; 121 139 unsigned long val; 122 140 ··· 142 160 143 161 rng_init_per_cpu(rng, dn); 144 162 145 - ppc_md.get_random_seed = powernv_get_random_long; 163 + ppc_md.get_random_seed = pnv_get_random_long; 146 164 147 165 return 0; 148 166 } ··· 190 208 if (ppc_md.get_random_seed == pnv_get_random_long_early) 191 209 pnv_get_random_long_early(&v); 192 210 193 - if (ppc_md.get_random_seed == powernv_get_random_long) { 211 + if (ppc_md.get_random_seed == pnv_get_random_long) { 194 212 for_each_compatible_node(dn, NULL, "ibm,power-rng") 195 213 of_platform_device_create(dn, NULL, NULL); 196 214 }
+1 -1
arch/powerpc/platforms/powernv/vas-fault.c
··· 77 77 /* 78 78 * VAS can interrupt with multiple page faults. So process all 79 79 * valid CRBs within fault FIFO until reaches invalid CRB. 80 - * We use CCW[0] and pswid to validate validate CRBs: 80 + * We use CCW[0] and pswid to validate CRBs: 81 81 * 82 82 * CCW[0] Reserved bit. When NX pastes CRB, CCW[0]=0 83 83 * OS sets this bit to 1 after reading CRB.
+1 -1
arch/powerpc/platforms/ps3/Kconfig
··· 165 165 166 166 If you intend to use the advanced performance monitoring and 167 167 profiling support of the Cell processor with programs like 168 - oprofile and perfmon2, then say Y or M, otherwise say N. 168 + perfmon2, then say Y or M, otherwise say N. 169 169 170 170 config PS3GELIC_UDBG 171 171 bool "PS3 udbg output via UDP broadcasts on Ethernet"
+13
arch/powerpc/platforms/pseries/Kconfig
··· 141 141 help 142 142 Bus device driver for GX bus based adapters. 143 143 144 + config PSERIES_PLPKS 145 + depends on PPC_PSERIES 146 + bool "Support for the Platform Key Storage" 147 + help 148 + PowerVM provides an isolated Platform Keystore(PKS) storage 149 + allocation for each LPAR with individually managed access 150 + controls to store sensitive information securely. It can be 151 + used to store asymmetric public keys or secrets as required 152 + by different usecases. Select this config to enable 153 + operating system interface to hypervisor to access this space. 154 + 155 + If unsure, select N. 156 + 144 157 config PAPR_SCM 145 158 depends on PPC_PSERIES && MEMORY_HOTPLUG && LIBNVDIMM 146 159 tristate "Support for the PAPR Storage Class Memory interface"
+1
arch/powerpc/platforms/pseries/Makefile
··· 28 28 obj-$(CONFIG_PPC_SPLPAR) += vphn.o 29 29 obj-$(CONFIG_PPC_SVM) += svm.o 30 30 obj-$(CONFIG_FA_DUMP) += rtas-fadump.o 31 + obj-$(CONFIG_PSERIES_PLPKS) += plpks.o 31 32 32 33 obj-$(CONFIG_SUSPEND) += suspend.o 33 34 obj-$(CONFIG_PPC_VAS) += vas.o vas-sysfs.o
+1 -1
arch/powerpc/platforms/pseries/eeh_pseries.c
··· 71 71 if (pdev->is_virtfn) { 72 72 /* 73 73 * FIXME: This really should be handled by choosing the right 74 - * parent PE in in pseries_eeh_init_edev(). 74 + * parent PE in pseries_eeh_init_edev(). 75 75 */ 76 76 struct eeh_pe *physfn_pe = pci_dev_to_eeh_dev(pdev->physfn)->pe; 77 77 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+1
arch/powerpc/platforms/pseries/firmware.c
··· 67 67 {FW_FEATURE_PAPR_SCM, "hcall-scm"}, 68 68 {FW_FEATURE_RPT_INVALIDATE, "hcall-rpt-invalidate"}, 69 69 {FW_FEATURE_ENERGY_SCALE_INFO, "hcall-energy-scale-info"}, 70 + {FW_FEATURE_WATCHDOG, "hcall-watchdog"}, 70 71 }; 71 72 72 73 /* Build up the firmware features bitmask using the contents of
+53 -44
arch/powerpc/platforms/pseries/iommu.c
··· 700 700 .get = tce_get_pSeriesLP 701 701 }; 702 702 703 + /* 704 + * Find nearest ibm,dma-window (default DMA window) or direct DMA window or 705 + * dynamic 64bit DMA window, walking up the device tree. 706 + */ 707 + static struct device_node *pci_dma_find(struct device_node *dn, 708 + const __be32 **dma_window) 709 + { 710 + const __be32 *dw = NULL; 711 + 712 + for ( ; dn && PCI_DN(dn); dn = dn->parent) { 713 + dw = of_get_property(dn, "ibm,dma-window", NULL); 714 + if (dw) { 715 + if (dma_window) 716 + *dma_window = dw; 717 + return dn; 718 + } 719 + dw = of_get_property(dn, DIRECT64_PROPNAME, NULL); 720 + if (dw) 721 + return dn; 722 + dw = of_get_property(dn, DMA64_PROPNAME, NULL); 723 + if (dw) 724 + return dn; 725 + } 726 + 727 + return NULL; 728 + } 729 + 703 730 static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) 704 731 { 705 732 struct iommu_table *tbl; ··· 739 712 pr_debug("pci_dma_bus_setup_pSeriesLP: setting up bus %pOF\n", 740 713 dn); 741 714 742 - /* 743 - * Find nearest ibm,dma-window (default DMA window), walking up the 744 - * device tree 745 - */ 746 - for (pdn = dn; pdn != NULL; pdn = pdn->parent) { 747 - dma_window = of_get_property(pdn, "ibm,dma-window", NULL); 748 - if (dma_window != NULL) 749 - break; 750 - } 715 + pdn = pci_dma_find(dn, &dma_window); 751 716 752 - if (dma_window == NULL) { 717 + if (dma_window == NULL) 753 718 pr_debug(" no ibm,dma-window property !\n"); 754 - return; 755 - } 756 719 757 720 ppci = PCI_DN(pdn); 758 721 ··· 752 735 if (!ppci->table_group) { 753 736 ppci->table_group = iommu_pseries_alloc_group(ppci->phb->node); 754 737 tbl = ppci->table_group->tables[0]; 755 - iommu_table_setparms_lpar(ppci->phb, pdn, tbl, 756 - ppci->table_group, dma_window); 738 + if (dma_window) { 739 + iommu_table_setparms_lpar(ppci->phb, pdn, tbl, 740 + ppci->table_group, dma_window); 757 741 758 - if (!iommu_init_table(tbl, ppci->phb->node, 0, 0)) 759 - panic("Failed to initialize iommu table"); 742 + if (!iommu_init_table(tbl, ppci->phb->node, 0, 0)) 743 + panic("Failed to initialize iommu table"); 744 + } 760 745 iommu_register_group(ppci->table_group, 761 746 pci_domain_nr(bus), 0); 762 747 pr_debug(" created table: %p\n", ppci->table_group); ··· 1040 1021 1041 1022 ret = rtas_call(ddw_avail[DDW_QUERY_PE_DMA_WIN], 3, out_sz, query_out, 1042 1023 cfg_addr, BUID_HI(buid), BUID_LO(buid)); 1043 - dev_info(&dev->dev, "ibm,query-pe-dma-windows(%x) %x %x %x returned %d\n", 1044 - ddw_avail[DDW_QUERY_PE_DMA_WIN], cfg_addr, BUID_HI(buid), 1045 - BUID_LO(buid), ret); 1046 1024 1047 1025 switch (out_sz) { 1048 1026 case 5: ··· 1056 1040 query->migration_capable = query_out[4]; 1057 1041 break; 1058 1042 } 1043 + 1044 + dev_info(&dev->dev, "ibm,query-pe-dma-windows(%x) %x %x %x returned %d, lb=%llx ps=%x wn=%d\n", 1045 + ddw_avail[DDW_QUERY_PE_DMA_WIN], cfg_addr, BUID_HI(buid), 1046 + BUID_LO(buid), ret, query->largest_available_block, 1047 + query->page_size, query->windows_available); 1059 1048 1060 1049 return ret; 1061 1050 } ··· 1253 1232 bool default_win_removed = false, direct_mapping = false; 1254 1233 bool pmem_present; 1255 1234 struct pci_dn *pci = PCI_DN(pdn); 1256 - struct iommu_table *tbl = pci->table_group->tables[0]; 1235 + struct property *default_win = NULL; 1257 1236 1258 1237 dn = of_find_node_by_type(NULL, "ibm,pmemory"); 1259 1238 pmem_present = dn != NULL; ··· 1310 1289 * for extensions presence. 1311 1290 */ 1312 1291 if (query.windows_available == 0) { 1313 - struct property *default_win; 1314 1292 int reset_win_ext; 1315 1293 1316 1294 /* DDW + IOMMU on single window may fail if there is any allocation */ 1317 - if (iommu_table_in_use(tbl)) { 1295 + if (iommu_table_in_use(pci->table_group->tables[0])) { 1318 1296 dev_warn(&dev->dev, "current IOMMU table in use, can't be replaced.\n"); 1319 1297 goto out_failed; 1320 1298 } ··· 1449 1429 1450 1430 pci->table_group->tables[1] = newtbl; 1451 1431 1452 - /* Keep default DMA window struct if removed */ 1453 - if (default_win_removed) { 1454 - tbl->it_size = 0; 1455 - vfree(tbl->it_map); 1456 - tbl->it_map = NULL; 1457 - } 1458 - 1459 1432 set_iommu_table_base(&dev->dev, newtbl); 1433 + } 1434 + 1435 + if (default_win_removed) { 1436 + iommu_tce_table_put(pci->table_group->tables[0]); 1437 + pci->table_group->tables[0] = NULL; 1438 + 1439 + /* default_win is valid here because default_win_removed == true */ 1440 + of_remove_property(pdn, default_win); 1441 + dev_info(&dev->dev, "Removed default DMA window for %pOF\n", pdn); 1460 1442 } 1461 1443 1462 1444 spin_lock(&dma_win_list_lock); ··· 1525 1503 dn = pci_device_to_OF_node(dev); 1526 1504 pr_debug(" node is %pOF\n", dn); 1527 1505 1528 - for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->table_group; 1529 - pdn = pdn->parent) { 1530 - dma_window = of_get_property(pdn, "ibm,dma-window", NULL); 1531 - if (dma_window) 1532 - break; 1533 - } 1534 - 1506 + pdn = pci_dma_find(dn, &dma_window); 1535 1507 if (!pdn || !PCI_DN(pdn)) { 1536 1508 printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: " 1537 1509 "no DMA window found for pci dev=%s dn=%pOF\n", ··· 1556 1540 static bool iommu_bypass_supported_pSeriesLP(struct pci_dev *pdev, u64 dma_mask) 1557 1541 { 1558 1542 struct device_node *dn = pci_device_to_OF_node(pdev), *pdn; 1559 - const __be32 *dma_window = NULL; 1560 1543 1561 1544 /* only attempt to use a new window if 64-bit DMA is requested */ 1562 1545 if (dma_mask < DMA_BIT_MASK(64)) ··· 1569 1554 * search upwards in the tree until we either hit a dma-window 1570 1555 * property, OR find a parent with a table already allocated. 1571 1556 */ 1572 - for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->table_group; 1573 - pdn = pdn->parent) { 1574 - dma_window = of_get_property(pdn, "ibm,dma-window", NULL); 1575 - if (dma_window) 1576 - break; 1577 - } 1578 - 1557 + pdn = pci_dma_find(dn, NULL); 1579 1558 if (pdn && PCI_DN(pdn)) 1580 1559 return enable_ddw(pdev, pdn); 1581 1560
+1 -1
arch/powerpc/platforms/pseries/kexec.c
··· 6 6 #include <linux/kernel.h> 7 7 #include <linux/interrupt.h> 8 8 9 - #include <asm/machdep.h> 9 + #include <asm/setup.h> 10 10 #include <asm/page.h> 11 11 #include <asm/firmware.h> 12 12 #include <asm/kexec.h>
+1 -1
arch/powerpc/platforms/pseries/lpar.c
··· 27 27 #include <asm/processor.h> 28 28 #include <asm/mmu.h> 29 29 #include <asm/page.h> 30 - #include <asm/machdep.h> 30 + #include <asm/setup.h> 31 31 #include <asm/mmu_context.h> 32 32 #include <asm/iommu.h> 33 33 #include <asm/tlb.h>
+89 -2
arch/powerpc/platforms/pseries/mobility.c
··· 48 48 #define MIGRATION_SCOPE (1) 49 49 #define PRRN_SCOPE -2 50 50 51 + #ifdef CONFIG_PPC_WATCHDOG 52 + static unsigned int nmi_wd_lpm_factor = 200; 53 + 54 + #ifdef CONFIG_SYSCTL 55 + static struct ctl_table nmi_wd_lpm_factor_ctl_table[] = { 56 + { 57 + .procname = "nmi_wd_lpm_factor", 58 + .data = &nmi_wd_lpm_factor, 59 + .maxlen = sizeof(int), 60 + .mode = 0644, 61 + .proc_handler = proc_douintvec_minmax, 62 + }, 63 + {} 64 + }; 65 + static struct ctl_table nmi_wd_lpm_factor_sysctl_root[] = { 66 + { 67 + .procname = "kernel", 68 + .mode = 0555, 69 + .child = nmi_wd_lpm_factor_ctl_table, 70 + }, 71 + {} 72 + }; 73 + 74 + static int __init register_nmi_wd_lpm_factor_sysctl(void) 75 + { 76 + register_sysctl_table(nmi_wd_lpm_factor_sysctl_root); 77 + 78 + return 0; 79 + } 80 + device_initcall(register_nmi_wd_lpm_factor_sysctl); 81 + #endif /* CONFIG_SYSCTL */ 82 + #endif /* CONFIG_PPC_WATCHDOG */ 83 + 51 84 static int mobility_rtas_call(int token, char *buf, s32 scope) 52 85 { 53 86 int rc; ··· 460 427 return ret; 461 428 } 462 429 430 + static void wait_for_vasi_session_completed(u64 handle) 431 + { 432 + unsigned long state = 0; 433 + int ret; 434 + 435 + pr_info("waiting for memory transfer to complete...\n"); 436 + 437 + /* 438 + * Wait for transition from H_VASI_RESUMED to H_VASI_COMPLETED. 439 + */ 440 + while (true) { 441 + ret = poll_vasi_state(handle, &state); 442 + 443 + /* 444 + * If the memory transfer is already complete and the migration 445 + * has been cleaned up by the hypervisor, H_PARAMETER is return, 446 + * which is translate in EINVAL by poll_vasi_state(). 447 + */ 448 + if (ret == -EINVAL || (!ret && state == H_VASI_COMPLETED)) { 449 + pr_info("memory transfer completed.\n"); 450 + break; 451 + } 452 + 453 + if (ret) { 454 + pr_err("H_VASI_STATE return error (%d)\n", ret); 455 + break; 456 + } 457 + 458 + if (state != H_VASI_RESUMED) { 459 + pr_err("unexpected H_VASI_STATE result %lu\n", state); 460 + break; 461 + } 462 + 463 + msleep(500); 464 + } 465 + } 466 + 463 467 static void prod_single(unsigned int target_cpu) 464 468 { 465 469 long hvrc; ··· 735 665 static int pseries_migrate_partition(u64 handle) 736 666 { 737 667 int ret; 668 + unsigned int factor = 0; 738 669 670 + #ifdef CONFIG_PPC_WATCHDOG 671 + factor = nmi_wd_lpm_factor; 672 + #endif 739 673 ret = wait_for_vasi_session_suspending(handle); 740 674 if (ret) 741 675 return ret; 742 676 743 677 vas_migration_handler(VAS_SUSPEND); 744 678 679 + if (factor) 680 + watchdog_nmi_set_timeout_pct(factor); 681 + 745 682 ret = pseries_suspend(handle); 746 - if (ret == 0) 683 + if (ret == 0) { 747 684 post_mobility_fixup(); 748 - else 685 + /* 686 + * Wait until the memory transfer is complete, so that the user 687 + * space process returns from the syscall after the transfer is 688 + * complete. This allows the user hooks to be executed at the 689 + * right time. 690 + */ 691 + wait_for_vasi_session_completed(handle); 692 + } else 749 693 pseries_cancel_migration(handle, ret); 694 + 695 + if (factor) 696 + watchdog_nmi_set_timeout_pct(0); 750 697 751 698 vas_migration_handler(VAS_RESUME); 752 699
+1
arch/powerpc/platforms/pseries/papr_platform_attributes.c
··· 22 22 23 23 #include <asm/hvcall.h> 24 24 #include <asm/machdep.h> 25 + #include <asm/firmware.h> 25 26 26 27 #include "pseries.h" 27 28
+2 -2
arch/powerpc/platforms/pseries/papr_scm.c
··· 29 29 (1ul << ND_CMD_SET_CONFIG_DATA) | \ 30 30 (1ul << ND_CMD_CALL)) 31 31 32 - /* DIMM health bitmap bitmap indicators */ 32 + /* DIMM health bitmap indicators */ 33 33 /* SCM device is unable to persist memory contents */ 34 34 #define PAPR_PMEM_UNARMED (1ULL << (63 - 0)) 35 35 /* SCM device failed to persist memory contents */ ··· 354 354 { 355 355 struct papr_scm_perf_stat *stat; 356 356 struct papr_scm_perf_stats *stats; 357 - struct papr_scm_priv *p = (struct papr_scm_priv *)dev->driver_data; 357 + struct papr_scm_priv *p = dev_get_drvdata(dev); 358 358 int rc, size; 359 359 360 360 /* Allocate request buffer enough to hold single performance stat */
+460
arch/powerpc/platforms/pseries/plpks.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * POWER LPAR Platform KeyStore(PLPKS) 4 + * Copyright (C) 2022 IBM Corporation 5 + * Author: Nayna Jain <nayna@linux.ibm.com> 6 + * 7 + * Provides access to variables stored in Power LPAR Platform KeyStore(PLPKS). 8 + */ 9 + 10 + #define pr_fmt(fmt) "plpks: " fmt 11 + 12 + #include <linux/delay.h> 13 + #include <linux/errno.h> 14 + #include <linux/io.h> 15 + #include <linux/printk.h> 16 + #include <linux/slab.h> 17 + #include <linux/string.h> 18 + #include <linux/types.h> 19 + #include <asm/hvcall.h> 20 + 21 + #include "plpks.h" 22 + 23 + #define PKS_FW_OWNER 0x1 24 + #define PKS_BOOTLOADER_OWNER 0x2 25 + #define PKS_OS_OWNER 0x3 26 + 27 + #define LABEL_VERSION 0 28 + #define MAX_LABEL_ATTR_SIZE 16 29 + #define MAX_NAME_SIZE 239 30 + #define MAX_DATA_SIZE 4000 31 + 32 + #define PKS_FLUSH_MAX_TIMEOUT 5000 //msec 33 + #define PKS_FLUSH_SLEEP 10 //msec 34 + #define PKS_FLUSH_SLEEP_RANGE 400 35 + 36 + static u8 *ospassword; 37 + static u16 ospasswordlength; 38 + 39 + // Retrieved with H_PKS_GET_CONFIG 40 + static u16 maxpwsize; 41 + static u16 maxobjsize; 42 + 43 + struct plpks_auth { 44 + u8 version; 45 + u8 consumer; 46 + __be64 rsvd0; 47 + __be32 rsvd1; 48 + __be16 passwordlength; 49 + u8 password[]; 50 + } __packed __aligned(16); 51 + 52 + struct label_attr { 53 + u8 prefix[8]; 54 + u8 version; 55 + u8 os; 56 + u8 length; 57 + u8 reserved[5]; 58 + }; 59 + 60 + struct label { 61 + struct label_attr attr; 62 + u8 name[MAX_NAME_SIZE]; 63 + size_t size; 64 + }; 65 + 66 + static int pseries_status_to_err(int rc) 67 + { 68 + int err; 69 + 70 + switch (rc) { 71 + case H_SUCCESS: 72 + err = 0; 73 + break; 74 + case H_FUNCTION: 75 + err = -ENXIO; 76 + break; 77 + case H_P1: 78 + case H_P2: 79 + case H_P3: 80 + case H_P4: 81 + case H_P5: 82 + case H_P6: 83 + err = -EINVAL; 84 + break; 85 + case H_NOT_FOUND: 86 + err = -ENOENT; 87 + break; 88 + case H_BUSY: 89 + err = -EBUSY; 90 + break; 91 + case H_AUTHORITY: 92 + err = -EPERM; 93 + break; 94 + case H_NO_MEM: 95 + err = -ENOMEM; 96 + break; 97 + case H_RESOURCE: 98 + err = -EEXIST; 99 + break; 100 + case H_TOO_BIG: 101 + err = -EFBIG; 102 + break; 103 + case H_STATE: 104 + err = -EIO; 105 + break; 106 + case H_R_STATE: 107 + err = -EIO; 108 + break; 109 + case H_IN_USE: 110 + err = -EEXIST; 111 + break; 112 + case H_ABORTED: 113 + err = -EINTR; 114 + break; 115 + default: 116 + err = -EINVAL; 117 + } 118 + 119 + return err; 120 + } 121 + 122 + static int plpks_gen_password(void) 123 + { 124 + unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 125 + u8 *password, consumer = PKS_OS_OWNER; 126 + int rc; 127 + 128 + password = kzalloc(maxpwsize, GFP_KERNEL); 129 + if (!password) 130 + return -ENOMEM; 131 + 132 + rc = plpar_hcall(H_PKS_GEN_PASSWORD, retbuf, consumer, 0, 133 + virt_to_phys(password), maxpwsize); 134 + 135 + if (!rc) { 136 + ospasswordlength = maxpwsize; 137 + ospassword = kzalloc(maxpwsize, GFP_KERNEL); 138 + if (!ospassword) { 139 + kfree(password); 140 + return -ENOMEM; 141 + } 142 + memcpy(ospassword, password, ospasswordlength); 143 + } else { 144 + if (rc == H_IN_USE) { 145 + pr_warn("Password is already set for POWER LPAR Platform KeyStore\n"); 146 + rc = 0; 147 + } else { 148 + goto out; 149 + } 150 + } 151 + out: 152 + kfree(password); 153 + 154 + return pseries_status_to_err(rc); 155 + } 156 + 157 + static struct plpks_auth *construct_auth(u8 consumer) 158 + { 159 + struct plpks_auth *auth; 160 + 161 + if (consumer > PKS_OS_OWNER) 162 + return ERR_PTR(-EINVAL); 163 + 164 + auth = kmalloc(struct_size(auth, password, maxpwsize), GFP_KERNEL); 165 + if (!auth) 166 + return ERR_PTR(-ENOMEM); 167 + 168 + auth->version = 1; 169 + auth->consumer = consumer; 170 + auth->rsvd0 = 0; 171 + auth->rsvd1 = 0; 172 + 173 + if (consumer == PKS_FW_OWNER || consumer == PKS_BOOTLOADER_OWNER) { 174 + auth->passwordlength = 0; 175 + return auth; 176 + } 177 + 178 + memcpy(auth->password, ospassword, ospasswordlength); 179 + 180 + auth->passwordlength = cpu_to_be16(ospasswordlength); 181 + 182 + return auth; 183 + } 184 + 185 + /** 186 + * Label is combination of label attributes + name. 187 + * Label attributes are used internally by kernel and not exposed to the user. 188 + */ 189 + static struct label *construct_label(char *component, u8 varos, u8 *name, 190 + u16 namelen) 191 + { 192 + struct label *label; 193 + size_t slen; 194 + 195 + if (!name || namelen > MAX_NAME_SIZE) 196 + return ERR_PTR(-EINVAL); 197 + 198 + slen = strlen(component); 199 + if (component && slen > sizeof(label->attr.prefix)) 200 + return ERR_PTR(-EINVAL); 201 + 202 + label = kzalloc(sizeof(*label), GFP_KERNEL); 203 + if (!label) 204 + return ERR_PTR(-ENOMEM); 205 + 206 + if (component) 207 + memcpy(&label->attr.prefix, component, slen); 208 + 209 + label->attr.version = LABEL_VERSION; 210 + label->attr.os = varos; 211 + label->attr.length = MAX_LABEL_ATTR_SIZE; 212 + memcpy(&label->name, name, namelen); 213 + 214 + label->size = sizeof(struct label_attr) + namelen; 215 + 216 + return label; 217 + } 218 + 219 + static int _plpks_get_config(void) 220 + { 221 + unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 222 + struct { 223 + u8 version; 224 + u8 flags; 225 + __be32 rsvd0; 226 + __be16 maxpwsize; 227 + __be16 maxobjlabelsize; 228 + __be16 maxobjsize; 229 + __be32 totalsize; 230 + __be32 usedspace; 231 + __be32 supportedpolicies; 232 + __be64 rsvd1; 233 + } __packed config; 234 + size_t size; 235 + int rc; 236 + 237 + size = sizeof(config); 238 + 239 + rc = plpar_hcall(H_PKS_GET_CONFIG, retbuf, virt_to_phys(&config), size); 240 + 241 + if (rc != H_SUCCESS) 242 + return pseries_status_to_err(rc); 243 + 244 + maxpwsize = be16_to_cpu(config.maxpwsize); 245 + maxobjsize = be16_to_cpu(config.maxobjsize); 246 + 247 + return 0; 248 + } 249 + 250 + static int plpks_confirm_object_flushed(struct label *label, 251 + struct plpks_auth *auth) 252 + { 253 + unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 254 + u64 timeout = 0; 255 + u8 status; 256 + int rc; 257 + 258 + do { 259 + rc = plpar_hcall(H_PKS_CONFIRM_OBJECT_FLUSHED, retbuf, 260 + virt_to_phys(auth), virt_to_phys(label), 261 + label->size); 262 + 263 + status = retbuf[0]; 264 + if (rc) { 265 + if (rc == H_NOT_FOUND && status == 1) 266 + rc = 0; 267 + break; 268 + } 269 + 270 + if (!rc && status == 1) 271 + break; 272 + 273 + usleep_range(PKS_FLUSH_SLEEP, 274 + PKS_FLUSH_SLEEP + PKS_FLUSH_SLEEP_RANGE); 275 + timeout = timeout + PKS_FLUSH_SLEEP; 276 + } while (timeout < PKS_FLUSH_MAX_TIMEOUT); 277 + 278 + rc = pseries_status_to_err(rc); 279 + 280 + return rc; 281 + } 282 + 283 + int plpks_write_var(struct plpks_var var) 284 + { 285 + unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 286 + struct plpks_auth *auth; 287 + struct label *label; 288 + int rc; 289 + 290 + if (!var.component || !var.data || var.datalen <= 0 || 291 + var.namelen > MAX_NAME_SIZE || var.datalen > MAX_DATA_SIZE) 292 + return -EINVAL; 293 + 294 + if (var.policy & SIGNEDUPDATE) 295 + return -EINVAL; 296 + 297 + auth = construct_auth(PKS_OS_OWNER); 298 + if (IS_ERR(auth)) 299 + return PTR_ERR(auth); 300 + 301 + label = construct_label(var.component, var.os, var.name, var.namelen); 302 + if (IS_ERR(label)) { 303 + rc = PTR_ERR(label); 304 + goto out; 305 + } 306 + 307 + rc = plpar_hcall(H_PKS_WRITE_OBJECT, retbuf, virt_to_phys(auth), 308 + virt_to_phys(label), label->size, var.policy, 309 + virt_to_phys(var.data), var.datalen); 310 + 311 + if (!rc) 312 + rc = plpks_confirm_object_flushed(label, auth); 313 + 314 + if (rc) 315 + pr_err("Failed to write variable %s for component %s with error %d\n", 316 + var.name, var.component, rc); 317 + 318 + rc = pseries_status_to_err(rc); 319 + kfree(label); 320 + out: 321 + kfree(auth); 322 + 323 + return rc; 324 + } 325 + 326 + int plpks_remove_var(char *component, u8 varos, struct plpks_var_name vname) 327 + { 328 + unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 329 + struct plpks_auth *auth; 330 + struct label *label; 331 + int rc; 332 + 333 + if (!component || vname.namelen > MAX_NAME_SIZE) 334 + return -EINVAL; 335 + 336 + auth = construct_auth(PKS_OS_OWNER); 337 + if (IS_ERR(auth)) 338 + return PTR_ERR(auth); 339 + 340 + label = construct_label(component, varos, vname.name, vname.namelen); 341 + if (IS_ERR(label)) { 342 + rc = PTR_ERR(label); 343 + goto out; 344 + } 345 + 346 + rc = plpar_hcall(H_PKS_REMOVE_OBJECT, retbuf, virt_to_phys(auth), 347 + virt_to_phys(label), label->size); 348 + 349 + if (!rc) 350 + rc = plpks_confirm_object_flushed(label, auth); 351 + 352 + if (rc) 353 + pr_err("Failed to remove variable %s for component %s with error %d\n", 354 + vname.name, component, rc); 355 + 356 + rc = pseries_status_to_err(rc); 357 + kfree(label); 358 + out: 359 + kfree(auth); 360 + 361 + return rc; 362 + } 363 + 364 + static int plpks_read_var(u8 consumer, struct plpks_var *var) 365 + { 366 + unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 367 + struct plpks_auth *auth; 368 + struct label *label; 369 + u8 *output; 370 + int rc; 371 + 372 + if (var->namelen > MAX_NAME_SIZE) 373 + return -EINVAL; 374 + 375 + auth = construct_auth(PKS_OS_OWNER); 376 + if (IS_ERR(auth)) 377 + return PTR_ERR(auth); 378 + 379 + label = construct_label(var->component, var->os, var->name, 380 + var->namelen); 381 + if (IS_ERR(label)) { 382 + rc = PTR_ERR(label); 383 + goto out_free_auth; 384 + } 385 + 386 + output = kzalloc(maxobjsize, GFP_KERNEL); 387 + if (!output) { 388 + rc = -ENOMEM; 389 + goto out_free_label; 390 + } 391 + 392 + rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth), 393 + virt_to_phys(label), label->size, virt_to_phys(output), 394 + maxobjsize); 395 + 396 + if (rc != H_SUCCESS) { 397 + pr_err("Failed to read variable %s for component %s with error %d\n", 398 + var->name, var->component, rc); 399 + rc = pseries_status_to_err(rc); 400 + goto out_free_output; 401 + } 402 + 403 + if (var->datalen == 0 || var->datalen > retbuf[0]) 404 + var->datalen = retbuf[0]; 405 + 406 + var->data = kzalloc(var->datalen, GFP_KERNEL); 407 + if (!var->data) { 408 + rc = -ENOMEM; 409 + goto out_free_output; 410 + } 411 + var->policy = retbuf[1]; 412 + 413 + memcpy(var->data, output, var->datalen); 414 + rc = 0; 415 + 416 + out_free_output: 417 + kfree(output); 418 + out_free_label: 419 + kfree(label); 420 + out_free_auth: 421 + kfree(auth); 422 + 423 + return rc; 424 + } 425 + 426 + int plpks_read_os_var(struct plpks_var *var) 427 + { 428 + return plpks_read_var(PKS_OS_OWNER, var); 429 + } 430 + 431 + int plpks_read_fw_var(struct plpks_var *var) 432 + { 433 + return plpks_read_var(PKS_FW_OWNER, var); 434 + } 435 + 436 + int plpks_read_bootloader_var(struct plpks_var *var) 437 + { 438 + return plpks_read_var(PKS_BOOTLOADER_OWNER, var); 439 + } 440 + 441 + static __init int pseries_plpks_init(void) 442 + { 443 + int rc; 444 + 445 + rc = _plpks_get_config(); 446 + 447 + if (rc) { 448 + pr_err("POWER LPAR Platform KeyStore is not supported or enabled\n"); 449 + return rc; 450 + } 451 + 452 + rc = plpks_gen_password(); 453 + if (rc) 454 + pr_err("Failed setting POWER LPAR Platform KeyStore Password\n"); 455 + else 456 + pr_info("POWER LPAR Platform KeyStore initialized successfully\n"); 457 + 458 + return rc; 459 + } 460 + arch_initcall(pseries_plpks_init);
+71
arch/powerpc/platforms/pseries/plpks.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2022 IBM Corporation 4 + * Author: Nayna Jain <nayna@linux.ibm.com> 5 + * 6 + * Platform keystore for pseries LPAR(PLPKS). 7 + */ 8 + 9 + #ifndef _PSERIES_PLPKS_H 10 + #define _PSERIES_PLPKS_H 11 + 12 + #include <linux/types.h> 13 + #include <linux/list.h> 14 + 15 + #define OSSECBOOTAUDIT 0x40000000 16 + #define OSSECBOOTENFORCE 0x20000000 17 + #define WORLDREADABLE 0x08000000 18 + #define SIGNEDUPDATE 0x01000000 19 + 20 + #define PLPKS_VAR_LINUX 0x01 21 + #define PLPKS_VAR_COMMON 0x04 22 + 23 + struct plpks_var { 24 + char *component; 25 + u8 *name; 26 + u8 *data; 27 + u32 policy; 28 + u16 namelen; 29 + u16 datalen; 30 + u8 os; 31 + }; 32 + 33 + struct plpks_var_name { 34 + u8 *name; 35 + u16 namelen; 36 + }; 37 + 38 + struct plpks_var_name_list { 39 + u32 varcount; 40 + struct plpks_var_name varlist[]; 41 + }; 42 + 43 + /** 44 + * Writes the specified var and its data to PKS. 45 + * Any caller of PKS driver should present a valid component type for 46 + * their variable. 47 + */ 48 + int plpks_write_var(struct plpks_var var); 49 + 50 + /** 51 + * Removes the specified var and its data from PKS. 52 + */ 53 + int plpks_remove_var(char *component, u8 varos, 54 + struct plpks_var_name vname); 55 + 56 + /** 57 + * Returns the data for the specified os variable. 58 + */ 59 + int plpks_read_os_var(struct plpks_var *var); 60 + 61 + /** 62 + * Returns the data for the specified firmware variable. 63 + */ 64 + int plpks_read_fw_var(struct plpks_var *var); 65 + 66 + /** 67 + * Returns the data for the specified bootloader variable. 68 + */ 69 + int plpks_read_bootloader_var(struct plpks_var *var); 70 + 71 + #endif
+16 -3
arch/powerpc/platforms/pseries/setup.c
··· 14 14 15 15 #include <linux/cpu.h> 16 16 #include <linux/errno.h> 17 + #include <linux/platform_device.h> 17 18 #include <linux/sched.h> 18 19 #include <linux/kernel.h> 19 20 #include <linux/mm.h> ··· 73 72 #include <asm/svm.h> 74 73 #include <asm/dtl.h> 75 74 #include <asm/hvconsole.h> 75 + #include <asm/setup.h> 76 76 77 77 #include "pseries.h" 78 78 ··· 170 168 } 171 169 #endif 172 170 } 171 + 172 + /* 173 + * Affix a device for the first timer to the platform bus if 174 + * we have firmware support for the H_WATCHDOG hypercall. 175 + */ 176 + static __init int pseries_wdt_init(void) 177 + { 178 + if (firmware_has_feature(FW_FEATURE_WATCHDOG)) 179 + platform_device_register_simple("pseries-wdt", 0, NULL, 0); 180 + return 0; 181 + } 182 + machine_subsys_initcall(pseries, pseries_wdt_init); 173 183 174 184 static void pseries_8259_cascade(struct irq_desc *desc) 175 185 { ··· 816 802 fwnmi_init(); 817 803 818 804 pseries_setup_security_mitigations(); 819 - #ifdef CONFIG_PPC_64S_HASH_MMU 820 - pseries_lpar_read_hblkrm_characteristics(); 821 - #endif 805 + if (!radix_enabled()) 806 + pseries_lpar_read_hblkrm_characteristics(); 822 807 823 808 /* By default, only probe PCI (can be overridden by rtas_pci) */ 824 809 pci_add_flags(PCI_PROBE_ONLY);
+2 -1
arch/powerpc/platforms/pseries/vas.c
··· 16 16 #include <asm/machdep.h> 17 17 #include <asm/hvcall.h> 18 18 #include <asm/plpar_wrappers.h> 19 + #include <asm/firmware.h> 19 20 #include <asm/vas.h> 20 21 #include "vas.h" 21 22 ··· 804 803 * The total number of available credits may be decreased or 805 804 * increased with DLPAR operation. Means some windows have to be 806 805 * closed / reopened. Hold the vas_pseries_mutex so that the 807 - * the user space can not open new windows. 806 + * user space can not open new windows. 808 807 */ 809 808 if (old_nr_creds < new_nr_creds) { 810 809 /*
-1
arch/powerpc/purgatory/.gitignore
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - kexec-purgatory.c 3 2 purgatory.ro
+2 -6
arch/powerpc/purgatory/Makefile
··· 2 2 3 3 KASAN_SANITIZE := n 4 4 5 - targets += trampoline_$(BITS).o purgatory.ro kexec-purgatory.c 5 + targets += trampoline_$(BITS).o purgatory.ro 6 6 7 7 LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined 8 8 9 9 $(obj)/purgatory.ro: $(obj)/trampoline_$(BITS).o FORCE 10 10 $(call if_changed,ld) 11 11 12 - quiet_cmd_bin2c = BIN2C $@ 13 - cmd_bin2c = $(objtree)/scripts/bin2c kexec_purgatory < $< > $@ 14 - 15 - $(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE 16 - $(call if_changed,bin2c) 12 + $(obj)/kexec-purgatory.o: $(obj)/purgatory.ro 17 13 18 14 obj-y += kexec-purgatory.o
+14
arch/powerpc/purgatory/kexec-purgatory.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + .section .rodata, "a" 4 + 5 + .align 8 6 + kexec_purgatory: 7 + .globl kexec_purgatory 8 + .incbin "arch/powerpc/purgatory/purgatory.ro" 9 + .Lkexec_purgatory_end: 10 + 11 + .align 8 12 + kexec_purgatory_size: 13 + .globl kexec_purgatory_size 14 + .quad .Lkexec_purgatory_end - kexec_purgatory
+1 -1
arch/powerpc/sysdev/cpm2.c
··· 107 107 * memory mapped space. 108 108 * The baud rate clock is the system clock divided by something. 109 109 * It was set up long ago during the initial boot phase and is 110 - * is given to us. 110 + * given to us. 111 111 * Baud rate clocks are zero-based in the driver code (as that maps 112 112 * to port numbers). Documentation uses 1-based numbering. 113 113 */
+9
arch/powerpc/sysdev/fsl_pci.c
··· 38 38 #include <asm/disassemble.h> 39 39 #include <asm/ppc-opcode.h> 40 40 #include <asm/swiotlb.h> 41 + #include <asm/setup.h> 41 42 #include <sysdev/fsl_soc.h> 42 43 #include <sysdev/fsl_pci.h> 43 44 ··· 522 521 struct resource rsrc; 523 522 const int *bus_range; 524 523 u8 hdr_type, progif; 524 + u32 class_code; 525 525 struct device_node *dev; 526 526 struct ccsr_pci __iomem *pci; 527 527 u16 temp; ··· 596 594 PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS; 597 595 if (fsl_pcie_check_link(hose)) 598 596 hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; 597 + /* Fix Class Code to PCI_CLASS_BRIDGE_PCI_NORMAL for pre-3.0 controller */ 598 + if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) { 599 + early_read_config_dword(hose, 0, 0, PCIE_FSL_CSR_CLASSCODE, &class_code); 600 + class_code &= 0xff; 601 + class_code |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8; 602 + early_write_config_dword(hose, 0, 0, PCIE_FSL_CSR_CLASSCODE, class_code); 603 + } 599 604 } else { 600 605 /* 601 606 * Set PBFR(PCI Bus Function Register)[10] = 1 to
+1
arch/powerpc/sysdev/fsl_pci.h
··· 18 18 19 19 #define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */ 20 20 #define PCIE_LTSSM_L0 0x16 /* L0 state */ 21 + #define PCIE_FSL_CSR_CLASSCODE 0x474 /* FSL GPEX CSR */ 21 22 #define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */ 22 23 #define PCIE_IP_REV_3_0 0x02080300 /* PCIE IP block version Rev3.0 */ 23 24 #define PIWAR_EN 0x80000000 /* Enable */
+10 -2
arch/powerpc/sysdev/fsl_rio.c
··· 69 69 70 70 static DEFINE_SPINLOCK(fsl_rio_config_lock); 71 71 72 - #define __fsl_read_rio_config(x, addr, err, op) \ 72 + #define ___fsl_read_rio_config(x, addr, err, op, barrier) \ 73 73 __asm__ __volatile__( \ 74 74 "1: "op" %1,0(%2)\n" \ 75 - " eieio\n" \ 75 + " "barrier"\n" \ 76 76 "2:\n" \ 77 77 ".section .fixup,\"ax\"\n" \ 78 78 "3: li %1,-1\n" \ ··· 82 82 EX_TABLE(1b, 3b) \ 83 83 : "=r" (err), "=r" (x) \ 84 84 : "b" (addr), "i" (-EFAULT), "0" (err)) 85 + 86 + #ifdef CONFIG_BOOKE 87 + #define __fsl_read_rio_config(x, addr, err, op) \ 88 + ___fsl_read_rio_config(x, addr, err, op, "mbar") 89 + #else 90 + #define __fsl_read_rio_config(x, addr, err, op) \ 91 + ___fsl_read_rio_config(x, addr, err, op, "eieio") 92 + #endif 85 93 86 94 void __iomem *rio_regs_win; 87 95 void __iomem *rmu_regs_win;
+22 -19
arch/powerpc/sysdev/mpc5xxx_clocks.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 - /** 3 - * mpc5xxx_get_bus_frequency - Find the bus frequency for a device 4 - * @node: device node 5 - * 6 - * Returns bus frequency (IPS on MPC512x, IPB on MPC52xx), 7 - * or 0 if the bus frequency cannot be found. 8 - */ 9 2 10 3 #include <linux/kernel.h> 11 - #include <linux/of_platform.h> 12 4 #include <linux/export.h> 5 + #include <linux/property.h> 6 + 13 7 #include <asm/mpc5xxx.h> 14 8 15 - unsigned long mpc5xxx_get_bus_frequency(struct device_node *node) 9 + /** 10 + * mpc5xxx_fwnode_get_bus_frequency - Find the bus frequency for a firmware node 11 + * @fwnode: firmware node 12 + * 13 + * Returns bus frequency (IPS on MPC512x, IPB on MPC52xx), 14 + * or 0 if the bus frequency cannot be found. 15 + */ 16 + unsigned long mpc5xxx_fwnode_get_bus_frequency(struct fwnode_handle *fwnode) 16 17 { 17 - const unsigned int *p_bus_freq = NULL; 18 + struct fwnode_handle *parent; 19 + u32 bus_freq; 20 + int ret; 18 21 19 - of_node_get(node); 20 - while (node) { 21 - p_bus_freq = of_get_property(node, "bus-frequency", NULL); 22 - if (p_bus_freq) 23 - break; 22 + ret = fwnode_property_read_u32(fwnode, "bus-frequency", &bus_freq); 23 + if (!ret) 24 + return bus_freq; 24 25 25 - node = of_get_next_parent(node); 26 + fwnode_for_each_parent_node(fwnode, parent) { 27 + ret = fwnode_property_read_u32(parent, "bus-frequency", &bus_freq); 28 + if (!ret) 29 + return bus_freq; 26 30 } 27 - of_node_put(node); 28 31 29 - return p_bus_freq ? *p_bus_freq : 0; 32 + return 0; 30 33 } 31 - EXPORT_SYMBOL(mpc5xxx_get_bus_frequency); 34 + EXPORT_SYMBOL(mpc5xxx_fwnode_get_bus_frequency);
+2
arch/powerpc/sysdev/of_rtc.c
··· 11 11 #include <linux/of_platform.h> 12 12 #include <linux/slab.h> 13 13 14 + #include <asm/prom.h> 15 + 14 16 static __initdata struct { 15 17 const char *compatible; 16 18 char *plat_name;
+1
arch/powerpc/sysdev/xive/spapr.c
··· 718 718 } 719 719 720 720 reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len); 721 + of_node_put(rootdn); 721 722 if (!reg) { 722 723 pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n"); 723 724 return false;
+2 -2
arch/powerpc/xmon/xmon.c
··· 116 116 static struct bpt bpts[NBPTS]; 117 117 static struct bpt dabr[HBP_NUM_MAX]; 118 118 static struct bpt *iabr; 119 - static unsigned bpinstr = 0x7fe00008; /* trap */ 119 + static unsigned int bpinstr = PPC_RAW_TRAP(); 120 120 121 121 #define BP_NUM(bp) ((bp) - bpts + 1) 122 122 ··· 3047 3047 dotted = 0; 3048 3048 last_inst = inst; 3049 3049 if (praddr) 3050 - printf(REG" %s", adr, ppc_inst_as_str(inst)); 3050 + printf(REG" %08lx", adr, ppc_inst_as_ulong(inst)); 3051 3051 printf("\t"); 3052 3052 if (!ppc_inst_prefixed(inst)) 3053 3053 dump_func(ppc_inst_val(inst), adr);
+1 -1
drivers/ata/pata_mpc52xx.c
··· 683 683 struct bcom_task *dmatsk; 684 684 685 685 /* Get ipb frequency */ 686 - ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); 686 + ipb_freq = mpc5xxx_get_bus_frequency(&op->dev); 687 687 if (!ipb_freq) { 688 688 dev_err(&op->dev, "could not determine IPB bus frequency\n"); 689 689 return -ENODEV;
+1 -1
drivers/char/hw_random/powernv-rng.c
··· 23 23 buf = (unsigned long *)data; 24 24 25 25 for (i = 0; i < len; i++) 26 - powernv_get_random_long(buf++); 26 + pnv_get_random_long(buf++); 27 27 28 28 return len * sizeof(unsigned long); 29 29 }
+2
drivers/edac/mpc85xx_edac.c
··· 24 24 25 25 #include <linux/of_platform.h> 26 26 #include <linux/of_device.h> 27 + #include <linux/of_address.h> 28 + #include <linux/of_irq.h> 27 29 #include "edac_module.h" 28 30 #include "mpc85xx_edac.h" 29 31 #include "fsl_ddr_edac.h"
+1
drivers/edac/ppc4xx_edac.c
··· 11 11 #include <linux/mm.h> 12 12 #include <linux/module.h> 13 13 #include <linux/of_device.h> 14 + #include <linux/of_irq.h> 14 15 #include <linux/of_platform.h> 15 16 #include <linux/types.h> 16 17
+4 -3
drivers/i2c/busses/i2c-mpc.c
··· 239 239 static int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, 240 240 u32 *real_clk) 241 241 { 242 + struct fwnode_handle *fwnode = of_fwnode_handle(node); 242 243 const struct mpc_i2c_divider *div = NULL; 243 244 unsigned int pvr = mfspr(SPRN_PVR); 244 245 u32 divider; ··· 247 246 248 247 if (clock == MPC_I2C_CLOCK_LEGACY) { 249 248 /* see below - default fdr = 0x3f -> div = 2048 */ 250 - *real_clk = mpc5xxx_get_bus_frequency(node) / 2048; 249 + *real_clk = mpc5xxx_fwnode_get_bus_frequency(fwnode) / 2048; 251 250 return -EINVAL; 252 251 } 253 252 254 253 /* Determine divider value */ 255 - divider = mpc5xxx_get_bus_frequency(node) / clock; 254 + divider = mpc5xxx_fwnode_get_bus_frequency(fwnode) / clock; 256 255 257 256 /* 258 257 * We want to choose an FDR/DFSR that generates an I2C bus speed that ··· 267 266 break; 268 267 } 269 268 270 - *real_clk = mpc5xxx_get_bus_frequency(node) / div->divider; 269 + *real_clk = mpc5xxx_fwnode_get_bus_frequency(fwnode) / div->divider; 271 270 return (int)div->fdr; 272 271 } 273 272
+1 -1
drivers/macintosh/adb.c
··· 647 647 648 648 switch(req->data[1]) { 649 649 case ADB_QUERY_GETDEVINFO: 650 - if (req->nbytes < 3) 650 + if (req->nbytes < 3 || req->data[2] >= 16) 651 651 break; 652 652 mutex_lock(&adb_handler_mutex); 653 653 req->reply[0] = adb_handler[req->data[2]].original_address;
+1 -1
drivers/net/can/mscan/mpc5xxx_can.c
··· 63 63 else 64 64 *mscan_clksrc = MSCAN_CLKSRC_XTAL; 65 65 66 - freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); 66 + freq = mpc5xxx_get_bus_frequency(&ofdev->dev); 67 67 if (!freq) 68 68 return 0; 69 69
+1 -1
drivers/net/ethernet/freescale/fec_mpc52xx.c
··· 924 924 /* Start with safe defaults for link connection */ 925 925 priv->speed = 100; 926 926 priv->duplex = DUPLEX_HALF; 927 - priv->mdio_speed = ((mpc5xxx_get_bus_frequency(np) >> 20) / 5) << 1; 927 + priv->mdio_speed = ((mpc5xxx_get_bus_frequency(&op->dev) >> 20) / 5) << 1; 928 928 929 929 /* The current speed preconfigures the speed of the MII link */ 930 930 prop = of_get_property(np, "current-speed", &prop_size);
+1 -2
drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
··· 100 100 dev_set_drvdata(dev, bus); 101 101 102 102 /* set MII speed */ 103 - out_be32(&priv->regs->mii_speed, 104 - ((mpc5xxx_get_bus_frequency(of->dev.of_node) >> 20) / 5) << 1); 103 + out_be32(&priv->regs->mii_speed, ((mpc5xxx_get_bus_frequency(dev) >> 20) / 5) << 1); 105 104 106 105 err = of_mdiobus_register(bus, np); 107 106 if (err)
+2 -2
drivers/net/ethernet/freescale/fs_enet/mii-fec.c
··· 102 102 struct resource res; 103 103 struct mii_bus *new_bus; 104 104 struct fec_info *fec; 105 - int (*get_bus_freq)(struct device_node *); 105 + int (*get_bus_freq)(struct device *); 106 106 int ret = -ENOMEM, clock, speed; 107 107 108 108 match = of_match_device(fs_enet_mdio_fec_match, &ofdev->dev); ··· 136 136 } 137 137 138 138 if (get_bus_freq) { 139 - clock = get_bus_freq(ofdev->dev.of_node); 139 + clock = get_bus_freq(&ofdev->dev); 140 140 if (!clock) { 141 141 /* Use maximum divider if clock is unknown */ 142 142 dev_warn(&ofdev->dev, "could not determine IPS clock\n");
+1
drivers/scsi/cxlflash/ocxl_hw.c
··· 16 16 #include <linux/poll.h> 17 17 #include <linux/sched/signal.h> 18 18 #include <linux/interrupt.h> 19 + #include <linux/irqdomain.h> 19 20 #include <asm/xive.h> 20 21 #include <misc/ocxl.h> 21 22
+1 -6
drivers/scsi/mesh.c
··· 38 38 #include <asm/irq.h> 39 39 #include <asm/hydra.h> 40 40 #include <asm/processor.h> 41 - #include <asm/machdep.h> 41 + #include <asm/setup.h> 42 42 #include <asm/pmac_feature.h> 43 43 #include <asm/macio.h> 44 44 ··· 1882 1882 goto out_release; 1883 1883 } 1884 1884 1885 - /* Old junk for root discovery, that will die ultimately */ 1886 - #if !defined(MODULE) 1887 - note_scsi_host(mesh, mesh_host); 1888 - #endif 1889 - 1890 1885 mesh_host->base = macio_resource_start(mdev, 0); 1891 1886 mesh_host->irq = macio_irq(mdev, 0); 1892 1887 ms = (struct mesh_state *) mesh_host->hostdata;
+1 -1
drivers/spi/spi-mpc52xx.c
··· 437 437 ms->irq0 = irq_of_parse_and_map(op->dev.of_node, 0); 438 438 ms->irq1 = irq_of_parse_and_map(op->dev.of_node, 1); 439 439 ms->state = mpc52xx_spi_fsmstate_idle; 440 - ms->ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); 440 + ms->ipb_freq = mpc5xxx_get_bus_frequency(&op->dev); 441 441 ms->gpio_cs_count = of_gpio_count(op->dev.of_node); 442 442 if (ms->gpio_cs_count > 0) { 443 443 master->num_chipselect = ms->gpio_cs_count;
+2 -2
drivers/tty/serial/mpc52xx_uart.c
··· 1630 1630 return ret; 1631 1631 } 1632 1632 1633 - uartclk = mpc5xxx_get_bus_frequency(np); 1633 + uartclk = mpc5xxx_fwnode_get_bus_frequency(of_fwnode_handle(np)); 1634 1634 if (uartclk == 0) { 1635 1635 pr_debug("Could not find uart clock frequency!\n"); 1636 1636 return -EINVAL; ··· 1747 1747 /* set the uart clock to the input clock of the psc, the different 1748 1748 * prescalers are taken into account in the set_baudrate() methods 1749 1749 * of the respective chip */ 1750 - uartclk = mpc5xxx_get_bus_frequency(op->dev.of_node); 1750 + uartclk = mpc5xxx_get_bus_frequency(&op->dev); 1751 1751 if (uartclk == 0) { 1752 1752 dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); 1753 1753 return -EINVAL;
+1
drivers/video/fbdev/offb.c
··· 26 26 #include <linux/init.h> 27 27 #include <linux/ioport.h> 28 28 #include <linux/pci.h> 29 + #include <linux/platform_device.h> 29 30 #include <asm/io.h> 30 31 31 32 #ifdef CONFIG_PPC32
+8
drivers/watchdog/Kconfig
··· 1963 1963 1964 1964 # PPC64 Architecture 1965 1965 1966 + config PSERIES_WDT 1967 + tristate "POWER Architecture Platform Watchdog Timer" 1968 + depends on PPC_PSERIES 1969 + select WATCHDOG_CORE 1970 + help 1971 + Driver for virtual watchdog timers provided by PAPR 1972 + hypervisors (e.g. PowerVM, KVM). 1973 + 1966 1974 config WATCHDOG_RTAS 1967 1975 tristate "RTAS watchdog" 1968 1976 depends on PPC_RTAS
+1
drivers/watchdog/Makefile
··· 187 187 obj-$(CONFIG_MEN_A21_WDT) += mena21_wdt.o 188 188 189 189 # PPC64 Architecture 190 + obj-$(CONFIG_PSERIES_WDT) += pseries-wdt.o 190 191 obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o 191 192 192 193 # S390 Architecture
+239
drivers/watchdog/pseries-wdt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (c) 2022 International Business Machines, Inc. 4 + */ 5 + 6 + #include <linux/bitops.h> 7 + #include <linux/kernel.h> 8 + #include <linux/limits.h> 9 + #include <linux/math.h> 10 + #include <linux/mod_devicetable.h> 11 + #include <linux/module.h> 12 + #include <linux/moduleparam.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/time64.h> 15 + #include <linux/watchdog.h> 16 + 17 + #define DRV_NAME "pseries-wdt" 18 + 19 + /* 20 + * H_WATCHDOG Input 21 + * 22 + * R4: "flags": 23 + * 24 + * Bits 48-55: "operation" 25 + */ 26 + #define PSERIES_WDTF_OP_START 0x100UL /* start timer */ 27 + #define PSERIES_WDTF_OP_STOP 0x200UL /* stop timer */ 28 + #define PSERIES_WDTF_OP_QUERY 0x300UL /* query timer capabilities */ 29 + 30 + /* 31 + * Bits 56-63: "timeoutAction" (for "Start Watchdog" only) 32 + */ 33 + #define PSERIES_WDTF_ACTION_HARD_POWEROFF 0x1UL /* poweroff */ 34 + #define PSERIES_WDTF_ACTION_HARD_RESTART 0x2UL /* restart */ 35 + #define PSERIES_WDTF_ACTION_DUMP_RESTART 0x3UL /* dump + restart */ 36 + 37 + /* 38 + * H_WATCHDOG Output 39 + * 40 + * R3: Return code 41 + * 42 + * H_SUCCESS The operation completed. 43 + * 44 + * H_BUSY The hypervisor is too busy; retry the operation. 45 + * 46 + * H_PARAMETER The given "flags" are somehow invalid. Either the 47 + * "operation" or "timeoutAction" is invalid, or a 48 + * reserved bit is set. 49 + * 50 + * H_P2 The given "watchdogNumber" is zero or exceeds the 51 + * supported maximum value. 52 + * 53 + * H_P3 The given "timeoutInMs" is below the supported 54 + * minimum value. 55 + * 56 + * H_NOOP The given "watchdogNumber" is already stopped. 57 + * 58 + * H_HARDWARE The operation failed for ineffable reasons. 59 + * 60 + * H_FUNCTION The H_WATCHDOG hypercall is not supported by this 61 + * hypervisor. 62 + * 63 + * R4: 64 + * 65 + * - For the "Query Watchdog Capabilities" operation, a 64-bit 66 + * structure: 67 + */ 68 + #define PSERIES_WDTQ_MIN_TIMEOUT(cap) (((cap) >> 48) & 0xffff) 69 + #define PSERIES_WDTQ_MAX_NUMBER(cap) (((cap) >> 32) & 0xffff) 70 + 71 + static const unsigned long pseries_wdt_action[] = { 72 + [0] = PSERIES_WDTF_ACTION_HARD_POWEROFF, 73 + [1] = PSERIES_WDTF_ACTION_HARD_RESTART, 74 + [2] = PSERIES_WDTF_ACTION_DUMP_RESTART, 75 + }; 76 + 77 + #define WATCHDOG_ACTION 1 78 + static unsigned int action = WATCHDOG_ACTION; 79 + module_param(action, uint, 0444); 80 + MODULE_PARM_DESC(action, "Action taken when watchdog expires (default=" 81 + __MODULE_STRING(WATCHDOG_ACTION) ")"); 82 + 83 + static bool nowayout = WATCHDOG_NOWAYOUT; 84 + module_param(nowayout, bool, 0444); 85 + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 86 + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 87 + 88 + #define WATCHDOG_TIMEOUT 60 89 + static unsigned int timeout = WATCHDOG_TIMEOUT; 90 + module_param(timeout, uint, 0444); 91 + MODULE_PARM_DESC(timeout, "Initial watchdog timeout in seconds (default=" 92 + __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 93 + 94 + struct pseries_wdt { 95 + struct watchdog_device wd; 96 + unsigned long action; 97 + unsigned long num; /* Watchdog numbers are 1-based */ 98 + }; 99 + 100 + static int pseries_wdt_start(struct watchdog_device *wdd) 101 + { 102 + struct pseries_wdt *pw = watchdog_get_drvdata(wdd); 103 + struct device *dev = wdd->parent; 104 + unsigned long flags, msecs; 105 + long rc; 106 + 107 + flags = pw->action | PSERIES_WDTF_OP_START; 108 + msecs = wdd->timeout * MSEC_PER_SEC; 109 + rc = plpar_hcall_norets(H_WATCHDOG, flags, pw->num, msecs); 110 + if (rc != H_SUCCESS) { 111 + dev_crit(dev, "H_WATCHDOG: %ld: failed to start timer %lu", 112 + rc, pw->num); 113 + return -EIO; 114 + } 115 + return 0; 116 + } 117 + 118 + static int pseries_wdt_stop(struct watchdog_device *wdd) 119 + { 120 + struct pseries_wdt *pw = watchdog_get_drvdata(wdd); 121 + struct device *dev = wdd->parent; 122 + long rc; 123 + 124 + rc = plpar_hcall_norets(H_WATCHDOG, PSERIES_WDTF_OP_STOP, pw->num); 125 + if (rc != H_SUCCESS && rc != H_NOOP) { 126 + dev_crit(dev, "H_WATCHDOG: %ld: failed to stop timer %lu", 127 + rc, pw->num); 128 + return -EIO; 129 + } 130 + return 0; 131 + } 132 + 133 + static struct watchdog_info pseries_wdt_info = { 134 + .identity = DRV_NAME, 135 + .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT 136 + | WDIOF_PRETIMEOUT, 137 + }; 138 + 139 + static const struct watchdog_ops pseries_wdt_ops = { 140 + .owner = THIS_MODULE, 141 + .start = pseries_wdt_start, 142 + .stop = pseries_wdt_stop, 143 + }; 144 + 145 + static int pseries_wdt_probe(struct platform_device *pdev) 146 + { 147 + unsigned long ret[PLPAR_HCALL_BUFSIZE] = { 0 }; 148 + struct pseries_wdt *pw; 149 + unsigned long cap; 150 + long msecs, rc; 151 + int err; 152 + 153 + rc = plpar_hcall(H_WATCHDOG, ret, PSERIES_WDTF_OP_QUERY); 154 + if (rc == H_FUNCTION) 155 + return -ENODEV; 156 + if (rc != H_SUCCESS) 157 + return -EIO; 158 + cap = ret[0]; 159 + 160 + pw = devm_kzalloc(&pdev->dev, sizeof(*pw), GFP_KERNEL); 161 + if (!pw) 162 + return -ENOMEM; 163 + 164 + /* 165 + * Assume watchdogNumber 1 for now. If we ever support 166 + * multiple timers we will need to devise a way to choose a 167 + * distinct watchdogNumber for each platform device at device 168 + * registration time. 169 + */ 170 + pw->num = 1; 171 + if (PSERIES_WDTQ_MAX_NUMBER(cap) < pw->num) 172 + return -ENODEV; 173 + 174 + if (action >= ARRAY_SIZE(pseries_wdt_action)) 175 + return -EINVAL; 176 + pw->action = pseries_wdt_action[action]; 177 + 178 + pw->wd.parent = &pdev->dev; 179 + pw->wd.info = &pseries_wdt_info; 180 + pw->wd.ops = &pseries_wdt_ops; 181 + msecs = PSERIES_WDTQ_MIN_TIMEOUT(cap); 182 + pw->wd.min_timeout = DIV_ROUND_UP(msecs, MSEC_PER_SEC); 183 + pw->wd.max_timeout = UINT_MAX / 1000; /* from linux/watchdog.h */ 184 + pw->wd.timeout = timeout; 185 + if (watchdog_init_timeout(&pw->wd, 0, NULL)) 186 + return -EINVAL; 187 + watchdog_set_nowayout(&pw->wd, nowayout); 188 + watchdog_stop_on_reboot(&pw->wd); 189 + watchdog_stop_on_unregister(&pw->wd); 190 + watchdog_set_drvdata(&pw->wd, pw); 191 + 192 + err = devm_watchdog_register_device(&pdev->dev, &pw->wd); 193 + if (err) 194 + return err; 195 + 196 + platform_set_drvdata(pdev, &pw->wd); 197 + 198 + return 0; 199 + } 200 + 201 + static int pseries_wdt_suspend(struct platform_device *pdev, pm_message_t state) 202 + { 203 + struct watchdog_device *wd = platform_get_drvdata(pdev); 204 + 205 + if (watchdog_active(wd)) 206 + return pseries_wdt_stop(wd); 207 + return 0; 208 + } 209 + 210 + static int pseries_wdt_resume(struct platform_device *pdev) 211 + { 212 + struct watchdog_device *wd = platform_get_drvdata(pdev); 213 + 214 + if (watchdog_active(wd)) 215 + return pseries_wdt_start(wd); 216 + return 0; 217 + } 218 + 219 + static const struct platform_device_id pseries_wdt_id[] = { 220 + { .name = "pseries-wdt" }, 221 + {} 222 + }; 223 + MODULE_DEVICE_TABLE(platform, pseries_wdt_id); 224 + 225 + static struct platform_driver pseries_wdt_driver = { 226 + .driver = { 227 + .name = DRV_NAME, 228 + }, 229 + .id_table = pseries_wdt_id, 230 + .probe = pseries_wdt_probe, 231 + .resume = pseries_wdt_resume, 232 + .suspend = pseries_wdt_suspend, 233 + }; 234 + module_platform_driver(pseries_wdt_driver); 235 + 236 + MODULE_AUTHOR("Alexey Kardashevskiy"); 237 + MODULE_AUTHOR("Scott Cheloha"); 238 + MODULE_DESCRIPTION("POWER Architecture Platform Watchdog Driver"); 239 + MODULE_LICENSE("GPL");
+2
include/linux/nmi.h
··· 122 122 int watchdog_nmi_enable(unsigned int cpu); 123 123 void watchdog_nmi_disable(unsigned int cpu); 124 124 125 + void lockup_detector_reconfigure(void); 126 + 125 127 /** 126 128 * touch_nmi_watchdog - restart NMI watchdog timeout. 127 129 *
+16 -5
kernel/watchdog.c
··· 537 537 return 0; 538 538 } 539 539 540 - static void lockup_detector_reconfigure(void) 540 + static void __lockup_detector_reconfigure(void) 541 541 { 542 542 cpus_read_lock(); 543 543 watchdog_nmi_stop(); ··· 557 557 __lockup_detector_cleanup(); 558 558 } 559 559 560 + void lockup_detector_reconfigure(void) 561 + { 562 + mutex_lock(&watchdog_mutex); 563 + __lockup_detector_reconfigure(); 564 + mutex_unlock(&watchdog_mutex); 565 + } 566 + 560 567 /* 561 568 * Create the watchdog infrastructure and configure the detector(s). 562 569 */ ··· 580 573 return; 581 574 582 575 mutex_lock(&watchdog_mutex); 583 - lockup_detector_reconfigure(); 576 + __lockup_detector_reconfigure(); 584 577 softlockup_initialized = true; 585 578 mutex_unlock(&watchdog_mutex); 586 579 } 587 580 588 581 #else /* CONFIG_SOFTLOCKUP_DETECTOR */ 589 - static void lockup_detector_reconfigure(void) 582 + static void __lockup_detector_reconfigure(void) 590 583 { 591 584 cpus_read_lock(); 592 585 watchdog_nmi_stop(); ··· 594 587 watchdog_nmi_start(); 595 588 cpus_read_unlock(); 596 589 } 590 + void lockup_detector_reconfigure(void) 591 + { 592 + __lockup_detector_reconfigure(); 593 + } 597 594 static inline void lockup_detector_setup(void) 598 595 { 599 - lockup_detector_reconfigure(); 596 + __lockup_detector_reconfigure(); 600 597 } 601 598 #endif /* !CONFIG_SOFTLOCKUP_DETECTOR */ 602 599 ··· 640 629 { 641 630 /* Remove impossible cpus to keep sysctl output clean. */ 642 631 cpumask_and(&watchdog_cpumask, &watchdog_cpumask, cpu_possible_mask); 643 - lockup_detector_reconfigure(); 632 + __lockup_detector_reconfigure(); 644 633 } 645 634 646 635 /*
+2
scripts/remove-stale-files
··· 20 20 # yard. Stale files stay in this file for a while (for some release cycles?), 21 21 # then will be really dead and removed from the code base entirely. 22 22 23 + rm -f arch/powerpc/purgatory/kexec-purgatory.c 24 + 23 25 # These were previously generated source files. When you are building the kernel 24 26 # with O=, make sure to remove the stale files in the output tree. Otherwise, 25 27 # the build system wrongly compiles the stale ones.
+47 -16
tools/testing/selftests/powerpc/include/basic_asm.h
··· 5 5 #include <ppc-asm.h> 6 6 #include <asm/unistd.h> 7 7 8 + #ifdef __powerpc64__ 9 + #define PPC_LL ld 10 + #define PPC_STL std 11 + #define PPC_STLU stdu 12 + #else 13 + #define PPC_LL lwz 14 + #define PPC_STL stw 15 + #define PPC_STLU stwu 16 + #endif 17 + 8 18 #define LOAD_REG_IMMEDIATE(reg, expr) \ 9 19 lis reg, (expr)@highest; \ 10 20 ori reg, reg, (expr)@higher; \ ··· 24 14 25 15 /* 26 16 * Note: These macros assume that variables being stored on the stack are 27 - * doublewords, while this is usually the case it may not always be the 17 + * sizeof(long), while this is usually the case it may not always be the 28 18 * case for each use case. 29 19 */ 20 + #ifdef __powerpc64__ 21 + 22 + // ABIv2 30 23 #if defined(_CALL_ELF) && _CALL_ELF == 2 31 24 #define STACK_FRAME_MIN_SIZE 32 32 25 #define STACK_FRAME_TOC_POS 24 33 26 #define __STACK_FRAME_PARAM(_param) (32 + ((_param)*8)) 34 27 #define __STACK_FRAME_LOCAL(_num_params, _var_num) \ 35 28 ((STACK_FRAME_PARAM(_num_params)) + ((_var_num)*8)) 36 - #else 29 + 30 + #else // ABIv1 below 37 31 #define STACK_FRAME_MIN_SIZE 112 38 32 #define STACK_FRAME_TOC_POS 40 39 33 #define __STACK_FRAME_PARAM(i) (48 + ((i)*8)) ··· 48 34 */ 49 35 #define __STACK_FRAME_LOCAL(_num_params, _var_num) \ 50 36 (112 + ((_var_num)*8)) 51 - #endif 37 + 38 + 39 + #endif // ABIv2 40 + 41 + // Common 64-bit 42 + #define STACK_FRAME_LR_POS 16 43 + #define STACK_FRAME_CR_POS 8 44 + 45 + #else // 32-bit below 46 + 47 + #define STACK_FRAME_MIN_SIZE 16 48 + #define STACK_FRAME_LR_POS 4 49 + 50 + #define __STACK_FRAME_PARAM(_param) (STACK_FRAME_MIN_SIZE + ((_param)*4)) 51 + #define __STACK_FRAME_LOCAL(_num_params, _var_num) \ 52 + ((STACK_FRAME_PARAM(_num_params)) + ((_var_num)*4)) 53 + 54 + #endif // __powerpc64__ 52 55 53 56 /* Parameter x saved to the stack */ 54 57 #define STACK_FRAME_PARAM(var) __STACK_FRAME_PARAM(var) ··· 73 42 /* Local variable x saved to the stack after x parameters */ 74 43 #define STACK_FRAME_LOCAL(num_params, var) \ 75 44 __STACK_FRAME_LOCAL(num_params, var) 76 - #define STACK_FRAME_LR_POS 16 77 - #define STACK_FRAME_CR_POS 8 78 45 79 46 /* 80 47 * It is very important to note here that _extra is the extra amount of ··· 85 56 * preprocessed incorrectly, hence r0. 86 57 */ 87 58 #define PUSH_BASIC_STACK(_extra) \ 88 - mflr r0; \ 89 - std r0, STACK_FRAME_LR_POS(%r1); \ 90 - stdu %r1, -(_extra + STACK_FRAME_MIN_SIZE)(%r1); \ 91 - mfcr r0; \ 92 - stw r0, STACK_FRAME_CR_POS(%r1); \ 93 - std %r2, STACK_FRAME_TOC_POS(%r1); 59 + mflr r0; \ 60 + PPC_STL r0, STACK_FRAME_LR_POS(%r1); \ 61 + PPC_STLU %r1, -(((_extra + 15) & ~15) + STACK_FRAME_MIN_SIZE)(%r1); 94 62 95 63 #define POP_BASIC_STACK(_extra) \ 96 - ld %r2, STACK_FRAME_TOC_POS(%r1); \ 97 - lwz r0, STACK_FRAME_CR_POS(%r1); \ 98 - mtcr r0; \ 99 - addi %r1, %r1, (_extra + STACK_FRAME_MIN_SIZE); \ 100 - ld r0, STACK_FRAME_LR_POS(%r1); \ 64 + addi %r1, %r1, (((_extra + 15) & ~15) + STACK_FRAME_MIN_SIZE); \ 65 + PPC_LL r0, STACK_FRAME_LR_POS(%r1); \ 101 66 mtlr r0; 67 + 68 + .macro OP_REGS op, reg_width, start_reg, end_reg, base_reg, base_reg_offset=0, skip=0 69 + .set i, \start_reg 70 + .rept (\end_reg - \start_reg + 1) 71 + \op i, (\reg_width * (i - \skip) + \base_reg_offset)(\base_reg) 72 + .set i, i + 1 73 + .endr 74 + .endm 102 75 103 76 #endif /* _SELFTESTS_POWERPC_BASIC_ASM_H */
+38 -35
tools/testing/selftests/powerpc/include/reg.h
··· 55 55 #define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) 56 56 #define SPRN_PVR 0x11F 57 57 58 + #define PVR_CFG(pvr) (((pvr) >> 8) & 0xF) /* Configuration field */ 59 + #define PVR_MAJ(pvr) (((pvr) >> 4) & 0xF) /* Major revision field */ 60 + #define PVR_MIN(pvr) (((pvr) >> 0) & 0xF) /* Minor revision field */ 61 + 58 62 #define SPRN_DSCR_PRIV 0x11 /* Privilege State DSCR */ 59 63 #define SPRN_DSCR 0x03 /* Data Stream Control Register */ 60 64 #define SPRN_PPR 896 /* Program Priority Register */ ··· 127 123 "li 30, %[" #_asm_symbol_name_immed "];" \ 128 124 "li 31, %[" #_asm_symbol_name_immed "];" 129 125 130 - #define ASM_LOAD_FPR_SINGLE_PRECISION(_asm_symbol_name_addr) \ 131 - "lfs 0, 0(%[" #_asm_symbol_name_addr "]);" \ 132 - "lfs 1, 0(%[" #_asm_symbol_name_addr "]);" \ 133 - "lfs 2, 0(%[" #_asm_symbol_name_addr "]);" \ 134 - "lfs 3, 0(%[" #_asm_symbol_name_addr "]);" \ 135 - "lfs 4, 0(%[" #_asm_symbol_name_addr "]);" \ 136 - "lfs 5, 0(%[" #_asm_symbol_name_addr "]);" \ 137 - "lfs 6, 0(%[" #_asm_symbol_name_addr "]);" \ 138 - "lfs 7, 0(%[" #_asm_symbol_name_addr "]);" \ 139 - "lfs 8, 0(%[" #_asm_symbol_name_addr "]);" \ 140 - "lfs 9, 0(%[" #_asm_symbol_name_addr "]);" \ 141 - "lfs 10, 0(%[" #_asm_symbol_name_addr "]);" \ 142 - "lfs 11, 0(%[" #_asm_symbol_name_addr "]);" \ 143 - "lfs 12, 0(%[" #_asm_symbol_name_addr "]);" \ 144 - "lfs 13, 0(%[" #_asm_symbol_name_addr "]);" \ 145 - "lfs 14, 0(%[" #_asm_symbol_name_addr "]);" \ 146 - "lfs 15, 0(%[" #_asm_symbol_name_addr "]);" \ 147 - "lfs 16, 0(%[" #_asm_symbol_name_addr "]);" \ 148 - "lfs 17, 0(%[" #_asm_symbol_name_addr "]);" \ 149 - "lfs 18, 0(%[" #_asm_symbol_name_addr "]);" \ 150 - "lfs 19, 0(%[" #_asm_symbol_name_addr "]);" \ 151 - "lfs 20, 0(%[" #_asm_symbol_name_addr "]);" \ 152 - "lfs 21, 0(%[" #_asm_symbol_name_addr "]);" \ 153 - "lfs 22, 0(%[" #_asm_symbol_name_addr "]);" \ 154 - "lfs 23, 0(%[" #_asm_symbol_name_addr "]);" \ 155 - "lfs 24, 0(%[" #_asm_symbol_name_addr "]);" \ 156 - "lfs 25, 0(%[" #_asm_symbol_name_addr "]);" \ 157 - "lfs 26, 0(%[" #_asm_symbol_name_addr "]);" \ 158 - "lfs 27, 0(%[" #_asm_symbol_name_addr "]);" \ 159 - "lfs 28, 0(%[" #_asm_symbol_name_addr "]);" \ 160 - "lfs 29, 0(%[" #_asm_symbol_name_addr "]);" \ 161 - "lfs 30, 0(%[" #_asm_symbol_name_addr "]);" \ 162 - "lfs 31, 0(%[" #_asm_symbol_name_addr "]);" 126 + #define ASM_LOAD_FPR(_asm_symbol_name_addr) \ 127 + "lfd 0, 0(%[" #_asm_symbol_name_addr "]);" \ 128 + "lfd 1, 0(%[" #_asm_symbol_name_addr "]);" \ 129 + "lfd 2, 0(%[" #_asm_symbol_name_addr "]);" \ 130 + "lfd 3, 0(%[" #_asm_symbol_name_addr "]);" \ 131 + "lfd 4, 0(%[" #_asm_symbol_name_addr "]);" \ 132 + "lfd 5, 0(%[" #_asm_symbol_name_addr "]);" \ 133 + "lfd 6, 0(%[" #_asm_symbol_name_addr "]);" \ 134 + "lfd 7, 0(%[" #_asm_symbol_name_addr "]);" \ 135 + "lfd 8, 0(%[" #_asm_symbol_name_addr "]);" \ 136 + "lfd 9, 0(%[" #_asm_symbol_name_addr "]);" \ 137 + "lfd 10, 0(%[" #_asm_symbol_name_addr "]);" \ 138 + "lfd 11, 0(%[" #_asm_symbol_name_addr "]);" \ 139 + "lfd 12, 0(%[" #_asm_symbol_name_addr "]);" \ 140 + "lfd 13, 0(%[" #_asm_symbol_name_addr "]);" \ 141 + "lfd 14, 0(%[" #_asm_symbol_name_addr "]);" \ 142 + "lfd 15, 0(%[" #_asm_symbol_name_addr "]);" \ 143 + "lfd 16, 0(%[" #_asm_symbol_name_addr "]);" \ 144 + "lfd 17, 0(%[" #_asm_symbol_name_addr "]);" \ 145 + "lfd 18, 0(%[" #_asm_symbol_name_addr "]);" \ 146 + "lfd 19, 0(%[" #_asm_symbol_name_addr "]);" \ 147 + "lfd 20, 0(%[" #_asm_symbol_name_addr "]);" \ 148 + "lfd 21, 0(%[" #_asm_symbol_name_addr "]);" \ 149 + "lfd 22, 0(%[" #_asm_symbol_name_addr "]);" \ 150 + "lfd 23, 0(%[" #_asm_symbol_name_addr "]);" \ 151 + "lfd 24, 0(%[" #_asm_symbol_name_addr "]);" \ 152 + "lfd 25, 0(%[" #_asm_symbol_name_addr "]);" \ 153 + "lfd 26, 0(%[" #_asm_symbol_name_addr "]);" \ 154 + "lfd 27, 0(%[" #_asm_symbol_name_addr "]);" \ 155 + "lfd 28, 0(%[" #_asm_symbol_name_addr "]);" \ 156 + "lfd 29, 0(%[" #_asm_symbol_name_addr "]);" \ 157 + "lfd 30, 0(%[" #_asm_symbol_name_addr "]);" \ 158 + "lfd 31, 0(%[" #_asm_symbol_name_addr "]);" 163 159 164 160 #ifndef __ASSEMBLER__ 165 161 void store_gpr(unsigned long *addr); 166 162 void load_gpr(unsigned long *addr); 167 - void load_fpr_single_precision(float *addr); 168 - void store_fpr_single_precision(float *addr); 163 + void store_fpr(double *addr); 169 164 #endif /* end of __ASSEMBLER__ */ 170 165 171 166 #endif /* _SELFTESTS_POWERPC_REG_H */
+10
tools/testing/selftests/powerpc/include/utils.h
··· 74 74 } 75 75 #endif 76 76 77 + static inline char *auxv_base_platform(void) 78 + { 79 + return ((char *)get_auxv_entry(AT_BASE_PLATFORM)); 80 + } 81 + 82 + static inline char *auxv_platform(void) 83 + { 84 + return ((char *)get_auxv_entry(AT_PLATFORM)); 85 + } 86 + 77 87 bool is_ppc64le(void); 78 88 int using_hash_mmu(bool *using_hash); 79 89
+35 -72
tools/testing/selftests/powerpc/lib/reg.S
··· 53 53 blr 54 54 FUNC_END(store_gpr) 55 55 56 - /* Single Precision Float - float buf[32] */ 57 - FUNC_START(load_fpr_single_precision) 58 - lfs 0, 0*4(3) 59 - lfs 1, 1*4(3) 60 - lfs 2, 2*4(3) 61 - lfs 3, 3*4(3) 62 - lfs 4, 4*4(3) 63 - lfs 5, 5*4(3) 64 - lfs 6, 6*4(3) 65 - lfs 7, 7*4(3) 66 - lfs 8, 8*4(3) 67 - lfs 9, 9*4(3) 68 - lfs 10, 10*4(3) 69 - lfs 11, 11*4(3) 70 - lfs 12, 12*4(3) 71 - lfs 13, 13*4(3) 72 - lfs 14, 14*4(3) 73 - lfs 15, 15*4(3) 74 - lfs 16, 16*4(3) 75 - lfs 17, 17*4(3) 76 - lfs 18, 18*4(3) 77 - lfs 19, 19*4(3) 78 - lfs 20, 20*4(3) 79 - lfs 21, 21*4(3) 80 - lfs 22, 22*4(3) 81 - lfs 23, 23*4(3) 82 - lfs 24, 24*4(3) 83 - lfs 25, 25*4(3) 84 - lfs 26, 26*4(3) 85 - lfs 27, 27*4(3) 86 - lfs 28, 28*4(3) 87 - lfs 29, 29*4(3) 88 - lfs 30, 30*4(3) 89 - lfs 31, 31*4(3) 56 + /* Double Precision Float - double buf[32] */ 57 + FUNC_START(store_fpr) 58 + stfd 0, 0*8(3) 59 + stfd 1, 1*8(3) 60 + stfd 2, 2*8(3) 61 + stfd 3, 3*8(3) 62 + stfd 4, 4*8(3) 63 + stfd 5, 5*8(3) 64 + stfd 6, 6*8(3) 65 + stfd 7, 7*8(3) 66 + stfd 8, 8*8(3) 67 + stfd 9, 9*8(3) 68 + stfd 10, 10*8(3) 69 + stfd 11, 11*8(3) 70 + stfd 12, 12*8(3) 71 + stfd 13, 13*8(3) 72 + stfd 14, 14*8(3) 73 + stfd 15, 15*8(3) 74 + stfd 16, 16*8(3) 75 + stfd 17, 17*8(3) 76 + stfd 18, 18*8(3) 77 + stfd 19, 19*8(3) 78 + stfd 20, 20*8(3) 79 + stfd 21, 21*8(3) 80 + stfd 22, 22*8(3) 81 + stfd 23, 23*8(3) 82 + stfd 24, 24*8(3) 83 + stfd 25, 25*8(3) 84 + stfd 26, 26*8(3) 85 + stfd 27, 27*8(3) 86 + stfd 28, 28*8(3) 87 + stfd 29, 29*8(3) 88 + stfd 30, 30*8(3) 89 + stfd 31, 31*8(3) 90 90 blr 91 - FUNC_END(load_fpr_single_precision) 92 - 93 - /* Single Precision Float - float buf[32] */ 94 - FUNC_START(store_fpr_single_precision) 95 - stfs 0, 0*4(3) 96 - stfs 1, 1*4(3) 97 - stfs 2, 2*4(3) 98 - stfs 3, 3*4(3) 99 - stfs 4, 4*4(3) 100 - stfs 5, 5*4(3) 101 - stfs 6, 6*4(3) 102 - stfs 7, 7*4(3) 103 - stfs 8, 8*4(3) 104 - stfs 9, 9*4(3) 105 - stfs 10, 10*4(3) 106 - stfs 11, 11*4(3) 107 - stfs 12, 12*4(3) 108 - stfs 13, 13*4(3) 109 - stfs 14, 14*4(3) 110 - stfs 15, 15*4(3) 111 - stfs 16, 16*4(3) 112 - stfs 17, 17*4(3) 113 - stfs 18, 18*4(3) 114 - stfs 19, 19*4(3) 115 - stfs 20, 20*4(3) 116 - stfs 21, 21*4(3) 117 - stfs 22, 22*4(3) 118 - stfs 23, 23*4(3) 119 - stfs 24, 24*4(3) 120 - stfs 25, 25*4(3) 121 - stfs 26, 26*4(3) 122 - stfs 27, 27*4(3) 123 - stfs 28, 28*4(3) 124 - stfs 29, 29*4(3) 125 - stfs 30, 30*4(3) 126 - stfs 31, 31*4(3) 127 - blr 128 - FUNC_END(store_fpr_single_precision) 91 + FUNC_END(store_fpr) 129 92 130 93 /* VMX/VSX registers - unsigned long buf[128] */ 131 94 FUNC_START(loadvsx)
+1
tools/testing/selftests/powerpc/math/.gitignore
··· 7 7 vmx_signal 8 8 vsx_preempt 9 9 fpu_denormal 10 + mma
+3
tools/testing/selftests/powerpc/math/mma.S
··· 20 20 /* xvi16ger2s */ 21 21 .long 0xec042958 22 22 23 + /* Deprime the accumulator - xxmfacc 0 */ 24 + .long 0x7c000162 25 + 23 26 /* Store result in image passed in r5 */ 24 27 stxvw4x 0,0,5 25 28 addi 5,5,16
+1
tools/testing/selftests/powerpc/mce/.gitignore
··· 1 + inject-ra-err
+18 -12
tools/testing/selftests/powerpc/papr_attributes/attr_test.c
··· 7 7 * Copyright 2022, Pratik Rajesh Sampat, IBM Corp. 8 8 */ 9 9 10 + #include <errno.h> 10 11 #include <stdio.h> 11 12 #include <string.h> 12 13 #include <dirent.h> ··· 33 32 NUM_VAL 34 33 }; 35 34 36 - int value_type(int id) 35 + static int value_type(int id) 37 36 { 38 37 int val_type; 39 38 ··· 55 54 return val_type; 56 55 } 57 56 58 - int verify_energy_info(void) 57 + static int verify_energy_info(void) 59 58 { 60 59 const char *path = "/sys/firmware/papr/energy_scale_info"; 61 60 struct dirent *entry; 62 61 struct stat s; 63 62 DIR *dirp; 64 63 65 - if (stat(path, &s) || !S_ISDIR(s.st_mode)) 66 - return -1; 64 + errno = 0; 65 + if (stat(path, &s)) { 66 + SKIP_IF(errno == ENOENT); 67 + FAIL_IF(errno); 68 + } 69 + 70 + FAIL_IF(!S_ISDIR(s.st_mode)); 71 + 67 72 dirp = opendir(path); 68 73 69 74 while ((entry = readdir(dirp)) != NULL) { ··· 83 76 84 77 id = atoi(entry->d_name); 85 78 attr_type = value_type(id); 86 - if (attr_type == INVALID) 87 - return -1; 79 + FAIL_IF(attr_type == INVALID); 88 80 89 81 /* Check if the files exist and have data in them */ 90 82 sprintf(file_name, "%s/%d/desc", path, id); 91 83 f = fopen(file_name, "r"); 92 - if (!f || fgetc(f) == EOF) 93 - return -1; 84 + FAIL_IF(!f); 85 + FAIL_IF(fgetc(f) == EOF); 94 86 95 87 sprintf(file_name, "%s/%d/value", path, id); 96 88 f = fopen(file_name, "r"); 97 - if (!f || fgetc(f) == EOF) 98 - return -1; 89 + FAIL_IF(!f); 90 + FAIL_IF(fgetc(f) == EOF); 99 91 100 92 if (attr_type == STR_VAL) { 101 93 sprintf(file_name, "%s/%d/value_desc", path, id); 102 94 f = fopen(file_name, "r"); 103 - if (!f || fgetc(f) == EOF) 104 - return -1; 95 + FAIL_IF(!f); 96 + FAIL_IF(fgetc(f) == EOF); 105 97 } 106 98 } 107 99
+9 -2
tools/testing/selftests/powerpc/pmu/Makefile
··· 8 8 top_srcdir = ../../../../.. 9 9 include ../../lib.mk 10 10 11 - all: $(TEST_GEN_PROGS) ebb sampling_tests 11 + all: $(TEST_GEN_PROGS) ebb sampling_tests event_code_tests 12 12 13 13 $(TEST_GEN_PROGS): $(EXTRA_SOURCES) 14 14 ··· 27 27 $(DEFAULT_RUN_TESTS) 28 28 TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests 29 29 TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests 30 + TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests 30 31 endef 31 32 32 33 DEFAULT_EMIT_TESTS := $(EMIT_TESTS) ··· 35 34 $(DEFAULT_EMIT_TESTS) 36 35 TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests 37 36 TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests 37 + TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests 38 38 endef 39 39 40 40 DEFAULT_INSTALL_RULE := $(INSTALL_RULE) ··· 43 41 $(DEFAULT_INSTALL_RULE) 44 42 TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install 45 43 TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install 44 + TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install 46 45 endef 47 46 48 47 clean: 49 48 $(RM) $(TEST_GEN_PROGS) $(OUTPUT)/loop.o 50 49 TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean 51 50 TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean 51 + TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean 52 52 53 53 ebb: 54 54 TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all ··· 58 54 sampling_tests: 59 55 TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all 60 56 61 - .PHONY: all run_tests clean ebb sampling_tests 57 + event_code_tests: 58 + TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all 59 + 60 + .PHONY: all run_tests clean ebb sampling_tests event_code_tests
+28
tools/testing/selftests/powerpc/pmu/branch_loops.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <ppc-asm.h> 7 + 8 + .text 9 + 10 + #define ITER_SHIFT 31 11 + 12 + FUNC_START(indirect_branch_loop) 13 + li r3, 1 14 + sldi r3, r3, ITER_SHIFT 15 + 16 + 1: cmpdi r3, 0 17 + beqlr 18 + 19 + addi r3, r3, -1 20 + 21 + ld r4, 2f@got(%r2) 22 + mtctr r4 23 + bctr 24 + 25 + .balign 32 26 + 2: b 1b 27 + 28 + FUNC_END(indirect_branch_loop)
+1
tools/testing/selftests/powerpc/pmu/ebb/.gitignore
··· 21 21 lost_exception_test 22 22 no_handler_test 23 23 cycles_with_mmcr2_test 24 + regs_access_pmccext_test
+1
tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c
··· 50 50 expected[1] = MMCR2_EXPECTED_2; 51 51 i = 0; 52 52 bad_mmcr2 = false; 53 + actual = 0; 53 54 54 55 /* Make sure we loop until we take at least one EBB */ 55 56 while ((ebb_state.stats.ebb_count < 20 && !bad_mmcr2) ||
+15
tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + CFLAGS += -m64 3 + 4 + TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ 5 + group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ 6 + group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ 7 + blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 generic_events_valid_test \ 8 + group_constraint_l2l3_sel_test group_constraint_cache_test group_constraint_thresh_cmp_test \ 9 + group_constraint_unit_test group_constraint_thresh_ctl_test group_constraint_thresh_sel_test \ 10 + hw_cache_event_type_test 11 + 12 + top_srcdir = ../../../../../.. 13 + include ../../../lib.mk 14 + 15 + $(TEST_GEN_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c ../sampling_tests/misc.h ../sampling_tests/misc.c
+132
tools/testing/selftests/powerpc/pmu/event_code_tests/blacklisted_events_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <sys/prctl.h> 8 + #include <limits.h> 9 + #include "../event.h" 10 + #include "../sampling_tests/misc.h" 11 + 12 + #define PM_DTLB_MISS_16G 0x1c058 13 + #define PM_DERAT_MISS_2M 0x1c05a 14 + #define PM_DTLB_MISS_2M 0x1c05c 15 + #define PM_MRK_DTLB_MISS_1G 0x1d15c 16 + #define PM_DTLB_MISS_4K 0x2c056 17 + #define PM_DERAT_MISS_1G 0x2c05a 18 + #define PM_MRK_DERAT_MISS_2M 0x2d152 19 + #define PM_MRK_DTLB_MISS_4K 0x2d156 20 + #define PM_MRK_DTLB_MISS_16G 0x2d15e 21 + #define PM_DTLB_MISS_64K 0x3c056 22 + #define PM_MRK_DERAT_MISS_1G 0x3d152 23 + #define PM_MRK_DTLB_MISS_64K 0x3d156 24 + #define PM_DISP_HELD_SYNC_HOLD 0x4003c 25 + #define PM_DTLB_MISS_16M 0x4c056 26 + #define PM_DTLB_MISS_1G 0x4c05a 27 + #define PM_MRK_DTLB_MISS_16M 0x4c15e 28 + #define PM_MRK_ST_DONE_L2 0x10134 29 + #define PM_RADIX_PWC_L1_HIT 0x1f056 30 + #define PM_FLOP_CMPL 0x100f4 31 + #define PM_MRK_NTF_FIN 0x20112 32 + #define PM_RADIX_PWC_L2_HIT 0x2d024 33 + #define PM_IFETCH_THROTTLE 0x3405e 34 + #define PM_MRK_L2_TM_ST_ABORT_SISTER 0x3e15c 35 + #define PM_RADIX_PWC_L3_HIT 0x3f056 36 + #define PM_RUN_CYC_SMT2_MODE 0x3006c 37 + #define PM_TM_TX_PASS_RUN_INST 0x4e014 38 + 39 + #define PVR_POWER9_CUMULUS 0x00002000 40 + 41 + int blacklist_events_dd21[] = { 42 + PM_MRK_ST_DONE_L2, 43 + PM_RADIX_PWC_L1_HIT, 44 + PM_FLOP_CMPL, 45 + PM_MRK_NTF_FIN, 46 + PM_RADIX_PWC_L2_HIT, 47 + PM_IFETCH_THROTTLE, 48 + PM_MRK_L2_TM_ST_ABORT_SISTER, 49 + PM_RADIX_PWC_L3_HIT, 50 + PM_RUN_CYC_SMT2_MODE, 51 + PM_TM_TX_PASS_RUN_INST, 52 + PM_DISP_HELD_SYNC_HOLD, 53 + }; 54 + 55 + int blacklist_events_dd22[] = { 56 + PM_DTLB_MISS_16G, 57 + PM_DERAT_MISS_2M, 58 + PM_DTLB_MISS_2M, 59 + PM_MRK_DTLB_MISS_1G, 60 + PM_DTLB_MISS_4K, 61 + PM_DERAT_MISS_1G, 62 + PM_MRK_DERAT_MISS_2M, 63 + PM_MRK_DTLB_MISS_4K, 64 + PM_MRK_DTLB_MISS_16G, 65 + PM_DTLB_MISS_64K, 66 + PM_MRK_DERAT_MISS_1G, 67 + PM_MRK_DTLB_MISS_64K, 68 + PM_DISP_HELD_SYNC_HOLD, 69 + PM_DTLB_MISS_16M, 70 + PM_DTLB_MISS_1G, 71 + PM_MRK_DTLB_MISS_16M, 72 + }; 73 + 74 + int pvr_min; 75 + 76 + /* 77 + * check for power9 support for 2.1 and 78 + * 2.2 model where blacklist is applicable. 79 + */ 80 + int check_for_power9_version(void) 81 + { 82 + pvr_min = PVR_MIN(mfspr(SPRN_PVR)); 83 + 84 + SKIP_IF(PVR_VER(pvr) != POWER9); 85 + SKIP_IF(!(pvr & PVR_POWER9_CUMULUS)); 86 + 87 + SKIP_IF(!(3 - pvr_min)); 88 + 89 + return 0; 90 + } 91 + 92 + /* 93 + * Testcase to ensure that using blacklisted bits in 94 + * event code should cause event_open to fail in power9 95 + */ 96 + 97 + static int blacklisted_events(void) 98 + { 99 + struct event event; 100 + int i = 0; 101 + 102 + /* Check for platform support for the test */ 103 + SKIP_IF(platform_check_for_tests()); 104 + 105 + /* 106 + * check for power9 support for 2.1 and 107 + * 2.2 model where blacklist is applicable. 108 + */ 109 + SKIP_IF(check_for_power9_version()); 110 + 111 + /* Skip for Generic compat mode */ 112 + SKIP_IF(check_for_generic_compat_pmu()); 113 + 114 + if (pvr_min == 1) { 115 + for (i = 0; i < ARRAY_SIZE(blacklist_events_dd21); i++) { 116 + event_init(&event, blacklist_events_dd21[i]); 117 + FAIL_IF(!event_open(&event)); 118 + } 119 + } else if (pvr_min == 2) { 120 + for (i = 0; i < ARRAY_SIZE(blacklist_events_dd22); i++) { 121 + event_init(&event, blacklist_events_dd22[i]); 122 + FAIL_IF(!event_open(&event)); 123 + } 124 + } 125 + 126 + return 0; 127 + } 128 + 129 + int main(void) 130 + { 131 + return test_harness(blacklisted_events, "blacklisted_events"); 132 + }
+109
tools/testing/selftests/powerpc/pmu/event_code_tests/event_alternatives_tests_p10.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include "../event.h" 8 + #include "../sampling_tests/misc.h" 9 + 10 + #define PM_RUN_CYC_ALT 0x200f4 11 + #define PM_INST_DISP 0x200f2 12 + #define PM_BR_2PATH 0x20036 13 + #define PM_LD_MISS_L1 0x3e054 14 + #define PM_RUN_INST_CMPL_ALT 0x400fa 15 + 16 + #define EventCode_1 0x100fc 17 + #define EventCode_2 0x200fa 18 + #define EventCode_3 0x300fc 19 + #define EventCode_4 0x400fc 20 + 21 + /* 22 + * Check for event alternatives. 23 + */ 24 + 25 + static int event_alternatives_tests_p10(void) 26 + { 27 + struct event *e, events[5]; 28 + int i; 29 + 30 + /* Check for platform support for the test */ 31 + SKIP_IF(platform_check_for_tests()); 32 + 33 + /* 34 + * PVR check is used here since PMU specific data like 35 + * alternative events is handled by respective PMU driver 36 + * code and using PVR will work correctly for all cases 37 + * including generic compat mode. 38 + */ 39 + SKIP_IF(PVR_VER(mfspr(SPRN_PVR)) != POWER10); 40 + 41 + SKIP_IF(check_for_generic_compat_pmu()); 42 + 43 + /* 44 + * Test for event alternative for 0x0001e 45 + * and 0x00002. 46 + */ 47 + e = &events[0]; 48 + event_init(e, 0x0001e); 49 + 50 + e = &events[1]; 51 + event_init(e, EventCode_1); 52 + 53 + e = &events[2]; 54 + event_init(e, EventCode_2); 55 + 56 + e = &events[3]; 57 + event_init(e, EventCode_3); 58 + 59 + e = &events[4]; 60 + event_init(e, EventCode_4); 61 + 62 + FAIL_IF(event_open(&events[0])); 63 + 64 + /* 65 + * Expected to pass since 0x0001e has alternative event 66 + * 0x600f4 in PMC6. So it can go in with other events 67 + * in PMC1 to PMC4. 68 + */ 69 + for (i = 1; i < 5; i++) 70 + FAIL_IF(event_open_with_group(&events[i], events[0].fd)); 71 + 72 + for (i = 0; i < 5; i++) 73 + event_close(&events[i]); 74 + 75 + e = &events[0]; 76 + event_init(e, 0x00002); 77 + 78 + e = &events[1]; 79 + event_init(e, EventCode_1); 80 + 81 + e = &events[2]; 82 + event_init(e, EventCode_2); 83 + 84 + e = &events[3]; 85 + event_init(e, EventCode_3); 86 + 87 + e = &events[4]; 88 + event_init(e, EventCode_4); 89 + 90 + FAIL_IF(event_open(&events[0])); 91 + 92 + /* 93 + * Expected to pass since 0x00020 has alternative event 94 + * 0x500fa in PMC5. So it can go in with other events 95 + * in PMC1 to PMC4. 96 + */ 97 + for (i = 1; i < 5; i++) 98 + FAIL_IF(event_open_with_group(&events[i], events[0].fd)); 99 + 100 + for (i = 0; i < 5; i++) 101 + event_close(&events[i]); 102 + 103 + return 0; 104 + } 105 + 106 + int main(void) 107 + { 108 + return test_harness(event_alternatives_tests_p10, "event_alternatives_tests_p10"); 109 + }
+116
tools/testing/selftests/powerpc/pmu/event_code_tests/event_alternatives_tests_p9.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include "../event.h" 8 + #include "../sampling_tests/misc.h" 9 + 10 + #define PM_RUN_CYC_ALT 0x200f4 11 + #define PM_INST_DISP 0x200f2 12 + #define PM_BR_2PATH 0x20036 13 + #define PM_LD_MISS_L1 0x3e054 14 + #define PM_RUN_INST_CMPL_ALT 0x400fa 15 + 16 + #define EventCode_1 0x200fa 17 + #define EventCode_2 0x200fc 18 + #define EventCode_3 0x300fc 19 + #define EventCode_4 0x400fc 20 + 21 + /* 22 + * Check for event alternatives. 23 + */ 24 + 25 + static int event_alternatives_tests_p9(void) 26 + { 27 + struct event event, leader; 28 + 29 + /* Check for platform support for the test */ 30 + SKIP_IF(platform_check_for_tests()); 31 + 32 + /* 33 + * PVR check is used here since PMU specific data like 34 + * alternative events is handled by respective PMU driver 35 + * code and using PVR will work correctly for all cases 36 + * including generic compat mode. 37 + */ 38 + SKIP_IF(PVR_VER(mfspr(SPRN_PVR)) != POWER9); 39 + 40 + /* Skip for generic compat PMU */ 41 + SKIP_IF(check_for_generic_compat_pmu()); 42 + 43 + /* Init the event for PM_RUN_CYC_ALT */ 44 + event_init(&leader, PM_RUN_CYC_ALT); 45 + FAIL_IF(event_open(&leader)); 46 + 47 + event_init(&event, EventCode_1); 48 + 49 + /* 50 + * Expected to pass since PM_RUN_CYC_ALT in PMC2 has alternative event 51 + * 0x600f4. So it can go in with EventCode_1 which is using PMC2 52 + */ 53 + FAIL_IF(event_open_with_group(&event, leader.fd)); 54 + 55 + event_close(&leader); 56 + event_close(&event); 57 + 58 + event_init(&leader, PM_INST_DISP); 59 + FAIL_IF(event_open(&leader)); 60 + 61 + event_init(&event, EventCode_2); 62 + /* 63 + * Expected to pass since PM_INST_DISP in PMC2 has alternative event 64 + * 0x300f2 in PMC3. So it can go in with EventCode_2 which is using PMC2 65 + */ 66 + FAIL_IF(event_open_with_group(&event, leader.fd)); 67 + 68 + event_close(&leader); 69 + event_close(&event); 70 + 71 + event_init(&leader, PM_BR_2PATH); 72 + FAIL_IF(event_open(&leader)); 73 + 74 + event_init(&event, EventCode_2); 75 + /* 76 + * Expected to pass since PM_BR_2PATH in PMC2 has alternative event 77 + * 0x40036 in PMC4. So it can go in with EventCode_2 which is using PMC2 78 + */ 79 + FAIL_IF(event_open_with_group(&event, leader.fd)); 80 + 81 + event_close(&leader); 82 + event_close(&event); 83 + 84 + event_init(&leader, PM_LD_MISS_L1); 85 + FAIL_IF(event_open(&leader)); 86 + 87 + event_init(&event, EventCode_3); 88 + /* 89 + * Expected to pass since PM_LD_MISS_L1 in PMC3 has alternative event 90 + * 0x400f0 in PMC4. So it can go in with EventCode_3 which is using PMC3 91 + */ 92 + FAIL_IF(event_open_with_group(&event, leader.fd)); 93 + 94 + event_close(&leader); 95 + event_close(&event); 96 + 97 + event_init(&leader, PM_RUN_INST_CMPL_ALT); 98 + FAIL_IF(event_open(&leader)); 99 + 100 + event_init(&event, EventCode_4); 101 + /* 102 + * Expected to pass since PM_RUN_INST_CMPL_ALT in PMC4 has alternative event 103 + * 0x500fa in PMC5. So it can go in with EventCode_4 which is using PMC4 104 + */ 105 + FAIL_IF(event_open_with_group(&event, leader.fd)); 106 + 107 + event_close(&leader); 108 + event_close(&event); 109 + 110 + return 0; 111 + } 112 + 113 + int main(void) 114 + { 115 + return test_harness(event_alternatives_tests_p9, "event_alternatives_tests_p9"); 116 + }
+130
tools/testing/selftests/powerpc/pmu/event_code_tests/generic_events_valid_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <sys/prctl.h> 8 + #include <limits.h> 9 + #include "../event.h" 10 + #include "../sampling_tests/misc.h" 11 + 12 + /* 13 + * Testcase to ensure that using invalid event in generic 14 + * event for PERF_TYPE_HARDWARE should fail 15 + */ 16 + 17 + static int generic_events_valid_test(void) 18 + { 19 + struct event event; 20 + 21 + /* Check for platform support for the test */ 22 + SKIP_IF(platform_check_for_tests()); 23 + 24 + /* generic events is different in compat_mode */ 25 + SKIP_IF(check_for_generic_compat_pmu()); 26 + 27 + /* 28 + * Invalid generic events in power10: 29 + * - PERF_COUNT_HW_BUS_CYCLES 30 + * - PERF_COUNT_HW_STALLED_CYCLES_FRONTEND 31 + * - PERF_COUNT_HW_STALLED_CYCLES_BACKEND 32 + * - PERF_COUNT_HW_REF_CPU_CYCLES 33 + */ 34 + if (PVR_VER(mfspr(SPRN_PVR)) == POWER10) { 35 + event_init_opts(&event, PERF_COUNT_HW_CPU_CYCLES, PERF_TYPE_HARDWARE, "event"); 36 + FAIL_IF(event_open(&event)); 37 + event_close(&event); 38 + 39 + event_init_opts(&event, PERF_COUNT_HW_INSTRUCTIONS, 40 + PERF_TYPE_HARDWARE, "event"); 41 + FAIL_IF(event_open(&event)); 42 + event_close(&event); 43 + 44 + event_init_opts(&event, PERF_COUNT_HW_CACHE_REFERENCES, 45 + PERF_TYPE_HARDWARE, "event"); 46 + FAIL_IF(event_open(&event)); 47 + event_close(&event); 48 + 49 + event_init_opts(&event, PERF_COUNT_HW_CACHE_MISSES, PERF_TYPE_HARDWARE, "event"); 50 + FAIL_IF(event_open(&event)); 51 + event_close(&event); 52 + 53 + event_init_opts(&event, PERF_COUNT_HW_BRANCH_INSTRUCTIONS, 54 + PERF_TYPE_HARDWARE, "event"); 55 + FAIL_IF(event_open(&event)); 56 + event_close(&event); 57 + 58 + event_init_opts(&event, PERF_COUNT_HW_BRANCH_MISSES, PERF_TYPE_HARDWARE, "event"); 59 + FAIL_IF(event_open(&event)); 60 + event_close(&event); 61 + 62 + event_init_opts(&event, PERF_COUNT_HW_BUS_CYCLES, PERF_TYPE_HARDWARE, "event"); 63 + FAIL_IF(!event_open(&event)); 64 + 65 + event_init_opts(&event, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND, 66 + PERF_TYPE_HARDWARE, "event"); 67 + FAIL_IF(!event_open(&event)); 68 + 69 + event_init_opts(&event, PERF_COUNT_HW_STALLED_CYCLES_BACKEND, 70 + PERF_TYPE_HARDWARE, "event"); 71 + FAIL_IF(!event_open(&event)); 72 + 73 + event_init_opts(&event, PERF_COUNT_HW_REF_CPU_CYCLES, PERF_TYPE_HARDWARE, "event"); 74 + FAIL_IF(!event_open(&event)); 75 + } else if (PVR_VER(mfspr(SPRN_PVR)) == POWER9) { 76 + /* 77 + * Invalid generic events in power9: 78 + * - PERF_COUNT_HW_BUS_CYCLES 79 + * - PERF_COUNT_HW_REF_CPU_CYCLES 80 + */ 81 + event_init_opts(&event, PERF_COUNT_HW_CPU_CYCLES, PERF_TYPE_HARDWARE, "event"); 82 + FAIL_IF(event_open(&event)); 83 + event_close(&event); 84 + 85 + event_init_opts(&event, PERF_COUNT_HW_INSTRUCTIONS, PERF_TYPE_HARDWARE, "event"); 86 + FAIL_IF(event_open(&event)); 87 + event_close(&event); 88 + 89 + event_init_opts(&event, PERF_COUNT_HW_CACHE_REFERENCES, 90 + PERF_TYPE_HARDWARE, "event"); 91 + FAIL_IF(event_open(&event)); 92 + event_close(&event); 93 + 94 + event_init_opts(&event, PERF_COUNT_HW_CACHE_MISSES, PERF_TYPE_HARDWARE, "event"); 95 + FAIL_IF(event_open(&event)); 96 + event_close(&event); 97 + 98 + event_init_opts(&event, PERF_COUNT_HW_BRANCH_INSTRUCTIONS, 99 + PERF_TYPE_HARDWARE, "event"); 100 + FAIL_IF(event_open(&event)); 101 + event_close(&event); 102 + 103 + event_init_opts(&event, PERF_COUNT_HW_BRANCH_MISSES, PERF_TYPE_HARDWARE, "event"); 104 + FAIL_IF(event_open(&event)); 105 + event_close(&event); 106 + 107 + event_init_opts(&event, PERF_COUNT_HW_BUS_CYCLES, PERF_TYPE_HARDWARE, "event"); 108 + FAIL_IF(!event_open(&event)); 109 + 110 + event_init_opts(&event, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND, 111 + PERF_TYPE_HARDWARE, "event"); 112 + FAIL_IF(event_open(&event)); 113 + event_close(&event); 114 + 115 + event_init_opts(&event, PERF_COUNT_HW_STALLED_CYCLES_BACKEND, 116 + PERF_TYPE_HARDWARE, "event"); 117 + FAIL_IF(event_open(&event)); 118 + event_close(&event); 119 + 120 + event_init_opts(&event, PERF_COUNT_HW_REF_CPU_CYCLES, PERF_TYPE_HARDWARE, "event"); 121 + FAIL_IF(!event_open(&event)); 122 + } 123 + 124 + return 0; 125 + } 126 + 127 + int main(void) 128 + { 129 + return test_harness(generic_events_valid_test, "generic_events_valid_test"); 130 + }
+60
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_cache_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "utils.h" 11 + #include "../sampling_tests/misc.h" 12 + 13 + /* All L1 D cache load references counted at finish, gated by reject */ 14 + #define EventCode_1 0x1100fc 15 + /* Load Missed L1 */ 16 + #define EventCode_2 0x23e054 17 + /* Load Missed L1 */ 18 + #define EventCode_3 0x13e054 19 + 20 + /* 21 + * Testcase for group constraint check of data and instructions 22 + * cache qualifier bits which is used to program cache select field in 23 + * Monitor Mode Control Register 1 (MMCR1: 16-17) for l1 cache. 24 + * All events in the group should match cache select bits otherwise 25 + * event_open for the group will fail. 26 + */ 27 + static int group_constraint_cache(void) 28 + { 29 + struct event event, leader; 30 + 31 + /* Check for platform support for the test */ 32 + SKIP_IF(platform_check_for_tests()); 33 + 34 + /* Init the events for the group contraint check for l1 cache select bits */ 35 + event_init(&leader, EventCode_1); 36 + FAIL_IF(event_open(&leader)); 37 + 38 + event_init(&event, EventCode_2); 39 + 40 + /* Expected to fail as sibling event doesn't request same l1 cache select bits as leader */ 41 + FAIL_IF(!event_open_with_group(&event, leader.fd)); 42 + 43 + event_close(&event); 44 + 45 + /* Init the event for the group contraint l1 cache select test */ 46 + event_init(&event, EventCode_3); 47 + 48 + /* Expected to succeed as sibling event request same l1 cache select bits as leader */ 49 + FAIL_IF(event_open_with_group(&event, leader.fd)); 50 + 51 + event_close(&leader); 52 + event_close(&event); 53 + 54 + return 0; 55 + } 56 + 57 + int main(void) 58 + { 59 + return test_harness(group_constraint_cache, "group_constraint_cache"); 60 + }
+64
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_l2l3_sel_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "utils.h" 11 + #include "../sampling_tests/misc.h" 12 + 13 + /* All successful D-side store dispatches for this thread */ 14 + #define EventCode_1 0x010000046080 15 + /* All successful D-side store dispatches for this thread that were L2 Miss */ 16 + #define EventCode_2 0x26880 17 + /* All successful D-side store dispatches for this thread that were L2 Miss */ 18 + #define EventCode_3 0x010000026880 19 + 20 + /* 21 + * Testcase for group constraint check of l2l3_sel bits which is 22 + * used to program l2l3 select field in Monitor Mode Control Register 0 23 + * (MMCR0: 56-60). 24 + * All events in the group should match l2l3_sel bits otherwise 25 + * event_open for the group should fail. 26 + */ 27 + static int group_constraint_l2l3_sel(void) 28 + { 29 + struct event event, leader; 30 + 31 + /* 32 + * Check for platform support for the test. 33 + * This test is only aplicable on power10 34 + */ 35 + SKIP_IF(platform_check_for_tests()); 36 + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 37 + 38 + /* Init the events for the group contraint check for l2l3_sel bits */ 39 + event_init(&leader, EventCode_1); 40 + FAIL_IF(event_open(&leader)); 41 + 42 + event_init(&event, EventCode_2); 43 + 44 + /* Expected to fail as sibling event doesn't request same l2l3_sel bits as leader */ 45 + FAIL_IF(!event_open_with_group(&event, leader.fd)); 46 + 47 + event_close(&event); 48 + 49 + /* Init the event for the group contraint l2l3_sel test */ 50 + event_init(&event, EventCode_3); 51 + 52 + /* Expected to succeed as sibling event request same l2l3_sel bits as leader */ 53 + FAIL_IF(event_open_with_group(&event, leader.fd)); 54 + 55 + event_close(&leader); 56 + event_close(&event); 57 + 58 + return 0; 59 + } 60 + 61 + int main(void) 62 + { 63 + return test_harness(group_constraint_l2l3_sel, "group_constraint_l2l3_sel"); 64 + }
+54
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_mmcra_sample_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include "../event.h" 8 + #include "../sampling_tests/misc.h" 9 + 10 + #define EventCode_1 0x35340401e0 11 + #define EventCode_2 0x353c0101ec 12 + #define EventCode_3 0x35340101ec 13 + /* 14 + * Test that using different sample bits in 15 + * event code cause failure in schedule for 16 + * group of events. 17 + */ 18 + 19 + static int group_constraint_mmcra_sample(void) 20 + { 21 + struct event event, leader; 22 + 23 + SKIP_IF(platform_check_for_tests()); 24 + 25 + /* 26 + * Events with different "sample" field values 27 + * in a group will fail to schedule. 28 + * Use event with load only sampling mode as 29 + * group leader. Use event with store only sampling 30 + * as sibling event. 31 + */ 32 + event_init(&leader, EventCode_1); 33 + FAIL_IF(event_open(&leader)); 34 + 35 + event_init(&event, EventCode_2); 36 + 37 + /* Expected to fail as sibling event doesn't use same sampling bits as leader */ 38 + FAIL_IF(!event_open_with_group(&event, leader.fd)); 39 + 40 + event_init(&event, EventCode_3); 41 + 42 + /* Expected to pass as sibling event use same sampling bits as leader */ 43 + FAIL_IF(event_open_with_group(&event, leader.fd)); 44 + 45 + event_close(&leader); 46 + event_close(&event); 47 + 48 + return 0; 49 + } 50 + 51 + int main(void) 52 + { 53 + return test_harness(group_constraint_mmcra_sample, "group_constraint_mmcra_sample"); 54 + }
+63
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_pmc56_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include "../event.h" 8 + #include "../sampling_tests/misc.h" 9 + 10 + /* 11 + * Testcase for checking constraint checks for 12 + * Performance Monitor Counter 5 (PMC5) and also 13 + * Performance Monitor Counter 6 (PMC6). Events using 14 + * PMC5/PMC6 shouldn't have other fields in event 15 + * code like cache bits, thresholding or marked bit. 16 + */ 17 + 18 + static int group_constraint_pmc56(void) 19 + { 20 + struct event event; 21 + 22 + /* Check for platform support for the test */ 23 + SKIP_IF(platform_check_for_tests()); 24 + 25 + /* 26 + * Events using PMC5 and PMC6 with cache bit 27 + * set in event code is expected to fail. 28 + */ 29 + event_init(&event, 0x2500fa); 30 + FAIL_IF(!event_open(&event)); 31 + 32 + event_init(&event, 0x2600f4); 33 + FAIL_IF(!event_open(&event)); 34 + 35 + /* 36 + * PMC5 and PMC6 only supports base events: 37 + * ie 500fa and 600f4. Other combinations 38 + * should fail. 39 + */ 40 + event_init(&event, 0x501e0); 41 + FAIL_IF(!event_open(&event)); 42 + 43 + event_init(&event, 0x6001e); 44 + FAIL_IF(!event_open(&event)); 45 + 46 + event_init(&event, 0x501fa); 47 + FAIL_IF(!event_open(&event)); 48 + 49 + /* 50 + * Events using PMC5 and PMC6 with random 51 + * sampling bits set in event code should fail 52 + * to schedule. 53 + */ 54 + event_init(&event, 0x35340500fa); 55 + FAIL_IF(!event_open(&event)); 56 + 57 + return 0; 58 + } 59 + 60 + int main(void) 61 + { 62 + return test_harness(group_constraint_pmc56, "group_constraint_pmc56"); 63 + }
+70
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_pmc_count_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include "../event.h" 8 + #include "../sampling_tests/misc.h" 9 + 10 + /* 11 + * Testcase for number of counters in use. 12 + * The number of programmable counters is from 13 + * performance monitor counter 1 to performance 14 + * monitor counter 4 (PMC1-PMC4). If number of 15 + * counters in use exceeds the limit, next event 16 + * should fail to schedule. 17 + */ 18 + 19 + static int group_constraint_pmc_count(void) 20 + { 21 + struct event *e, events[5]; 22 + int i; 23 + 24 + /* Check for platform support for the test */ 25 + SKIP_IF(platform_check_for_tests()); 26 + 27 + /* 28 + * Test for number of counters in use. 29 + * Use PMC1 to PMC4 for leader and 3 sibling 30 + * events. Trying to open fourth event should 31 + * fail here. 32 + */ 33 + e = &events[0]; 34 + event_init(e, 0x1001a); 35 + 36 + e = &events[1]; 37 + event_init(e, 0x200fc); 38 + 39 + e = &events[2]; 40 + event_init(e, 0x30080); 41 + 42 + e = &events[3]; 43 + event_init(e, 0x40054); 44 + 45 + e = &events[4]; 46 + event_init(e, 0x0002c); 47 + 48 + FAIL_IF(event_open(&events[0])); 49 + 50 + /* 51 + * The event_open will fail on event 4 if constraint 52 + * check fails 53 + */ 54 + for (i = 1; i < 5; i++) { 55 + if (i == 4) 56 + FAIL_IF(!event_open_with_group(&events[i], events[0].fd)); 57 + else 58 + FAIL_IF(event_open_with_group(&events[i], events[0].fd)); 59 + } 60 + 61 + for (i = 1; i < 4; i++) 62 + event_close(&events[i]); 63 + 64 + return 0; 65 + } 66 + 67 + int main(void) 68 + { 69 + return test_harness(group_constraint_pmc_count, "group_constraint_pmc_count"); 70 + }
+56
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_radix_scope_qual_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include "../event.h" 8 + #include "../sampling_tests/misc.h" 9 + 10 + /* PM_DATA_RADIX_PROCESS_L2_PTE_FROM_L2 */ 11 + #define EventCode_1 0x14242 12 + /* PM_DATA_RADIX_PROCESS_L2_PTE_FROM_L3 */ 13 + #define EventCode_2 0x24242 14 + 15 + /* 16 + * Testcase for group constraint check for radix_scope_qual 17 + * field which is used to program Monitor Mode Control 18 + * egister (MMCR1) bit 18. 19 + * All events in the group should match radix_scope_qual, 20 + * bits otherwise event_open for the group should fail. 21 + */ 22 + 23 + static int group_constraint_radix_scope_qual(void) 24 + { 25 + struct event event, leader; 26 + 27 + /* 28 + * Check for platform support for the test. 29 + * This test is aplicable on power10 only. 30 + */ 31 + SKIP_IF(platform_check_for_tests()); 32 + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 33 + 34 + /* Init the events for the group contraint check for radix_scope_qual bits */ 35 + event_init(&leader, EventCode_1); 36 + FAIL_IF(event_open(&leader)); 37 + 38 + event_init(&event, 0x200fc); 39 + 40 + /* Expected to fail as sibling event doesn't request same radix_scope_qual bits as leader */ 41 + FAIL_IF(!event_open_with_group(&event, leader.fd)); 42 + 43 + event_init(&event, EventCode_2); 44 + /* Expected to pass as sibling event request same radix_scope_qual bits as leader */ 45 + FAIL_IF(event_open_with_group(&event, leader.fd)); 46 + 47 + event_close(&leader); 48 + event_close(&event); 49 + return 0; 50 + } 51 + 52 + int main(void) 53 + { 54 + return test_harness(group_constraint_radix_scope_qual, 55 + "group_constraint_radix_scope_qual"); 56 + }
+56
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_repeat_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include "../event.h" 8 + #include "../sampling_tests/misc.h" 9 + 10 + /* The processor's L1 data cache was reloaded */ 11 + #define EventCode1 0x21C040 12 + #define EventCode2 0x22C040 13 + 14 + /* 15 + * Testcase for group constraint check 16 + * when using events with same PMC. 17 + * Multiple events in a group shouldn't 18 + * ask for same PMC. If so it should fail. 19 + */ 20 + 21 + static int group_constraint_repeat(void) 22 + { 23 + struct event event, leader; 24 + 25 + /* Check for platform support for the test */ 26 + SKIP_IF(platform_check_for_tests()); 27 + 28 + /* 29 + * Two events in a group using same PMC 30 + * should fail to get scheduled. Usei same PMC2 31 + * for leader and sibling event which is expected 32 + * to fail. 33 + */ 34 + event_init(&leader, EventCode1); 35 + FAIL_IF(event_open(&leader)); 36 + 37 + event_init(&event, EventCode1); 38 + 39 + /* Expected to fail since sibling event is requesting same PMC as leader */ 40 + FAIL_IF(!event_open_with_group(&event, leader.fd)); 41 + 42 + event_init(&event, EventCode2); 43 + 44 + /* Expected to pass since sibling event is requesting different PMC */ 45 + FAIL_IF(event_open_with_group(&event, leader.fd)); 46 + 47 + event_close(&leader); 48 + event_close(&event); 49 + 50 + return 0; 51 + } 52 + 53 + int main(void) 54 + { 55 + return test_harness(group_constraint_repeat, "group_constraint_repeat"); 56 + }
+96
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_cmp_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "utils.h" 11 + #include "../sampling_tests/misc.h" 12 + 13 + /* 14 + * Primary PMU events used here is PM_MRK_INST_CMPL (0x401e0) and 15 + * PM_THRESH_MET (0x101ec) 16 + * Threshold event selection used is issue to complete for cycles 17 + * Sampling criteria is Load or Store only sampling 18 + */ 19 + #define p9_EventCode_1 0x13e35340401e0 20 + #define p9_EventCode_2 0x17d34340101ec 21 + #define p9_EventCode_3 0x13e35340101ec 22 + #define p10_EventCode_1 0x35340401e0 23 + #define p10_EventCode_2 0x35340101ec 24 + 25 + /* 26 + * Testcase for group constraint check of thresh_cmp bits which is 27 + * used to program thresh compare field in Monitor Mode Control Register A 28 + * (MMCRA: 9-18 bits for power9 and MMCRA: 8-18 bits for power10). 29 + * All events in the group should match thresh compare bits otherwise 30 + * event_open for the group will fail. 31 + */ 32 + static int group_constraint_thresh_cmp(void) 33 + { 34 + struct event event, leader; 35 + 36 + /* Check for platform support for the test */ 37 + SKIP_IF(platform_check_for_tests()); 38 + 39 + if (have_hwcap2(PPC_FEATURE2_ARCH_3_1)) { 40 + /* Init the events for the group contraint check for thresh_cmp bits */ 41 + event_init(&leader, p10_EventCode_1); 42 + 43 + /* Add the thresh_cmp value for leader in config1 */ 44 + leader.attr.config1 = 1000; 45 + FAIL_IF(event_open(&leader)); 46 + 47 + event_init(&event, p10_EventCode_2); 48 + 49 + /* Add the different thresh_cmp value from the leader event in config1 */ 50 + event.attr.config1 = 2000; 51 + 52 + /* Expected to fail as sibling and leader event request different thresh_cmp bits */ 53 + FAIL_IF(!event_open_with_group(&event, leader.fd)); 54 + 55 + event_close(&event); 56 + 57 + /* Init the event for the group contraint thresh compare test */ 58 + event_init(&event, p10_EventCode_2); 59 + 60 + /* Add the same thresh_cmp value for leader and sibling event in config1 */ 61 + event.attr.config1 = 1000; 62 + 63 + /* Expected to succeed as sibling and leader event request same thresh_cmp bits */ 64 + FAIL_IF(event_open_with_group(&event, leader.fd)); 65 + 66 + event_close(&leader); 67 + event_close(&event); 68 + } else { 69 + /* Init the events for the group contraint check for thresh_cmp bits */ 70 + event_init(&leader, p9_EventCode_1); 71 + FAIL_IF(event_open(&leader)); 72 + 73 + event_init(&event, p9_EventCode_2); 74 + 75 + /* Expected to fail as sibling and leader event request different thresh_cmp bits */ 76 + FAIL_IF(!event_open_with_group(&event, leader.fd)); 77 + 78 + event_close(&event); 79 + 80 + /* Init the event for the group contraint thresh compare test */ 81 + event_init(&event, p9_EventCode_3); 82 + 83 + /* Expected to succeed as sibling and leader event request same thresh_cmp bits */ 84 + FAIL_IF(event_open_with_group(&event, leader.fd)); 85 + 86 + event_close(&leader); 87 + event_close(&event); 88 + } 89 + 90 + return 0; 91 + } 92 + 93 + int main(void) 94 + { 95 + return test_harness(group_constraint_thresh_cmp, "group_constraint_thresh_cmp"); 96 + }
+64
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_ctl_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "utils.h" 11 + #include "../sampling_tests/misc.h" 12 + 13 + /* 14 + * Primary PMU events used here are PM_MRK_INST_CMPL (0x401e0) and 15 + * PM_THRESH_MET (0x101ec). 16 + * Threshold event selection used is issue to complete and issue to 17 + * finished for cycles 18 + * Sampling criteria is Load or Store only sampling 19 + */ 20 + #define EventCode_1 0x35340401e0 21 + #define EventCode_2 0x34340101ec 22 + #define EventCode_3 0x35340101ec 23 + 24 + /* 25 + * Testcase for group constraint check of thresh_ctl bits which is 26 + * used to program thresh compare field in Monitor Mode Control Register A 27 + * (MMCR0: 48-55). 28 + * All events in the group should match thresh ctl bits otherwise 29 + * event_open for the group will fail. 30 + */ 31 + static int group_constraint_thresh_ctl(void) 32 + { 33 + struct event event, leader; 34 + 35 + /* Check for platform support for the test */ 36 + SKIP_IF(platform_check_for_tests()); 37 + 38 + /* Init the events for the group contraint thresh control test */ 39 + event_init(&leader, EventCode_1); 40 + FAIL_IF(event_open(&leader)); 41 + 42 + event_init(&event, EventCode_2); 43 + 44 + /* Expected to fail as sibling and leader event request different thresh_ctl bits */ 45 + FAIL_IF(!event_open_with_group(&event, leader.fd)); 46 + 47 + event_close(&event); 48 + 49 + /* Init the event for the group contraint thresh control test */ 50 + event_init(&event, EventCode_3); 51 + 52 + /* Expected to succeed as sibling and leader event request same thresh_ctl bits */ 53 + FAIL_IF(event_open_with_group(&event, leader.fd)); 54 + 55 + event_close(&leader); 56 + event_close(&event); 57 + 58 + return 0; 59 + } 60 + 61 + int main(void) 62 + { 63 + return test_harness(group_constraint_thresh_ctl, "group_constraint_thresh_ctl"); 64 + }
+63
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_sel_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "utils.h" 11 + #include "../sampling_tests/misc.h" 12 + 13 + /* 14 + * Primary PMU events used here are PM_MRK_INST_CMPL (0x401e0) and 15 + * PM_THRESH_MET (0x101ec). 16 + * Threshold event selection used is issue to complete 17 + * Sampling criteria is Load or Store only sampling 18 + */ 19 + #define EventCode_1 0x35340401e0 20 + #define EventCode_2 0x35540101ec 21 + #define EventCode_3 0x35340101ec 22 + 23 + /* 24 + * Testcase for group constraint check of thresh_sel bits which is 25 + * used to program thresh select field in Monitor Mode Control Register A 26 + * (MMCRA: 45-57). 27 + * All events in the group should match thresh sel bits otherwise 28 + * event_open for the group will fail. 29 + */ 30 + static int group_constraint_thresh_sel(void) 31 + { 32 + struct event event, leader; 33 + 34 + /* Check for platform support for the test */ 35 + SKIP_IF(platform_check_for_tests()); 36 + 37 + /* Init the events for the group contraint thresh select test */ 38 + event_init(&leader, EventCode_1); 39 + FAIL_IF(event_open(&leader)); 40 + 41 + event_init(&event, EventCode_2); 42 + 43 + /* Expected to fail as sibling and leader event request different thresh_sel bits */ 44 + FAIL_IF(!event_open_with_group(&event, leader.fd)); 45 + 46 + event_close(&event); 47 + 48 + /* Init the event for the group contraint thresh select test */ 49 + event_init(&event, EventCode_3); 50 + 51 + /* Expected to succeed as sibling and leader event request same thresh_sel bits */ 52 + FAIL_IF(event_open_with_group(&event, leader.fd)); 53 + 54 + event_close(&leader); 55 + event_close(&event); 56 + 57 + return 0; 58 + } 59 + 60 + int main(void) 61 + { 62 + return test_harness(group_constraint_thresh_sel, "group_constraint_thresh_sel"); 63 + }
+74
tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_unit_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "utils.h" 11 + #include "../sampling_tests/misc.h" 12 + 13 + /* All successful D-side store dispatches for this thread with PMC 2 */ 14 + #define EventCode_1 0x26080 15 + /* All successful D-side store dispatches for this thread with PMC 4 */ 16 + #define EventCode_2 0x46080 17 + /* All successful D-side store dispatches for this thread that were L2 Miss with PMC 3 */ 18 + #define EventCode_3 0x36880 19 + 20 + /* 21 + * Testcase for group constraint check of unit and pmc bits which is 22 + * used to program corresponding unit and pmc field in Monitor Mode 23 + * Control Register 1 (MMCR1) 24 + * One of the event in the group should use PMC 4 incase units field 25 + * value is within 6 to 9 otherwise event_open for the group will fail. 26 + */ 27 + static int group_constraint_unit(void) 28 + { 29 + struct event *e, events[3]; 30 + 31 + /* 32 + * Check for platform support for the test. 33 + * Constraint to use PMC4 with one of the event in group, 34 + * when the unit is within 6 to 9 is only applicable on 35 + * power9. 36 + */ 37 + SKIP_IF(platform_check_for_tests()); 38 + SKIP_IF(have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 39 + 40 + /* Init the events for the group contraint check for unit bits */ 41 + e = &events[0]; 42 + event_init(e, EventCode_1); 43 + 44 + /* Expected to fail as PMC 4 is not used with unit field value 6 to 9 */ 45 + FAIL_IF(!event_open(&events[0])); 46 + 47 + /* Init the events for the group contraint check for unit bits */ 48 + e = &events[1]; 49 + event_init(e, EventCode_2); 50 + 51 + /* Expected to pass as PMC 4 is used with unit field value 6 to 9 */ 52 + FAIL_IF(event_open(&events[1])); 53 + 54 + /* Init the event for the group contraint unit test */ 55 + e = &events[2]; 56 + event_init(e, EventCode_3); 57 + 58 + /* Expected to fail as PMC4 is not being used */ 59 + FAIL_IF(!event_open_with_group(&events[2], events[0].fd)); 60 + 61 + /* Expected to succeed as event using PMC4 */ 62 + FAIL_IF(event_open_with_group(&events[2], events[1].fd)); 63 + 64 + event_close(&events[0]); 65 + event_close(&events[1]); 66 + event_close(&events[2]); 67 + 68 + return 0; 69 + } 70 + 71 + int main(void) 72 + { 73 + return test_harness(group_constraint_unit, "group_constraint_unit"); 74 + }
+64
tools/testing/selftests/powerpc/pmu/event_code_tests/group_pmc56_exclude_constraints_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include "../event.h" 8 + #include <sys/prctl.h> 9 + #include <limits.h> 10 + #include "../sampling_tests/misc.h" 11 + 12 + /* 13 + * Testcase for group constraint check for 14 + * Performance Monitor Counter 5 (PMC5) and also 15 + * Performance Monitor Counter 6 (PMC6). 16 + * Test that pmc5/6 is excluded from constraint 17 + * check when scheduled along with group of events. 18 + */ 19 + 20 + static int group_pmc56_exclude_constraints(void) 21 + { 22 + struct event *e, events[3]; 23 + int i; 24 + 25 + /* Check for platform support for the test */ 26 + SKIP_IF(platform_check_for_tests()); 27 + 28 + /* 29 + * PMC5/6 is excluded from constraint bit 30 + * check along with group of events. Use 31 + * group of events with PMC5, PMC6 and also 32 + * event with cache bit (dc_ic) set. Test expects 33 + * this set of events to go in as a group. 34 + */ 35 + e = &events[0]; 36 + event_init(e, 0x500fa); 37 + 38 + e = &events[1]; 39 + event_init(e, 0x600f4); 40 + 41 + e = &events[2]; 42 + event_init(e, 0x22C040); 43 + 44 + FAIL_IF(event_open(&events[0])); 45 + 46 + /* 47 + * The event_open will fail if constraint check fails. 48 + * Since we are asking for events in a group and since 49 + * PMC5/PMC6 is excluded from group constraints, even_open 50 + * should pass. 51 + */ 52 + for (i = 1; i < 3; i++) 53 + FAIL_IF(event_open_with_group(&events[i], events[0].fd)); 54 + 55 + for (i = 0; i < 3; i++) 56 + event_close(&events[i]); 57 + 58 + return 0; 59 + } 60 + 61 + int main(void) 62 + { 63 + return test_harness(group_pmc56_exclude_constraints, "group_pmc56_exclude_constraints"); 64 + }
+88
tools/testing/selftests/powerpc/pmu/event_code_tests/hw_cache_event_type_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "utils.h" 11 + #include "../sampling_tests/misc.h" 12 + 13 + /* 14 + * Load Missed L1, for power9 its pointing to PM_LD_MISS_L1_FIN (0x2c04e) and 15 + * for power10 its pointing to PM_LD_MISS_L1 (0x3e054) 16 + * 17 + * Hardware cache level : PERF_COUNT_HW_CACHE_L1D 18 + * Hardware cache event operation type : PERF_COUNT_HW_CACHE_OP_READ 19 + * Hardware cache event result type : PERF_COUNT_HW_CACHE_RESULT_MISS 20 + */ 21 + #define EventCode_1 0x10000 22 + /* 23 + * Hardware cache level : PERF_COUNT_HW_CACHE_L1D 24 + * Hardware cache event operation type : PERF_COUNT_HW_CACHE_OP_WRITE 25 + * Hardware cache event result type : PERF_COUNT_HW_CACHE_RESULT_ACCESS 26 + */ 27 + #define EventCode_2 0x0100 28 + /* 29 + * Hardware cache level : PERF_COUNT_HW_CACHE_DTLB 30 + * Hardware cache event operation type : PERF_COUNT_HW_CACHE_OP_WRITE 31 + * Hardware cache event result type : PERF_COUNT_HW_CACHE_RESULT_ACCESS 32 + */ 33 + #define EventCode_3 0x0103 34 + /* 35 + * Hardware cache level : PERF_COUNT_HW_CACHE_L1D 36 + * Hardware cache event operation type : PERF_COUNT_HW_CACHE_OP_READ 37 + * Hardware cache event result type : Invalid ( > PERF_COUNT_HW_CACHE_RESULT_MAX) 38 + */ 39 + #define EventCode_4 0x030000 40 + 41 + /* 42 + * A perf test to check valid hardware cache events. 43 + */ 44 + static int hw_cache_event_type_test(void) 45 + { 46 + struct event event; 47 + 48 + /* Check for platform support for the test */ 49 + SKIP_IF(platform_check_for_tests()); 50 + 51 + /* Skip for Generic compat PMU */ 52 + SKIP_IF(check_for_generic_compat_pmu()); 53 + 54 + /* Init the event to test hardware cache event */ 55 + event_init_opts(&event, EventCode_1, PERF_TYPE_HW_CACHE, "event"); 56 + 57 + /* Expected to success as its pointing to L1 load miss */ 58 + FAIL_IF(event_open(&event)); 59 + event_close(&event); 60 + 61 + /* Init the event to test hardware cache event */ 62 + event_init_opts(&event, EventCode_2, PERF_TYPE_HW_CACHE, "event"); 63 + 64 + /* Expected to fail as the corresponding cache event entry have 0 in that index */ 65 + FAIL_IF(!event_open(&event)); 66 + event_close(&event); 67 + 68 + /* Init the event to test hardware cache event */ 69 + event_init_opts(&event, EventCode_3, PERF_TYPE_HW_CACHE, "event"); 70 + 71 + /* Expected to fail as the corresponding cache event entry have -1 in that index */ 72 + FAIL_IF(!event_open(&event)); 73 + event_close(&event); 74 + 75 + /* Init the event to test hardware cache event */ 76 + event_init_opts(&event, EventCode_4, PERF_TYPE_HW_CACHE, "event"); 77 + 78 + /* Expected to fail as hardware cache event result type is Invalid */ 79 + FAIL_IF(!event_open(&event)); 80 + event_close(&event); 81 + 82 + return 0; 83 + } 84 + 85 + int main(void) 86 + { 87 + return test_harness(hw_cache_event_type_test, "hw_cache_event_type_test"); 88 + }
+67
tools/testing/selftests/powerpc/pmu/event_code_tests/invalid_event_code_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <sys/prctl.h> 8 + #include <limits.h> 9 + #include "../event.h" 10 + #include "../sampling_tests/misc.h" 11 + 12 + /* The data cache was reloaded from local core's L3 due to a demand load */ 13 + #define EventCode_1 0x1340000001c040 14 + /* PM_DATA_RADIX_PROCESS_L2_PTE_FROM_L2 */ 15 + #define EventCode_2 0x14242 16 + /* Event code with IFM, EBB, BHRB bits set in event code */ 17 + #define EventCode_3 0xf00000000000001e 18 + 19 + /* 20 + * Some of the bits in the event code is 21 + * reserved for specific platforms. 22 + * Event code bits 52-59 are reserved in power9, 23 + * whereas in power10, these are used for programming 24 + * Monitor Mode Control Register 3 (MMCR3). 25 + * Bit 9 in event code is reserved in power9, 26 + * whereas it is used for programming "radix_scope_qual" 27 + * bit 18 in Monitor Mode Control Register 1 (MMCR1). 28 + * 29 + * Testcase to ensure that using reserved bits in 30 + * event code should cause event_open to fail. 31 + */ 32 + 33 + static int invalid_event_code(void) 34 + { 35 + struct event event; 36 + 37 + /* Check for platform support for the test */ 38 + SKIP_IF(platform_check_for_tests()); 39 + 40 + /* 41 + * Events using MMCR3 bits and radix scope qual bits 42 + * should fail in power9 and should succeed in power10. 43 + * Init the events and check for pass/fail in event open. 44 + */ 45 + if (have_hwcap2(PPC_FEATURE2_ARCH_3_1)) { 46 + event_init(&event, EventCode_1); 47 + FAIL_IF(event_open(&event)); 48 + event_close(&event); 49 + 50 + event_init(&event, EventCode_2); 51 + FAIL_IF(event_open(&event)); 52 + event_close(&event); 53 + } else { 54 + event_init(&event, EventCode_1); 55 + FAIL_IF(!event_open(&event)); 56 + 57 + event_init(&event, EventCode_2); 58 + FAIL_IF(!event_open(&event)); 59 + } 60 + 61 + return 0; 62 + } 63 + 64 + int main(void) 65 + { 66 + return test_harness(invalid_event_code, "invalid_event_code"); 67 + }
+77
tools/testing/selftests/powerpc/pmu/event_code_tests/reserved_bits_mmcra_sample_elig_mode_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include "../event.h" 8 + #include "../sampling_tests/misc.h" 9 + 10 + /* 11 + * Testcase for reserved bits in Monitor Mode Control 12 + * Register A (MMCRA) Random Sampling Mode (SM) value. 13 + * As per Instruction Set Architecture (ISA), the values 14 + * 0x5, 0x9, 0xD, 0x19, 0x1D, 0x1A, 0x1E are reserved 15 + * for sampling mode field. Test that having these reserved 16 + * bit values should cause event_open to fail. 17 + * Input event code uses these sampling bits along with 18 + * 401e0 (PM_MRK_INST_CMPL). 19 + */ 20 + 21 + static int reserved_bits_mmcra_sample_elig_mode(void) 22 + { 23 + struct event event; 24 + 25 + /* Check for platform support for the test */ 26 + SKIP_IF(platform_check_for_tests()); 27 + 28 + /* Skip for Generic compat PMU */ 29 + SKIP_IF(check_for_generic_compat_pmu()); 30 + 31 + /* 32 + * MMCRA Random Sampling Mode (SM) values: 0x5 33 + * 0x9, 0xD, 0x19, 0x1D, 0x1A, 0x1E is reserved. 34 + * Expected to fail when using these reserved values. 35 + */ 36 + event_init(&event, 0x50401e0); 37 + FAIL_IF(!event_open(&event)); 38 + 39 + event_init(&event, 0x90401e0); 40 + FAIL_IF(!event_open(&event)); 41 + 42 + event_init(&event, 0xD0401e0); 43 + FAIL_IF(!event_open(&event)); 44 + 45 + event_init(&event, 0x190401e0); 46 + FAIL_IF(!event_open(&event)); 47 + 48 + event_init(&event, 0x1D0401e0); 49 + FAIL_IF(!event_open(&event)); 50 + 51 + event_init(&event, 0x1A0401e0); 52 + FAIL_IF(!event_open(&event)); 53 + 54 + event_init(&event, 0x1E0401e0); 55 + FAIL_IF(!event_open(&event)); 56 + 57 + /* 58 + * MMCRA Random Sampling Mode (SM) value 0x10 59 + * is reserved in power10 and 0xC is reserved in 60 + * power9. 61 + */ 62 + if (PVR_VER(mfspr(SPRN_PVR)) == POWER10) { 63 + event_init(&event, 0x100401e0); 64 + FAIL_IF(!event_open(&event)); 65 + } else if (PVR_VER(mfspr(SPRN_PVR)) == POWER9) { 66 + event_init(&event, 0xC0401e0); 67 + FAIL_IF(!event_open(&event)); 68 + } 69 + 70 + return 0; 71 + } 72 + 73 + int main(void) 74 + { 75 + return test_harness(reserved_bits_mmcra_sample_elig_mode, 76 + "reserved_bits_mmcra_sample_elig_mode"); 77 + }
+44
tools/testing/selftests/powerpc/pmu/event_code_tests/reserved_bits_mmcra_thresh_ctl_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include "../event.h" 8 + #include "../sampling_tests/misc.h" 9 + 10 + /* 11 + * Testcase for reserved bits in Monitor Mode 12 + * Control Register A (MMCRA) thresh_ctl bits. 13 + * For MMCRA[48:51]/[52:55]) Threshold Start/Stop, 14 + * 0b11110000/0b00001111 is reserved. 15 + */ 16 + 17 + static int reserved_bits_mmcra_thresh_ctl(void) 18 + { 19 + struct event event; 20 + 21 + /* Check for platform support for the test */ 22 + SKIP_IF(platform_check_for_tests()); 23 + 24 + /* Skip for Generic compat PMU */ 25 + SKIP_IF(check_for_generic_compat_pmu()); 26 + 27 + /* 28 + * MMCRA[48:51]/[52:55]) Threshold Start/Stop 29 + * events Selection. 0b11110000/0b00001111 is reserved. 30 + * Expected to fail when using these reserved values. 31 + */ 32 + event_init(&event, 0xf0340401e0); 33 + FAIL_IF(!event_open(&event)); 34 + 35 + event_init(&event, 0x0f340401e0); 36 + FAIL_IF(!event_open(&event)); 37 + 38 + return 0; 39 + } 40 + 41 + int main(void) 42 + { 43 + return test_harness(reserved_bits_mmcra_thresh_ctl, "reserved_bits_mmcra_thresh_ctl"); 44 + }
+5 -2
tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile
··· 4 4 TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test \ 5 5 mmcr0_pmcjce_test mmcr0_fc56_pmc1ce_test mmcr0_fc56_pmc56_test \ 6 6 mmcr1_comb_test mmcr2_l2l3_test mmcr2_fcs_fch_test \ 7 - mmcr3_src_test mmcra_thresh_marked_sample_test 7 + mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test \ 8 + mmcra_bhrb_ind_call_test mmcra_bhrb_any_test mmcra_bhrb_cond_test \ 9 + mmcra_bhrb_disable_test bhrb_no_crash_wo_pmu_test intr_regs_no_crash_wo_pmu_test \ 10 + bhrb_filter_map_test mmcr1_sel_unit_cache_test mmcra_bhrb_disable_no_branch_test 8 11 9 12 top_srcdir = ../../../../../.. 10 13 include ../../../lib.mk 11 14 12 - $(TEST_GEN_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c misc.c misc.h ../loop.S 15 + $(TEST_GEN_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c misc.c misc.h ../loop.S ../branch_loops.S
+105
tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_filter_map_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "misc.h" 11 + #include "utils.h" 12 + 13 + /* 14 + * A perf sampling test to check bhrb filter 15 + * map. All the branch filters are not supported 16 + * in powerpc. Supported filters in: 17 + * power10: any, any_call, ind_call, cond 18 + * power9: any, any_call 19 + * 20 + * Testcase checks event open for invalid bhrb filter 21 + * types should fail and valid filter types should pass. 22 + * Testcase does validity check for these branch 23 + * sample types. 24 + */ 25 + 26 + /* Invalid types for powerpc */ 27 + /* Valid bhrb filters in power9/power10 */ 28 + int bhrb_filter_map_valid_common[] = { 29 + PERF_SAMPLE_BRANCH_ANY, 30 + PERF_SAMPLE_BRANCH_ANY_CALL, 31 + }; 32 + 33 + /* Valid bhrb filters in power10 */ 34 + int bhrb_filter_map_valid_p10[] = { 35 + PERF_SAMPLE_BRANCH_IND_CALL, 36 + PERF_SAMPLE_BRANCH_COND, 37 + }; 38 + 39 + #define EventCode 0x1001e 40 + 41 + static int bhrb_filter_map_test(void) 42 + { 43 + struct event event; 44 + int i; 45 + 46 + /* Check for platform support for the test */ 47 + SKIP_IF(platform_check_for_tests()); 48 + 49 + /* 50 + * Skip for Generic compat PMU since 51 + * bhrb filters is not supported 52 + */ 53 + SKIP_IF(check_for_generic_compat_pmu()); 54 + 55 + /* Init the event for the sampling test */ 56 + event_init(&event, EventCode); 57 + 58 + event.attr.sample_period = 1000; 59 + event.attr.sample_type = PERF_SAMPLE_BRANCH_STACK; 60 + event.attr.disabled = 1; 61 + 62 + /* Invalid filter maps which are expected to fail in event_open */ 63 + for (i = PERF_SAMPLE_BRANCH_USER_SHIFT; i < PERF_SAMPLE_BRANCH_MAX_SHIFT; i++) { 64 + /* Skip the valid branch sample type */ 65 + if (i == PERF_SAMPLE_BRANCH_ANY_SHIFT || i == PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT \ 66 + || i == PERF_SAMPLE_BRANCH_IND_CALL_SHIFT || i == PERF_SAMPLE_BRANCH_COND_SHIFT) 67 + continue; 68 + event.attr.branch_sample_type = 1U << i; 69 + FAIL_IF(!event_open(&event)); 70 + } 71 + 72 + /* valid filter maps for power9/power10 which are expected to pass in event_open */ 73 + for (i = 0; i < ARRAY_SIZE(bhrb_filter_map_valid_common); i++) { 74 + event.attr.branch_sample_type = bhrb_filter_map_valid_common[i]; 75 + FAIL_IF(event_open(&event)); 76 + event_close(&event); 77 + } 78 + 79 + /* 80 + * filter maps which are valid in power10 and invalid in power9. 81 + * PVR check is used here since PMU specific data like bhrb filter 82 + * alternative tests is handled by respective PMU driver code and 83 + * using PVR will work correctly for all cases including generic 84 + * compat mode. 85 + */ 86 + if (PVR_VER(mfspr(SPRN_PVR)) == POWER10) { 87 + for (i = 0; i < ARRAY_SIZE(bhrb_filter_map_valid_p10); i++) { 88 + event.attr.branch_sample_type = bhrb_filter_map_valid_p10[i]; 89 + FAIL_IF(event_open(&event)); 90 + event_close(&event); 91 + } 92 + } else { 93 + for (i = 0; i < ARRAY_SIZE(bhrb_filter_map_valid_p10); i++) { 94 + event.attr.branch_sample_type = bhrb_filter_map_valid_p10[i]; 95 + FAIL_IF(!event_open(&event)); 96 + } 97 + } 98 + 99 + return 0; 100 + } 101 + 102 + int main(void) 103 + { 104 + return test_harness(bhrb_filter_map_test, "bhrb_filter_map_test"); 105 + }
+59
tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_no_crash_wo_pmu_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "misc.h" 11 + #include "utils.h" 12 + 13 + /* 14 + * A perf sampling test for making sure 15 + * enabling branch stack doesn't crash in any 16 + * environment, say: 17 + * - With generic compat PMU 18 + * - without any PMU registered 19 + * - With platform specific PMU 20 + * A fix for bhrb sampling crash was added in kernel 21 + * via commit: b460b512417a ("powerpc/perf: Fix crashes 22 + * with generic_compat_pmu & BHRB") 23 + * 24 + * This testcase exercises this code by doing branch 25 + * stack enable for software event. s/w event is used 26 + * since software event will work even in platform 27 + * without PMU. 28 + */ 29 + static int bhrb_no_crash_wo_pmu_test(void) 30 + { 31 + struct event event; 32 + 33 + /* 34 + * Init the event for the sampling test. 35 + * This uses software event which works on 36 + * any platform. 37 + */ 38 + event_init_opts(&event, 0, PERF_TYPE_SOFTWARE, "cycles"); 39 + 40 + event.attr.sample_period = 1000; 41 + event.attr.sample_type = PERF_SAMPLE_BRANCH_STACK; 42 + event.attr.disabled = 1; 43 + 44 + /* 45 + * Return code of event_open is not 46 + * considered since test just expects no crash from 47 + * using PERF_SAMPLE_BRANCH_STACK. Also for environment 48 + * like generic compat PMU, branch stack is unsupported. 49 + */ 50 + event_open(&event); 51 + 52 + event_close(&event); 53 + return 0; 54 + } 55 + 56 + int main(void) 57 + { 58 + return test_harness(bhrb_no_crash_wo_pmu_test, "bhrb_no_crash_wo_pmu_test"); 59 + }
+57
tools/testing/selftests/powerpc/pmu/sampling_tests/intr_regs_no_crash_wo_pmu_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "misc.h" 11 + #include "utils.h" 12 + 13 + /* 14 + * A perf sampling test for making sure 15 + * sampling with -intr-regs doesn't crash 16 + * in any environment, say: 17 + * - With generic compat PMU 18 + * - without any PMU registered 19 + * - With platform specific PMU. 20 + * A fix for crash with intr_regs was 21 + * addressed in commit: f75e7d73bdf7 in kernel. 22 + * 23 + * This testcase exercises this code path by doing 24 + * intr_regs using software event. Software event is 25 + * used since s/w event will work even in platform 26 + * without PMU. 27 + */ 28 + static int intr_regs_no_crash_wo_pmu_test(void) 29 + { 30 + struct event event; 31 + 32 + /* 33 + * Init the event for the sampling test. 34 + * This uses software event which works on 35 + * any platform. 36 + */ 37 + event_init_opts(&event, 0, PERF_TYPE_SOFTWARE, "cycles"); 38 + 39 + event.attr.sample_period = 1000; 40 + event.attr.sample_type = PERF_SAMPLE_REGS_INTR; 41 + event.attr.disabled = 1; 42 + 43 + /* 44 + * Return code of event_open is not considered 45 + * since test just expects no crash from using 46 + * PERF_SAMPLE_REGS_INTR. 47 + */ 48 + event_open(&event); 49 + 50 + event_close(&event); 51 + return 0; 52 + } 53 + 54 + int main(void) 55 + { 56 + return test_harness(intr_regs_no_crash_wo_pmu_test, "intr_regs_no_crash_wo_pmu_test"); 57 + }
+130 -5
tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c
··· 60 60 61 61 switch (pvr) { 62 62 case POWER10: 63 + ev_mask_thd_cmp = 0x3ffff; 64 + ev_shift_thd_cmp = 0; 63 65 ev_mask_rsq = 1; 64 66 ev_shift_rsq = 9; 65 67 ev_mask_comb = 3; ··· 121 119 return -1; 122 120 } 123 121 124 - int check_pvr_for_sampling_tests(void) 122 + int platform_check_for_tests(void) 125 123 { 126 124 pvr = PVR_VER(mfspr(SPRN_PVR)); 127 - 128 - platform_extended_mask = perf_get_platform_reg_mask(); 129 125 130 126 /* 131 127 * Check for supported platforms ··· 136 136 * Check PMU driver registered by looking for 137 137 * PPC_FEATURE2_EBB bit in AT_HWCAP2 138 138 */ 139 - if (!have_hwcap2(PPC_FEATURE2_EBB)) 139 + if (!have_hwcap2(PPC_FEATURE2_EBB) || !have_hwcap2(PPC_FEATURE2_ARCH_3_00)) 140 140 goto out; 141 141 142 + return 0; 143 + 144 + out: 145 + printf("%s: Tests unsupported for this platform\n", __func__); 146 + return -1; 147 + } 148 + 149 + int check_pvr_for_sampling_tests(void) 150 + { 151 + SKIP_IF(platform_check_for_tests()); 152 + 153 + platform_extended_mask = perf_get_platform_reg_mask(); 142 154 /* check if platform supports extended regs */ 143 155 if (check_extended_regs_support()) 144 156 goto out; 145 157 146 158 init_ev_encodes(); 147 159 return 0; 160 + 148 161 out: 149 162 printf("%s: Sampling tests un-supported\n", __func__); 150 163 return -1; 151 164 } 165 + 152 166 /* 153 167 * Allocate mmap buffer of "mmap_pages" number of 154 168 * pages. ··· 271 257 u64 *intr_regs; 272 258 size_t size = 0; 273 259 274 - if ((type ^ PERF_SAMPLE_REGS_INTR)) 260 + if ((type ^ (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_BRANCH_STACK)) && 261 + (type ^ PERF_SAMPLE_REGS_INTR)) 275 262 return NULL; 276 263 277 264 intr_regs = (u64 *)perf_read_first_sample(sample_buff, &size); 278 265 if (!intr_regs) 279 266 return NULL; 267 + 268 + if (type & PERF_SAMPLE_BRANCH_STACK) { 269 + /* 270 + * PERF_RECORD_SAMPLE and PERF_SAMPLE_BRANCH_STACK: 271 + * struct { 272 + * struct perf_event_header hdr; 273 + * u64 number_of_branches; 274 + * struct perf_branch_entry[number_of_branches]; 275 + * u64 data[]; 276 + * }; 277 + * struct perf_branch_entry { 278 + * u64 from; 279 + * u64 to; 280 + * u64 misc; 281 + * }; 282 + */ 283 + intr_regs += ((*intr_regs) * 3) + 1; 284 + } 280 285 281 286 /* 282 287 * First entry in the sample buffer used to specify ··· 442 409 return -1; 443 410 444 411 return *(intr_regs + register_bit_position); 412 + } 413 + 414 + int get_thresh_cmp_val(struct event event) 415 + { 416 + int exp = 0; 417 + u64 result = 0; 418 + u64 value; 419 + 420 + if (!have_hwcap2(PPC_FEATURE2_ARCH_3_1)) 421 + return EV_CODE_EXTRACT(event.attr.config, thd_cmp); 422 + 423 + value = EV_CODE_EXTRACT(event.attr.config1, thd_cmp); 424 + 425 + if (!value) 426 + return value; 427 + 428 + /* 429 + * Incase of P10, thresh_cmp value is not part of raw event code 430 + * and provided via attr.config1 parameter. To program threshold in MMCRA, 431 + * take a 18 bit number N and shift right 2 places and increment 432 + * the exponent E by 1 until the upper 10 bits of N are zero. 433 + * Write E to the threshold exponent and write the lower 8 bits of N 434 + * to the threshold mantissa. 435 + * The max threshold that can be written is 261120. 436 + */ 437 + if (value > 261120) 438 + value = 261120; 439 + while ((64 - __builtin_clzl(value)) > 8) { 440 + exp++; 441 + value >>= 2; 442 + } 443 + 444 + /* 445 + * Note that it is invalid to write a mantissa with the 446 + * upper 2 bits of mantissa being zero, unless the 447 + * exponent is also zero. 448 + */ 449 + if (!(value & 0xC0) && exp) 450 + result = -1; 451 + else 452 + result = (exp << 8) | value; 453 + return result; 454 + } 455 + 456 + /* 457 + * Utility function to check for generic compat PMU 458 + * by comparing base_platform value from auxv and real 459 + * PVR value. 460 + */ 461 + static bool auxv_generic_compat_pmu(void) 462 + { 463 + int base_pvr = 0; 464 + 465 + if (!strcmp(auxv_base_platform(), "power9")) 466 + base_pvr = POWER9; 467 + else if (!strcmp(auxv_base_platform(), "power10")) 468 + base_pvr = POWER10; 469 + 470 + return (!base_pvr); 471 + } 472 + 473 + /* 474 + * Check for generic compat PMU. 475 + * First check for presence of pmu_name from 476 + * "/sys/bus/event_source/devices/cpu/caps". 477 + * If doesn't exist, fallback to using value 478 + * auxv. 479 + */ 480 + bool check_for_generic_compat_pmu(void) 481 + { 482 + char pmu_name[256]; 483 + 484 + memset(pmu_name, 0, sizeof(pmu_name)); 485 + if (read_sysfs_file("bus/event_source/devices/cpu/caps/pmu_name", 486 + pmu_name, sizeof(pmu_name)) < 0) 487 + return auxv_generic_compat_pmu(); 488 + 489 + if (!strcmp(pmu_name, "ISAv3")) 490 + return true; 491 + else 492 + return false; 493 + } 494 + 495 + /* 496 + * Check if system is booted in compat mode. 497 + */ 498 + bool check_for_compat_mode(void) 499 + { 500 + char *platform = auxv_platform(); 501 + char *base_platform = auxv_base_platform(); 502 + 503 + return strcmp(platform, base_platform); 445 504 }
+8 -1
tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h
··· 5 5 * Copyright 2022, Kajol Jain, IBM Corp. 6 6 */ 7 7 8 + #include <sys/stat.h> 8 9 #include "../event.h" 9 10 10 11 #define POWER10 0x80 ··· 17 16 #define MMCR0_PMCCEXT 0x00000200UL /* PMCCEXT control */ 18 17 #define MMCR1_RSQ 0x200000000000ULL /* radix scope qual field */ 19 18 #define BHRB_DISABLE 0x2000000000ULL /* MMCRA BHRB DISABLE bit */ 19 + 20 + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 20 21 21 22 extern int ev_mask_pmcxsel, ev_shift_pmcxsel; 22 23 extern int ev_mask_marked, ev_shift_marked; ··· 38 35 extern int pvr; 39 36 extern u64 platform_extended_mask; 40 37 extern int check_pvr_for_sampling_tests(void); 38 + extern int platform_check_for_tests(void); 41 39 42 40 /* 43 41 * Event code field extraction macro. ··· 56 52 int collect_samples(void *sample_buff); 57 53 u64 *get_intr_regs(struct event *event, void *sample_buff); 58 54 u64 get_reg_value(u64 *intr_regs, char *register_name); 55 + int get_thresh_cmp_val(struct event event); 56 + bool check_for_generic_compat_pmu(void); 57 + bool check_for_compat_mode(void); 59 58 60 59 static inline int get_mmcr0_fc56(u64 mmcr0, int pmc) 61 60 { ··· 191 184 return ((mmcra >> 42) & 0x3); 192 185 } 193 186 194 - static inline int get_mmcra_bhrb_disable(u64 mmcra, int pmc) 187 + static inline u64 get_mmcra_bhrb_disable(u64 mmcra, int pmc) 195 188 { 196 189 if (pvr == POWER10) 197 190 return mmcra & BHRB_DISABLE;
+77
tools/testing/selftests/powerpc/pmu/sampling_tests/mmcr1_sel_unit_cache_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Athira Rajeev, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "misc.h" 11 + #include "utils.h" 12 + 13 + #define MALLOC_SIZE (0x10000 * 10) /* Ought to be enough .. */ 14 + 15 + /* The data cache was reloaded from local core's L3 due to a demand load */ 16 + #define EventCode 0x21c040 17 + 18 + /* 19 + * A perf sampling test for mmcr1 20 + * fields : pmcxsel, unit, cache. 21 + */ 22 + static int mmcr1_sel_unit_cache(void) 23 + { 24 + struct event event; 25 + u64 *intr_regs; 26 + char *p; 27 + int i; 28 + 29 + /* Check for platform support for the test */ 30 + SKIP_IF(check_pvr_for_sampling_tests()); 31 + 32 + p = malloc(MALLOC_SIZE); 33 + FAIL_IF(!p); 34 + 35 + /* Init the event for the sampling test */ 36 + event_init_sampling(&event, EventCode); 37 + event.attr.sample_regs_intr = platform_extended_mask; 38 + event.attr.sample_period = 1; 39 + FAIL_IF(event_open(&event)); 40 + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); 41 + 42 + event_enable(&event); 43 + 44 + /* workload to make the event overflow */ 45 + for (i = 0; i < MALLOC_SIZE; i += 0x10000) 46 + p[i] = i; 47 + 48 + event_disable(&event); 49 + 50 + /* Check for sample count */ 51 + FAIL_IF(!collect_samples(event.mmap_buffer)); 52 + 53 + intr_regs = get_intr_regs(&event, event.mmap_buffer); 54 + 55 + /* Check for intr_regs */ 56 + FAIL_IF(!intr_regs); 57 + 58 + /* 59 + * Verify that pmcxsel, unit and cache field of MMCR1 60 + * match with corresponding event code fields 61 + */ 62 + FAIL_IF(EV_CODE_EXTRACT(event.attr.config, pmcxsel) != 63 + get_mmcr1_pmcxsel(get_reg_value(intr_regs, "MMCR1"), 1)); 64 + FAIL_IF(EV_CODE_EXTRACT(event.attr.config, unit) != 65 + get_mmcr1_unit(get_reg_value(intr_regs, "MMCR1"), 1)); 66 + FAIL_IF(EV_CODE_EXTRACT(event.attr.config, cache) != 67 + get_mmcr1_cache(get_reg_value(intr_regs, "MMCR1"), 1)); 68 + 69 + free(p); 70 + event_close(&event); 71 + return 0; 72 + } 73 + 74 + int main(void) 75 + { 76 + FAIL_IF(test_harness(mmcr1_sel_unit_cache, "mmcr1_sel_unit_cache")); 77 + }
+65
tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_any_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "misc.h" 11 + #include "utils.h" 12 + 13 + extern void thirty_two_instruction_loop(int loops); 14 + 15 + /* Instructions */ 16 + #define EventCode 0x500fa 17 + 18 + /* ifm field for any branch mode */ 19 + #define IFM_ANY_BRANCH 0x0 20 + 21 + /* 22 + * A perf sampling test for mmcra 23 + * field: ifm for bhrb any call. 24 + */ 25 + static int mmcra_bhrb_any_test(void) 26 + { 27 + struct event event; 28 + u64 *intr_regs; 29 + 30 + /* Check for platform support for the test */ 31 + SKIP_IF(check_pvr_for_sampling_tests()); 32 + 33 + /* Init the event for the sampling test */ 34 + event_init_sampling(&event, EventCode); 35 + event.attr.sample_regs_intr = platform_extended_mask; 36 + event.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK; 37 + event.attr.branch_sample_type = PERF_SAMPLE_BRANCH_ANY; 38 + event.attr.exclude_kernel = 1; 39 + 40 + FAIL_IF(event_open(&event)); 41 + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); 42 + 43 + FAIL_IF(event_enable(&event)); 44 + 45 + /* workload to make the event overflow */ 46 + thirty_two_instruction_loop(10000); 47 + 48 + FAIL_IF(event_disable(&event)); 49 + 50 + intr_regs = get_intr_regs(&event, event.mmap_buffer); 51 + 52 + /* Check for intr_regs */ 53 + FAIL_IF(!intr_regs); 54 + 55 + /* Verify that ifm bit is set properly in MMCRA */ 56 + FAIL_IF(get_mmcra_ifm(get_reg_value(intr_regs, "MMCRA"), 5) != IFM_ANY_BRANCH); 57 + 58 + event_close(&event); 59 + return 0; 60 + } 61 + 62 + int main(void) 63 + { 64 + return test_harness(mmcra_bhrb_any_test, "mmcra_bhrb_any_test"); 65 + }
+69
tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_cond_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "misc.h" 11 + #include "utils.h" 12 + 13 + extern void thirty_two_instruction_loop(int loops); 14 + 15 + /* Instructions */ 16 + #define EventCode 0x500fa 17 + 18 + /* ifm field for conditional branch mode */ 19 + #define IFM_COND_BRANCH 0x3 20 + 21 + /* 22 + * A perf sampling test for mmcra 23 + * field: ifm for bhrb cond call. 24 + */ 25 + static int mmcra_bhrb_cond_test(void) 26 + { 27 + struct event event; 28 + u64 *intr_regs; 29 + 30 + /* 31 + * Check for platform support for the test. 32 + * This test is only aplicable on power10 33 + */ 34 + SKIP_IF(check_pvr_for_sampling_tests()); 35 + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 36 + 37 + /* Init the event for the sampling test */ 38 + event_init_sampling(&event, EventCode); 39 + event.attr.sample_regs_intr = platform_extended_mask; 40 + event.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK; 41 + event.attr.branch_sample_type = PERF_SAMPLE_BRANCH_COND; 42 + event.attr.exclude_kernel = 1; 43 + 44 + FAIL_IF(event_open(&event)); 45 + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); 46 + 47 + FAIL_IF(event_enable(&event)); 48 + 49 + /* workload to make the event overflow */ 50 + thirty_two_instruction_loop(10000); 51 + 52 + FAIL_IF(event_disable(&event)); 53 + 54 + intr_regs = get_intr_regs(&event, event.mmap_buffer); 55 + 56 + /* Check for intr_regs */ 57 + FAIL_IF(!intr_regs); 58 + 59 + /* Verify that ifm bit is set properly in MMCRA */ 60 + FAIL_IF(get_mmcra_ifm(get_reg_value(intr_regs, "MMCRA"), 5) != IFM_COND_BRANCH); 61 + 62 + event_close(&event); 63 + return 0; 64 + } 65 + 66 + int main(void) 67 + { 68 + return test_harness(mmcra_bhrb_cond_test, "mmcra_bhrb_cond_test"); 69 + }
+64
tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_disable_no_branch_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "misc.h" 11 + #include "utils.h" 12 + 13 + extern void thirty_two_instruction_loop(int loops); 14 + 15 + /* Instructions */ 16 + #define EventCode 0x500fa 17 + 18 + /* 19 + * A perf sampling test for mmcra 20 + * field: bhrb_disable. 21 + */ 22 + static int mmcra_bhrb_disable_no_branch_test(void) 23 + { 24 + struct event event; 25 + u64 *intr_regs; 26 + 27 + /* 28 + * Check for platform support for the test. 29 + * This test is only aplicable on power10 30 + */ 31 + SKIP_IF(check_pvr_for_sampling_tests()); 32 + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 33 + 34 + /* Init the event for the sampling test */ 35 + event_init_sampling(&event, EventCode); 36 + event.attr.sample_regs_intr = platform_extended_mask; 37 + event.attr.exclude_kernel = 1; 38 + 39 + FAIL_IF(event_open(&event)); 40 + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); 41 + 42 + FAIL_IF(event_enable(&event)); 43 + 44 + /* workload to make the event overflow */ 45 + thirty_two_instruction_loop(10000); 46 + 47 + FAIL_IF(event_disable(&event)); 48 + 49 + intr_regs = get_intr_regs(&event, event.mmap_buffer); 50 + 51 + /* Check for intr_regs */ 52 + FAIL_IF(!intr_regs); 53 + 54 + /* Verify that bhrb_disable bit is set in MMCRA for non-branch samples */ 55 + FAIL_IF(!get_mmcra_bhrb_disable(get_reg_value(intr_regs, "MMCRA"), 5)); 56 + 57 + event_close(&event); 58 + return 0; 59 + } 60 + 61 + int main(void) 62 + { 63 + return test_harness(mmcra_bhrb_disable_no_branch_test, "mmcra_bhrb_disable_no_branch_test"); 64 + }
+66
tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_disable_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "misc.h" 11 + #include "utils.h" 12 + 13 + extern void thirty_two_instruction_loop(int loops); 14 + 15 + /* Instructions */ 16 + #define EventCode 0x500fa 17 + 18 + /* 19 + * A perf sampling test for mmcra 20 + * field: bhrb_disable. 21 + */ 22 + static int mmcra_bhrb_disable_test(void) 23 + { 24 + struct event event; 25 + u64 *intr_regs; 26 + 27 + /* 28 + * Check for platform support for the test. 29 + * This test is only aplicable on power10 30 + */ 31 + SKIP_IF(check_pvr_for_sampling_tests()); 32 + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 33 + 34 + /* Init the event for the sampling test */ 35 + event_init_sampling(&event, EventCode); 36 + event.attr.sample_regs_intr = platform_extended_mask; 37 + event.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK; 38 + event.attr.branch_sample_type = PERF_SAMPLE_BRANCH_ANY; 39 + event.attr.exclude_kernel = 1; 40 + 41 + FAIL_IF(event_open(&event)); 42 + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); 43 + 44 + FAIL_IF(event_enable(&event)); 45 + 46 + /* workload to make the event overflow */ 47 + thirty_two_instruction_loop(10000); 48 + 49 + FAIL_IF(event_disable(&event)); 50 + 51 + intr_regs = get_intr_regs(&event, event.mmap_buffer); 52 + 53 + /* Check for intr_regs */ 54 + FAIL_IF(!intr_regs); 55 + 56 + /* Verify that bhrb_disable bit is set in MMCRA */ 57 + FAIL_IF(get_mmcra_bhrb_disable(get_reg_value(intr_regs, "MMCRA"), 5)); 58 + 59 + event_close(&event); 60 + return 0; 61 + } 62 + 63 + int main(void) 64 + { 65 + return test_harness(mmcra_bhrb_disable_test, "mmcra_bhrb_disable_test"); 66 + }
+69
tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_ind_call_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "misc.h" 11 + #include "utils.h" 12 + 13 + extern void indirect_branch_loop(void); 14 + 15 + /* Instructions */ 16 + #define EventCode 0x500fa 17 + 18 + /* ifm field for indirect branch mode */ 19 + #define IFM_IND_BRANCH 0x2 20 + 21 + /* 22 + * A perf sampling test for mmcra 23 + * field: ifm for bhrb ind_call. 24 + */ 25 + static int mmcra_bhrb_ind_call_test(void) 26 + { 27 + struct event event; 28 + u64 *intr_regs; 29 + 30 + /* 31 + * Check for platform support for the test. 32 + * This test is only aplicable on power10 33 + */ 34 + SKIP_IF(check_pvr_for_sampling_tests()); 35 + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 36 + 37 + /* Init the event for the sampling test */ 38 + event_init_sampling(&event, EventCode); 39 + event.attr.sample_regs_intr = platform_extended_mask; 40 + event.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK; 41 + event.attr.branch_sample_type = PERF_SAMPLE_BRANCH_IND_CALL; 42 + event.attr.exclude_kernel = 1; 43 + 44 + FAIL_IF(event_open(&event)); 45 + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); 46 + 47 + FAIL_IF(event_enable(&event)); 48 + 49 + /* workload to make the event overflow */ 50 + indirect_branch_loop(); 51 + 52 + FAIL_IF(event_disable(&event)); 53 + 54 + intr_regs = get_intr_regs(&event, event.mmap_buffer); 55 + 56 + /* Check for intr_regs */ 57 + FAIL_IF(!intr_regs); 58 + 59 + /* Verify that ifm bit is set properly in MMCRA */ 60 + FAIL_IF(get_mmcra_ifm(get_reg_value(intr_regs, "MMCRA"), 5) != IFM_IND_BRANCH); 61 + 62 + event_close(&event); 63 + return 0; 64 + } 65 + 66 + int main(void) 67 + { 68 + return test_harness(mmcra_bhrb_ind_call_test, "mmcra_bhrb_ind_call_test"); 69 + }
+74
tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_cmp_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2022, Kajol Jain, IBM Corp. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "../event.h" 10 + #include "misc.h" 11 + #include "utils.h" 12 + 13 + /* 14 + * Primary PMU event used here is PM_MRK_INST_CMPL (0x401e0) 15 + * Threshold event selection used is issue to complete for cycles 16 + * Sampling criteria is Load only sampling 17 + */ 18 + #define p9_EventCode 0x13E35340401e0 19 + #define p10_EventCode 0x35340401e0 20 + 21 + extern void thirty_two_instruction_loop_with_ll_sc(u64 loops, u64 *ll_sc_target); 22 + 23 + /* A perf sampling test to test mmcra fields */ 24 + static int mmcra_thresh_cmp(void) 25 + { 26 + struct event event; 27 + u64 *intr_regs; 28 + u64 dummy; 29 + 30 + /* Check for platform support for the test */ 31 + SKIP_IF(check_pvr_for_sampling_tests()); 32 + 33 + /* Skip for comapt mode */ 34 + SKIP_IF(check_for_compat_mode()); 35 + 36 + /* Init the event for the sampling test */ 37 + if (!have_hwcap2(PPC_FEATURE2_ARCH_3_1)) { 38 + event_init_sampling(&event, p9_EventCode); 39 + } else { 40 + event_init_sampling(&event, p10_EventCode); 41 + event.attr.config1 = 1000; 42 + } 43 + 44 + event.attr.sample_regs_intr = platform_extended_mask; 45 + FAIL_IF(event_open(&event)); 46 + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); 47 + 48 + FAIL_IF(event_enable(&event)); 49 + 50 + /* workload to make the event overflow */ 51 + thirty_two_instruction_loop_with_ll_sc(1000000, &dummy); 52 + 53 + FAIL_IF(event_disable(&event)); 54 + 55 + /* Check for sample count */ 56 + FAIL_IF(!collect_samples(event.mmap_buffer)); 57 + 58 + intr_regs = get_intr_regs(&event, event.mmap_buffer); 59 + 60 + /* Check for intr_regs */ 61 + FAIL_IF(!intr_regs); 62 + 63 + /* Verify that thresh cmp match with the corresponding event code fields */ 64 + FAIL_IF(get_thresh_cmp_val(event) != 65 + get_mmcra_thd_cmp(get_reg_value(intr_regs, "MMCRA"), 4)); 66 + 67 + event_close(&event); 68 + return 0; 69 + } 70 + 71 + int main(void) 72 + { 73 + FAIL_IF(test_harness(mmcra_thresh_cmp, "mmcra_thresh_cmp")); 74 + }
+33 -7
tools/testing/selftests/powerpc/ptrace/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 - TEST_GEN_PROGS := ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \ 3 - ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx ptrace-tm-vsx \ 4 - ptrace-tm-spd-vsx ptrace-tm-spr ptrace-hwbreak ptrace-pkey core-pkey \ 5 - perf-hwbreak ptrace-syscall ptrace-perf-hwbreak 2 + 3 + TM_TESTS := ptrace-tm-gpr 4 + TM_TESTS += ptrace-tm-spd-gpr 5 + TM_TESTS += ptrace-tm-spd-tar 6 + TM_TESTS += ptrace-tm-spd-vsx 7 + TM_TESTS += ptrace-tm-spr 8 + TM_TESTS += ptrace-tm-tar 9 + TM_TESTS += ptrace-tm-vsx 10 + 11 + TESTS_64 := $(TM_TESTS) 12 + TESTS_64 += core-pkey 13 + TESTS_64 += perf-hwbreak 14 + TESTS_64 += ptrace-hwbreak 15 + TESTS_64 += ptrace-perf-hwbreak 16 + TESTS_64 += ptrace-pkey 17 + TESTS_64 += ptrace-syscall 18 + TESTS_64 += ptrace-tar 19 + TESTS_64 += ptrace-vsx 20 + 21 + TESTS += ptrace-gpr 22 + 23 + TEST_GEN_PROGS := $(TESTS) $(TESTS_64) 24 + 25 + LOCAL_HDRS += $(patsubst %,$(selfdir)/powerpc/ptrace/%,$(wildcard *.h)) 6 26 7 27 top_srcdir = ../../../../.. 8 28 include ../../lib.mk 9 29 10 - CFLAGS += -m64 -I../../../../../usr/include -I../tm -mhtm -fno-pie 30 + TM_TESTS := $(patsubst %,$(OUTPUT)/%,$(TM_TESTS)) 31 + TESTS_64 := $(patsubst %,$(OUTPUT)/%,$(TESTS_64)) 11 32 12 - $(OUTPUT)/ptrace-pkey $(OUTPUT)/core-pkey: child.h 33 + $(TESTS_64): CFLAGS += -m64 34 + $(TM_TESTS): CFLAGS += -I../tm -mhtm 35 + 36 + CFLAGS += -I../../../../../usr/include -fno-pie 37 + 38 + $(OUTPUT)/ptrace-gpr: ptrace-gpr.S 13 39 $(OUTPUT)/ptrace-pkey $(OUTPUT)/core-pkey: LDLIBS += -pthread 14 40 15 - $(TEST_GEN_PROGS): ../harness.c ../utils.c ../lib/reg.S ptrace.h 41 + $(TEST_GEN_PROGS): ../harness.c ../utils.c ../lib/reg.S
+52
tools/testing/selftests/powerpc/ptrace/ptrace-gpr.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * test helper assembly functions 4 + * 5 + * Copyright (C) 2016 Simon Guo, IBM Corporation. 6 + * Copyright 2022 Michael Ellerman, IBM Corporation. 7 + */ 8 + #include "basic_asm.h" 9 + 10 + #define GPR_SIZE __SIZEOF_LONG__ 11 + #define FIRST_GPR 14 12 + #define NUM_GPRS (32 - FIRST_GPR) 13 + #define STACK_SIZE (NUM_GPRS * GPR_SIZE) 14 + 15 + // gpr_child_loop(int *read_flag, int *write_flag, 16 + // unsigned long *gpr_buf, double *fpr_buf); 17 + FUNC_START(gpr_child_loop) 18 + // r3 = read_flag 19 + // r4 = write_flag 20 + // r5 = gpr_buf 21 + // r6 = fpr_buf 22 + PUSH_BASIC_STACK(STACK_SIZE) 23 + 24 + // Save non-volatile GPRs 25 + OP_REGS PPC_STL, GPR_SIZE, FIRST_GPR, 31, %r1, STACK_FRAME_LOCAL(0, 0), FIRST_GPR 26 + 27 + // Load GPRs with expected values 28 + OP_REGS PPC_LL, GPR_SIZE, FIRST_GPR, 31, r5, 0, FIRST_GPR 29 + 30 + // Load FPRs with expected values 31 + OP_REGS lfd, 8, 0, 31, r6 32 + 33 + // Signal to parent that we're ready 34 + li r0, 1 35 + stw r0, 0(r4) 36 + 37 + // Wait for parent to finish 38 + 1: lwz r0, 0(r3) 39 + cmpwi r0, 0 40 + beq 1b // Loop while flag is zero 41 + 42 + // Save GPRs back to caller buffer 43 + OP_REGS PPC_STL, GPR_SIZE, FIRST_GPR, 31, r5, 0, FIRST_GPR 44 + 45 + // Save FPRs 46 + OP_REGS stfd, 8, 0, 31, r6 47 + 48 + // Reload non-volatile GPRs 49 + OP_REGS PPC_LL, GPR_SIZE, FIRST_GPR, 31, %r1, STACK_FRAME_LOCAL(0, 0), FIRST_GPR 50 + 51 + POP_BASIC_STACK(STACK_SIZE) 52 + blr
+90 -35
tools/testing/selftests/powerpc/ptrace/ptrace-gpr.c
··· 7 7 #include "ptrace.h" 8 8 #include "ptrace-gpr.h" 9 9 #include "reg.h" 10 + #include <time.h> 10 11 11 12 /* Tracer and Tracee Shared Data */ 12 13 int shm_id; 13 14 int *cptr, *pptr; 14 15 15 - float a = FPR_1; 16 - float b = FPR_2; 17 - float c = FPR_3; 16 + extern void gpr_child_loop(int *read_flag, int *write_flag, 17 + unsigned long *gpr_buf, double *fpr_buf); 18 18 19 - void gpr(void) 19 + unsigned long child_gpr_val, parent_gpr_val; 20 + double child_fpr_val, parent_fpr_val; 21 + 22 + static int child(void) 20 23 { 21 - unsigned long gpr_buf[18]; 22 - float fpr_buf[32]; 24 + unsigned long gpr_buf[32]; 25 + double fpr_buf[32]; 26 + int i; 23 27 24 28 cptr = (int *)shmat(shm_id, NULL, 0); 29 + memset(gpr_buf, 0, sizeof(gpr_buf)); 30 + memset(fpr_buf, 0, sizeof(fpr_buf)); 25 31 26 - asm __volatile__( 27 - ASM_LOAD_GPR_IMMED(gpr_1) 28 - ASM_LOAD_FPR_SINGLE_PRECISION(flt_1) 29 - : 30 - : [gpr_1]"i"(GPR_1), [flt_1] "b" (&a) 31 - : "memory", "r6", "r7", "r8", "r9", "r10", 32 - "r11", "r12", "r13", "r14", "r15", "r16", "r17", 33 - "r18", "r19", "r20", "r21", "r22", "r23", "r24", 34 - "r25", "r26", "r27", "r28", "r29", "r30", "r31" 35 - ); 32 + for (i = 0; i < 32; i++) { 33 + gpr_buf[i] = child_gpr_val; 34 + fpr_buf[i] = child_fpr_val; 35 + } 36 36 37 - cptr[1] = 1; 38 - 39 - while (!cptr[0]) 40 - asm volatile("" : : : "memory"); 37 + gpr_child_loop(&cptr[0], &cptr[1], gpr_buf, fpr_buf); 41 38 42 39 shmdt((void *)cptr); 43 - store_gpr(gpr_buf); 44 - store_fpr_single_precision(fpr_buf); 45 40 46 - if (validate_gpr(gpr_buf, GPR_3)) 47 - exit(1); 41 + FAIL_IF(validate_gpr(gpr_buf, parent_gpr_val)); 42 + FAIL_IF(validate_fpr_double(fpr_buf, parent_fpr_val)); 48 43 49 - if (validate_fpr_float(fpr_buf, c)) 50 - exit(1); 51 - 52 - exit(0); 44 + return 0; 53 45 } 54 46 55 47 int trace_gpr(pid_t child) 56 48 { 49 + __u64 tmp, fpr[32], *peeked_fprs; 57 50 unsigned long gpr[18]; 58 - unsigned long fpr[32]; 59 51 60 52 FAIL_IF(start_trace(child)); 53 + 54 + // Check child GPRs match what we expect using GETREGS 61 55 FAIL_IF(show_gpr(child, gpr)); 62 - FAIL_IF(validate_gpr(gpr, GPR_1)); 56 + FAIL_IF(validate_gpr(gpr, child_gpr_val)); 57 + 58 + // Check child FPRs match what we expect using GETFPREGS 63 59 FAIL_IF(show_fpr(child, fpr)); 64 - FAIL_IF(validate_fpr(fpr, FPR_1_REP)); 65 - FAIL_IF(write_gpr(child, GPR_3)); 66 - FAIL_IF(write_fpr(child, FPR_3_REP)); 60 + memcpy(&tmp, &child_fpr_val, sizeof(tmp)); 61 + FAIL_IF(validate_fpr(fpr, tmp)); 62 + 63 + // Check child FPRs match what we expect using PEEKUSR 64 + peeked_fprs = peek_fprs(child); 65 + FAIL_IF(!peeked_fprs); 66 + FAIL_IF(validate_fpr(peeked_fprs, tmp)); 67 + free(peeked_fprs); 68 + 69 + // Write child GPRs using SETREGS 70 + FAIL_IF(write_gpr(child, parent_gpr_val)); 71 + 72 + // Write child FPRs using SETFPREGS 73 + memcpy(&tmp, &parent_fpr_val, sizeof(tmp)); 74 + FAIL_IF(write_fpr(child, tmp)); 75 + 76 + // Check child FPRs match what we just set, using PEEKUSR 77 + peeked_fprs = peek_fprs(child); 78 + FAIL_IF(!peeked_fprs); 79 + FAIL_IF(validate_fpr(peeked_fprs, tmp)); 80 + 81 + // Write child FPRs using POKEUSR 82 + FAIL_IF(poke_fprs(child, (unsigned long *)peeked_fprs)); 83 + 84 + // Child will check its FPRs match before exiting 67 85 FAIL_IF(stop_trace(child)); 68 86 69 87 return TEST_PASS; 70 88 } 71 89 90 + #ifndef __LONG_WIDTH__ 91 + #define __LONG_WIDTH__ (sizeof(long) * 8) 92 + #endif 93 + 94 + static uint64_t rand_reg(void) 95 + { 96 + uint64_t result; 97 + long r; 98 + 99 + r = random(); 100 + 101 + // Small values are typical 102 + result = r & 0xffff; 103 + if (r & 0x10000) 104 + return result; 105 + 106 + // Pointers tend to have high bits set 107 + result |= random() << (__LONG_WIDTH__ - 31); 108 + if (r & 0x100000) 109 + return result; 110 + 111 + // And sometimes we want a full 64-bit value 112 + result ^= random() << 16; 113 + 114 + return result; 115 + } 116 + 72 117 int ptrace_gpr(void) 73 118 { 74 - pid_t pid; 119 + unsigned long seed; 75 120 int ret, status; 121 + pid_t pid; 122 + 123 + seed = getpid() ^ time(NULL); 124 + printf("srand(%lu)\n", seed); 125 + srand(seed); 126 + 127 + child_gpr_val = rand_reg(); 128 + child_fpr_val = rand_reg(); 129 + parent_gpr_val = rand_reg(); 130 + parent_fpr_val = rand_reg(); 76 131 77 132 shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT); 78 133 pid = fork(); ··· 136 81 return TEST_FAIL; 137 82 } 138 83 if (pid == 0) 139 - gpr(); 84 + exit(child()); 140 85 141 86 if (pid) { 142 87 pptr = (int *)shmat(shm_id, NULL, 0);
+7 -7
tools/testing/selftests/powerpc/ptrace/ptrace-gpr.h
··· 12 12 #define FPR_3 0.003 13 13 #define FPR_4 0.004 14 14 15 - #define FPR_1_REP 0x3f50624de0000000 16 - #define FPR_2_REP 0x3f60624de0000000 17 - #define FPR_3_REP 0x3f689374c0000000 18 - #define FPR_4_REP 0x3f70624de0000000 15 + #define FPR_1_REP 0x3f50624dd2f1a9fcull 16 + #define FPR_2_REP 0x3f60624dd2f1a9fcull 17 + #define FPR_3_REP 0x3f689374bc6a7efaull 18 + #define FPR_4_REP 0x3f70624dd2f1a9fcull 19 19 20 20 /* Buffer must have 18 elements */ 21 21 int validate_gpr(unsigned long *gpr, unsigned long val) ··· 36 36 } 37 37 38 38 /* Buffer must have 32 elements */ 39 - int validate_fpr(unsigned long *fpr, unsigned long val) 39 + int validate_fpr(__u64 *fpr, __u64 val) 40 40 { 41 41 int i, found = 1; 42 42 43 43 for (i = 0; i < 32; i++) { 44 44 if (fpr[i] != val) { 45 - printf("FPR[%d]: %lx Expected: %lx\n", i, fpr[i], val); 45 + printf("FPR[%d]: %llx Expected: %llx\n", i, fpr[i], val); 46 46 found = 0; 47 47 } 48 48 } ··· 53 53 } 54 54 55 55 /* Buffer must have 32 elements */ 56 - int validate_fpr_float(float *fpr, float val) 56 + int validate_fpr_double(double *fpr, double val) 57 57 { 58 58 int i, found = 1; 59 59
+9 -9
tools/testing/selftests/powerpc/ptrace/ptrace-tm-gpr.c
··· 12 12 int shm_id; 13 13 unsigned long *cptr, *pptr; 14 14 15 - float a = FPR_1; 16 - float b = FPR_2; 17 - float c = FPR_3; 15 + double a = FPR_1; 16 + double b = FPR_2; 17 + double c = FPR_3; 18 18 19 19 void tm_gpr(void) 20 20 { 21 21 unsigned long gpr_buf[18]; 22 22 unsigned long result, texasr; 23 - float fpr_buf[32]; 23 + double fpr_buf[32]; 24 24 25 25 printf("Starting the child\n"); 26 26 cptr = (unsigned long *)shmat(shm_id, NULL, 0); ··· 29 29 cptr[1] = 0; 30 30 asm __volatile__( 31 31 ASM_LOAD_GPR_IMMED(gpr_1) 32 - ASM_LOAD_FPR_SINGLE_PRECISION(flt_1) 32 + ASM_LOAD_FPR(flt_1) 33 33 "1: ;" 34 34 "tbegin.;" 35 35 "beq 2f;" 36 36 ASM_LOAD_GPR_IMMED(gpr_2) 37 - ASM_LOAD_FPR_SINGLE_PRECISION(flt_2) 37 + ASM_LOAD_FPR(flt_2) 38 38 "tsuspend.;" 39 39 "li 7, 1;" 40 40 "stw 7, 0(%[cptr1]);" ··· 70 70 71 71 shmdt((void *)cptr); 72 72 store_gpr(gpr_buf); 73 - store_fpr_single_precision(fpr_buf); 73 + store_fpr(fpr_buf); 74 74 75 75 if (validate_gpr(gpr_buf, GPR_3)) 76 76 exit(1); 77 77 78 - if (validate_fpr_float(fpr_buf, c)) 78 + if (validate_fpr_double(fpr_buf, c)) 79 79 exit(1); 80 80 81 81 exit(0); ··· 87 87 int trace_tm_gpr(pid_t child) 88 88 { 89 89 unsigned long gpr[18]; 90 - unsigned long fpr[32]; 90 + __u64 fpr[32]; 91 91 92 92 FAIL_IF(start_trace(child)); 93 93 FAIL_IF(show_gpr(child, gpr));
+10 -10
tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c
··· 12 12 int shm_id; 13 13 int *cptr, *pptr; 14 14 15 - float a = FPR_1; 16 - float b = FPR_2; 17 - float c = FPR_3; 18 - float d = FPR_4; 15 + double a = FPR_1; 16 + double b = FPR_2; 17 + double c = FPR_3; 18 + double d = FPR_4; 19 19 20 20 __attribute__((used)) void wait_parent(void) 21 21 { ··· 28 28 { 29 29 unsigned long gpr_buf[18]; 30 30 unsigned long result, texasr; 31 - float fpr_buf[32]; 31 + double fpr_buf[32]; 32 32 33 33 cptr = (int *)shmat(shm_id, NULL, 0); 34 34 ··· 36 36 cptr[2] = 0; 37 37 asm __volatile__( 38 38 ASM_LOAD_GPR_IMMED(gpr_1) 39 - ASM_LOAD_FPR_SINGLE_PRECISION(flt_1) 39 + ASM_LOAD_FPR(flt_1) 40 40 41 41 "1: ;" 42 42 "tbegin.;" ··· 45 45 ASM_LOAD_GPR_IMMED(gpr_2) 46 46 "tsuspend.;" 47 47 ASM_LOAD_GPR_IMMED(gpr_4) 48 - ASM_LOAD_FPR_SINGLE_PRECISION(flt_4) 48 + ASM_LOAD_FPR(flt_4) 49 49 50 50 "bl wait_parent;" 51 51 "tresume.;" ··· 77 77 78 78 shmdt((void *)cptr); 79 79 store_gpr(gpr_buf); 80 - store_fpr_single_precision(fpr_buf); 80 + store_fpr(fpr_buf); 81 81 82 82 if (validate_gpr(gpr_buf, GPR_3)) 83 83 exit(1); 84 84 85 - if (validate_fpr_float(fpr_buf, c)) 85 + if (validate_fpr_double(fpr_buf, c)) 86 86 exit(1); 87 87 exit(0); 88 88 } ··· 93 93 int trace_tm_spd_gpr(pid_t child) 94 94 { 95 95 unsigned long gpr[18]; 96 - unsigned long fpr[32]; 96 + __u64 fpr[32]; 97 97 98 98 FAIL_IF(start_trace(child)); 99 99 FAIL_IF(show_gpr(child, gpr));
+73 -6
tools/testing/selftests/powerpc/ptrace/ptrace.h
··· 4 4 * 5 5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation. 6 6 */ 7 + 8 + #define __SANE_USERSPACE_TYPES__ 9 + 7 10 #include <inttypes.h> 8 11 #include <unistd.h> 9 12 #include <stdlib.h> ··· 23 20 #include <sys/ipc.h> 24 21 #include <sys/shm.h> 25 22 #include <sys/user.h> 23 + #include <sys/syscall.h> 26 24 #include <linux/elf.h> 27 25 #include <linux/types.h> 28 26 #include <linux/auxvec.h> ··· 34 30 #define TEST_FAIL 1 35 31 36 32 struct fpr_regs { 37 - unsigned long fpr[32]; 38 - unsigned long fpscr; 33 + __u64 fpr[32]; 34 + __u64 fpscr; 39 35 }; 40 36 41 37 struct tm_spr_regs { ··· 322 318 } 323 319 324 320 /* FPR */ 325 - int show_fpr(pid_t child, unsigned long *fpr) 321 + int show_fpr(pid_t child, __u64 *fpr) 326 322 { 327 323 struct fpr_regs *regs; 328 324 int ret, i; ··· 341 337 return TEST_PASS; 342 338 } 343 339 344 - int write_fpr(pid_t child, unsigned long val) 340 + int write_fpr(pid_t child, __u64 val) 345 341 { 346 342 struct fpr_regs *regs; 347 343 int ret, i; ··· 364 360 return TEST_PASS; 365 361 } 366 362 367 - int show_ckpt_fpr(pid_t child, unsigned long *fpr) 363 + int show_ckpt_fpr(pid_t child, __u64 *fpr) 368 364 { 369 365 struct fpr_regs *regs; 370 366 struct iovec iov; ··· 439 435 } 440 436 441 437 return TEST_PASS; 438 + } 439 + 440 + long sys_ptrace(enum __ptrace_request request, pid_t pid, unsigned long addr, unsigned long data) 441 + { 442 + return syscall(__NR_ptrace, request, pid, (void *)addr, data); 443 + } 444 + 445 + // 33 because of FPSCR 446 + #define PT_NUM_FPRS (33 * (sizeof(__u64) / sizeof(unsigned long))) 447 + 448 + __u64 *peek_fprs(pid_t child) 449 + { 450 + unsigned long *fprs, *p, addr; 451 + long ret; 452 + int i; 453 + 454 + fprs = malloc(sizeof(unsigned long) * PT_NUM_FPRS); 455 + if (!fprs) { 456 + perror("malloc() failed"); 457 + return NULL; 458 + } 459 + 460 + for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) { 461 + addr = sizeof(unsigned long) * (PT_FPR0 + i); 462 + ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)p); 463 + if (ret) { 464 + perror("ptrace(PTRACE_PEEKUSR) failed"); 465 + return NULL; 466 + } 467 + } 468 + 469 + addr = sizeof(unsigned long) * (PT_FPR0 + i); 470 + ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)&addr); 471 + if (!ret) { 472 + printf("ptrace(PTRACE_PEEKUSR) succeeded unexpectedly!\n"); 473 + return NULL; 474 + } 475 + 476 + return (__u64 *)fprs; 477 + } 478 + 479 + int poke_fprs(pid_t child, unsigned long *fprs) 480 + { 481 + unsigned long *p, addr; 482 + long ret; 483 + int i; 484 + 485 + for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) { 486 + addr = sizeof(unsigned long) * (PT_FPR0 + i); 487 + ret = sys_ptrace(PTRACE_POKEUSER, child, addr, *p); 488 + if (ret) { 489 + perror("ptrace(PTRACE_POKEUSR) failed"); 490 + return -1; 491 + } 492 + } 493 + 494 + addr = sizeof(unsigned long) * (PT_FPR0 + i); 495 + ret = sys_ptrace(PTRACE_POKEUSER, child, addr, addr); 496 + if (!ret) { 497 + printf("ptrace(PTRACE_POKEUSR) succeeded unexpectedly!\n"); 498 + return -1; 499 + } 500 + 501 + return 0; 442 502 } 443 503 444 504 int write_gpr(pid_t child, unsigned long val) ··· 810 742 } 811 743 812 744 void store_gpr(unsigned long *addr); 813 - void store_fpr(float *addr);
+1
tools/testing/selftests/powerpc/security/.gitignore
··· 2 2 rfi_flush 3 3 entry_flush 4 4 spectre_v2 5 + uaccess_flush