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.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc updates from Michael Ellerman:

- Support for configuring secure boot with user-defined keys on PowerVM
LPARs

- Simplify the replay of soft-masked IRQs by making it non-recursive

- Add support for KCSAN on 64-bit Book3S

- Improvements to the API & code which interacts with RTAS (pseries
firmware)

- Change 32-bit powermac to assign PCI bus numbers per domain by
default

- Some improvements to the 32-bit BPF JIT

- Various other small features and fixes

Thanks to Anders Roxell, Andrew Donnellan, Andrew Jeffery, Benjamin
Gray, Christophe Leroy, Frederic Barrat, Ganesh Goudar, Geoff Levand,
Greg Kroah-Hartman, Jan-Benedict Glaw, Josh Poimboeuf, Kajol Jain,
Laurent Dufour, Mahesh Salgaonkar, Mathieu Desnoyers, Mimi Zohar, Murphy
Zhou, Nathan Chancellor, Nathan Lynch, Nayna Jain, Nicholas Piggin, Pali
Rohár, Petr Mladek, Rohan McLure, Russell Currey, Sachin Sant, Sathvika
Vasireddy, Sourabh Jain, Stefan Berger, Stephen Rothwell, and Sudhakar
Kuppusamy.

* tag 'powerpc-6.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (114 commits)
powerpc/pseries: Avoid hcall in plpks_is_available() on non-pseries
powerpc: dts: turris1x.dts: Set lower priority for CPLD syscon-reboot
powerpc/e500: Add missing prototype for 'relocate_init'
powerpc/64: Fix unannotated intra-function call warning
powerpc/epapr: Don't use wrteei on non booke
powerpc: Pass correct CPU reference to assembler
powerpc/mm: Rearrange if-else block to avoid clang warning
powerpc/nohash: Fix build with llvm-as
powerpc/nohash: Fix build error with binutils >= 2.38
powerpc/pseries: Fix endianness issue when parsing PLPKS secvar flags
macintosh: windfarm: Use unsigned type for 1-bit bitfields
powerpc/kexec_file: print error string on usable memory property update failure
powerpc/machdep: warn when machine_is() used too early
powerpc/64: Replace -mcpu=e500mc64 by -mcpu=e5500
powerpc/eeh: Set channel state after notifying the drivers
selftests/powerpc: Fix incorrect kernel headers search path
powerpc/rtas: arch-wide function token lookup conversions
powerpc/rtas: introduce rtas_function_token() API
powerpc/pseries/lpar: convert to papr_sysparm API
powerpc/pseries/hv-24x7: convert to papr_sysparm API
...

+3856 -1588
+74 -1
Documentation/ABI/testing/sysfs-secvar
··· 18 18 This determines the format of the variable and the accepted 19 19 format of variable updates. 20 20 21 + On powernv/OPAL, this value is provided by the OPAL firmware 22 + and is expected to be "ibm,edk2-compat-v1". 23 + 24 + On pseries/PLPKS, this is generated by the kernel based on the 25 + version number in the SB_VERSION variable in the keystore, and 26 + has the form "ibm,plpks-sb-v<version>", or 27 + "ibm,plpks-sb-unknown" if there is no SB_VERSION variable. 28 + 21 29 What: /sys/firmware/secvar/vars/<variable name> 22 30 Date: August 2019 23 31 Contact: Nayna Jain <nayna@linux.ibm.com> ··· 42 34 43 35 What: /sys/firmware/secvar/vars/<variable_name>/data 44 36 Date: August 2019 45 - Contact: Nayna Jain h<nayna@linux.ibm.com> 37 + Contact: Nayna Jain <nayna@linux.ibm.com> 46 38 Description: A read-only file containing the value of the variable. The size 47 39 of the file represents the maximum size of the variable data. 48 40 ··· 52 44 Description: A write-only file that is used to submit the new value for the 53 45 variable. The size of the file represents the maximum size of 54 46 the variable data that can be written. 47 + 48 + What: /sys/firmware/secvar/config 49 + Date: February 2023 50 + Contact: Nayna Jain <nayna@linux.ibm.com> 51 + Description: This optional directory contains read-only config attributes as 52 + defined by the secure variable implementation. All data is in 53 + ASCII format. The directory is only created if the backing 54 + implementation provides variables to populate it, which at 55 + present is only PLPKS on the pseries platform. 56 + 57 + What: /sys/firmware/secvar/config/version 58 + Date: February 2023 59 + Contact: Nayna Jain <nayna@linux.ibm.com> 60 + Description: Config version as reported by the hypervisor in ASCII decimal 61 + format. 62 + 63 + Currently only provided by PLPKS on the pseries platform. 64 + 65 + What: /sys/firmware/secvar/config/max_object_size 66 + Date: February 2023 67 + Contact: Nayna Jain <nayna@linux.ibm.com> 68 + Description: Maximum allowed size of objects in the keystore in bytes, 69 + represented in ASCII decimal format. 70 + 71 + This is not necessarily the same as the max size that can be 72 + written to an update file as writes can contain more than 73 + object data, you should use the size of the update file for 74 + that purpose. 75 + 76 + Currently only provided by PLPKS on the pseries platform. 77 + 78 + What: /sys/firmware/secvar/config/total_size 79 + Date: February 2023 80 + Contact: Nayna Jain <nayna@linux.ibm.com> 81 + Description: Total size of the PLPKS in bytes, represented in ASCII decimal 82 + format. 83 + 84 + Currently only provided by PLPKS on the pseries platform. 85 + 86 + What: /sys/firmware/secvar/config/used_space 87 + Date: February 2023 88 + Contact: Nayna Jain <nayna@linux.ibm.com> 89 + Description: Current space consumed by the key store, in bytes, represented 90 + in ASCII decimal format. 91 + 92 + Currently only provided by PLPKS on the pseries platform. 93 + 94 + What: /sys/firmware/secvar/config/supported_policies 95 + Date: February 2023 96 + Contact: Nayna Jain <nayna@linux.ibm.com> 97 + Description: Bitmask of supported policy flags by the hypervisor, 98 + represented as an 8 byte hexadecimal ASCII string. Consult the 99 + hypervisor documentation for what these flags are. 100 + 101 + Currently only provided by PLPKS on the pseries platform. 102 + 103 + What: /sys/firmware/secvar/config/signed_update_algorithms 104 + Date: February 2023 105 + Contact: Nayna Jain <nayna@linux.ibm.com> 106 + Description: Bitmask of flags indicating which algorithms the hypervisor 107 + supports for signed update of objects, represented as a 16 byte 108 + hexadecimal ASCII string. Consult the hypervisor documentation 109 + for what these flags mean. 110 + 111 + Currently only provided by PLPKS on the pseries platform.
+17 -2
arch/powerpc/Kconfig
··· 197 197 select HAVE_ARCH_KASAN if PPC_RADIX_MMU 198 198 select HAVE_ARCH_KASAN if PPC_BOOK3E_64 199 199 select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN 200 + select HAVE_ARCH_KCSAN if PPC_BOOK3S_64 200 201 select HAVE_ARCH_KFENCE if ARCH_SUPPORTS_DEBUG_PAGEALLOC 201 202 select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET 202 203 select HAVE_ARCH_KGDB ··· 207 206 select HAVE_ARCH_SECCOMP_FILTER 208 207 select HAVE_ARCH_TRACEHOOK 209 208 select HAVE_ASM_MODVERSIONS 210 - select HAVE_CONTEXT_TRACKING_USER if PPC64 209 + select HAVE_CONTEXT_TRACKING_USER 211 210 select HAVE_C_RECORDMCOUNT 212 211 select HAVE_DEBUG_KMEMLEAK 213 212 select HAVE_DEBUG_STACKOVERFLOW ··· 257 256 select HAVE_STATIC_CALL if PPC32 258 257 select HAVE_SYSCALL_TRACEPOINTS 259 258 select HAVE_VIRT_CPU_ACCOUNTING 259 + select HAVE_VIRT_CPU_ACCOUNTING_GEN 260 260 select HUGETLB_PAGE_SIZE_VARIABLE if PPC_BOOK3S_64 && HUGETLB_PAGE 261 261 select IOMMU_HELPER if PPC64 262 262 select IRQ_DOMAIN ··· 389 387 depends on PPC_DCR_NATIVE || PPC_DCR_MMIO 390 388 default y 391 389 390 + config PPC_PCI_OF_BUS_MAP 391 + bool "Use pci_to_OF_bus_map (deprecated)" 392 + depends on PPC32 393 + depends on PPC_PMAC || PPC_CHRP 394 + help 395 + This option uses pci_to_OF_bus_map to map OF nodes to PCI devices, which 396 + restricts the system to only having 256 PCI buses. On CHRP it also causes 397 + the "pci-OF-bus-map" property to be created in the device tree. 398 + 399 + If unsure, say "N". 400 + 392 401 config PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT 393 402 depends on PPC32 394 - depends on !PPC_PMAC && !PPC_CHRP 403 + depends on !PPC_PCI_OF_BUS_MAP 395 404 bool "Assign PCI bus numbers from zero individually for each PCI domain" 405 + default y 396 406 help 397 407 By default on PPC32 were PCI bus numbers unique across all PCI domains. 398 408 So system could have only 256 PCI buses independently of available ··· 1042 1028 depends on PPC_POWERNV || PPC_PSERIES 1043 1029 depends on IMA_ARCH_POLICY 1044 1030 imply IMA_SECURE_AND_OR_TRUSTED_BOOT 1031 + select PSERIES_PLPKS if PPC_PSERIES 1045 1032 help 1046 1033 Systems with firmware secure boot enabled need to define security 1047 1034 policies to extend secure boot to the OS. This config allows a user
+5 -21
arch/powerpc/Makefile
··· 146 146 147 147 CFLAGS-$(CONFIG_PPC32) += $(call cc-option,-mno-readonly-in-sdata) 148 148 149 - ifdef CONFIG_PPC_BOOK3S_64 150 - ifdef CONFIG_CPU_LITTLE_ENDIAN 151 - CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power8 152 - else 153 - CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power4 154 - endif 155 - CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power10, \ 156 - $(call cc-option,-mtune=power9, \ 157 - $(call cc-option,-mtune=power8))) 158 - else ifdef CONFIG_PPC_BOOK3E_64 159 - CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 160 - endif 161 - 162 149 ifdef CONFIG_FUNCTION_TRACER 163 150 CC_FLAGS_FTRACE := -pg 164 151 ifdef CONFIG_MPROFILE_KERNEL ··· 153 166 endif 154 167 endif 155 168 156 - CFLAGS-$(CONFIG_TARGET_CPU_BOOL) += $(call cc-option,-mcpu=$(CONFIG_TARGET_CPU)) 157 - AFLAGS-$(CONFIG_TARGET_CPU_BOOL) += $(call cc-option,-mcpu=$(CONFIG_TARGET_CPU)) 169 + CFLAGS-$(CONFIG_TARGET_CPU_BOOL) += -mcpu=$(CONFIG_TARGET_CPU) 170 + AFLAGS-$(CONFIG_TARGET_CPU_BOOL) += -mcpu=$(CONFIG_TARGET_CPU) 158 171 159 - CFLAGS-$(CONFIG_E5500_CPU) += $(call cc-option,-mcpu=e500mc64,-mcpu=powerpc64) 160 - CFLAGS-$(CONFIG_E6500_CPU) += $(call cc-option,-mcpu=e6500,$(E5500_CPU)) 172 + CFLAGS-$(CONFIG_POWERPC64_CPU) += $(call cc-option,-mtune=power10, \ 173 + $(call cc-option,-mtune=power9, \ 174 + $(call cc-option,-mtune=power8))) 161 175 162 176 asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1) 163 177 ··· 201 213 # often slow when they are implemented at all 202 214 KBUILD_CFLAGS += $(call cc-option,-mno-string) 203 215 204 - cpu-as-$(CONFIG_40x) += -Wa,-m405 205 - cpu-as-$(CONFIG_44x) += -Wa,-m440 206 216 cpu-as-$(CONFIG_ALTIVEC) += $(call as-option,-Wa$(comma)-maltivec) 207 - cpu-as-$(CONFIG_PPC_E500) += -Wa,-me500 208 217 209 218 # When using '-many -mpower4' gas will first try and find a matching power4 210 219 # mnemonic and failing that it will allow any valid mnemonic that GAS knows ··· 209 224 # LLVM IAS doesn't understand either flag: https://github.com/ClangBuiltLinux/linux/issues/675 210 225 # but LLVM IAS only supports ISA >= 2.06 for Book3S 64 anyway... 211 226 cpu-as-$(CONFIG_PPC_BOOK3S_64) += $(call as-option,-Wa$(comma)-mpower4) $(call as-option,-Wa$(comma)-many) 212 - cpu-as-$(CONFIG_PPC_E500MC) += $(call as-option,-Wa$(comma)-me500mc) 213 227 214 228 KBUILD_AFLAGS += $(cpu-as-y) 215 229 KBUILD_CFLAGS += $(cpu-as-y)
+10 -4
arch/powerpc/boot/Makefile
··· 39 39 $(LINUXINCLUDE) 40 40 41 41 ifdef CONFIG_PPC64_BOOT_WRAPPER 42 - ifdef CONFIG_CPU_LITTLE_ENDIAN 43 - BOOTCFLAGS += -m64 -mcpu=powerpc64le 42 + BOOTCFLAGS += -m64 44 43 else 45 - BOOTCFLAGS += -m64 -mcpu=powerpc64 44 + BOOTCFLAGS += -m32 46 45 endif 46 + 47 + ifdef CONFIG_TARGET_CPU_BOOL 48 + BOOTCFLAGS += -mcpu=$(CONFIG_TARGET_CPU) 49 + else ifdef CONFIG_PPC64_BOOT_WRAPPER 50 + ifdef CONFIG_CPU_LITTLE_ENDIAN 51 + BOOTCFLAGS += -mcpu=powerpc64le 47 52 else 48 - BOOTCFLAGS += -m32 -mcpu=powerpc 53 + BOOTCFLAGS += -mcpu=powerpc64 54 + endif 49 55 endif 50 56 51 57 BOOTCFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include)
+23
arch/powerpc/boot/dts/turris1x.dts
··· 367 367 }; 368 368 369 369 reboot@d { 370 + /* 371 + * CPLD firmware which manages system reset and 372 + * watchdog registers has bugs. It does not 373 + * autoclear system reset register after change 374 + * and watchdog ignores reset line on immediate 375 + * succeeding reset cycle triggered by watchdog. 376 + * These bugs have to be workarounded in U-Boot 377 + * bootloader. So use system reset via syscon as 378 + * a last resort because older U-Boot versions 379 + * do not have workaround for watchdog. 380 + * 381 + * Reset method via rstcr's global-utilities 382 + * (the preferred one) has priority level 128, 383 + * watchdog has priority level 0 and default 384 + * syscon-reboot priority level is 192. 385 + * 386 + * So define syscon-reboot with custom priority 387 + * level 64 (between rstcr and watchdog) because 388 + * rstcr should stay as default preferred reset 389 + * method and reset via watchdog is more broken 390 + * than system reset via syscon. 391 + */ 370 392 compatible = "syscon-reboot"; 371 393 reg = <0x0d 0x01>; 372 394 offset = <0x0d>; 373 395 mask = <0x01>; 374 396 value = <0x01>; 397 + priority = <64>; 375 398 }; 376 399 377 400 led-controller@13 {
+17 -22
arch/powerpc/configs/ps3_defconfig
··· 1 - CONFIG_PPC64=y 2 - CONFIG_CELL_CPU=y 3 - CONFIG_ALTIVEC=y 4 - CONFIG_SMP=y 5 - CONFIG_NR_CPUS=2 6 1 CONFIG_SYSVIPC=y 7 2 CONFIG_POSIX_MQUEUE=y 8 3 CONFIG_HIGH_RES_TIMERS=y ··· 5 10 CONFIG_CC_OPTIMIZE_FOR_SIZE=y 6 11 CONFIG_EMBEDDED=y 7 12 # CONFIG_PERF_EVENTS is not set 8 - # CONFIG_COMPAT_BRK is not set 9 - CONFIG_SLAB=y 10 13 CONFIG_PROFILING=y 11 - CONFIG_MODULES=y 12 - CONFIG_MODULE_UNLOAD=y 14 + CONFIG_PPC64=y 15 + CONFIG_CELL_CPU=y 16 + CONFIG_ALTIVEC=y 17 + CONFIG_SMP=y 18 + CONFIG_NR_CPUS=2 13 19 # CONFIG_PPC_POWERNV is not set 14 20 # CONFIG_PPC_PSERIES is not set 15 21 # CONFIG_PPC_PMAC is not set ··· 23 27 CONFIG_PS3_VRAM=m 24 28 CONFIG_PS3_LPM=m 25 29 # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set 26 - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set 27 - CONFIG_BINFMT_MISC=y 28 30 CONFIG_KEXEC=y 29 31 CONFIG_PPC_4K_PAGES=y 30 - # CONFIG_SPARSEMEM_VMEMMAP is not set 31 - # CONFIG_COMPACTION is not set 32 32 CONFIG_SCHED_SMT=y 33 33 CONFIG_PM=y 34 34 CONFIG_PM_DEBUG=y 35 35 # CONFIG_SECCOMP is not set 36 - # CONFIG_PCI is not set 36 + CONFIG_MODULES=y 37 + CONFIG_MODULE_UNLOAD=y 38 + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set 39 + CONFIG_BINFMT_MISC=y 40 + CONFIG_SLAB=y 41 + # CONFIG_COMPAT_BRK is not set 42 + # CONFIG_SPARSEMEM_VMEMMAP is not set 43 + # CONFIG_COMPACTION is not set 37 44 CONFIG_NET=y 38 45 CONFIG_PACKET=y 39 46 CONFIG_UNIX=y ··· 86 87 # CONFIG_USB_NET_NET1080 is not set 87 88 # CONFIG_USB_NET_CDC_SUBSET is not set 88 89 # CONFIG_USB_NET_ZAURUS is not set 89 - CONFIG_INPUT_FF_MEMLESS=m 90 90 CONFIG_INPUT_JOYDEV=m 91 91 CONFIG_INPUT_EVDEV=m 92 92 # CONFIG_INPUT_KEYBOARD is not set ··· 108 110 # CONFIG_SND_DRIVERS is not set 109 111 CONFIG_SND_USB_AUDIO=m 110 112 CONFIG_HIDRAW=y 111 - CONFIG_HID_APPLE=m 112 113 CONFIG_HID_BELKIN=m 113 114 CONFIG_HID_CHERRY=m 114 115 CONFIG_HID_EZKEY=m 115 116 CONFIG_HID_TWINHAN=m 116 - CONFIG_HID_LOGITECH=m 117 - CONFIG_HID_LOGITECH_DJ=m 118 117 CONFIG_HID_MICROSOFT=m 119 118 CONFIG_HID_SUNPLUS=m 120 119 CONFIG_HID_SMARTJOYPLUS=m ··· 146 151 CONFIG_NLS=y 147 152 CONFIG_NLS_CODEPAGE_437=y 148 153 CONFIG_NLS_ISO8859_1=y 154 + CONFIG_CRYPTO_PCBC=m 155 + CONFIG_CRYPTO_MICHAEL_MIC=m 156 + CONFIG_CRYPTO_LZO=m 149 157 CONFIG_CRC_CCITT=m 150 158 CONFIG_CRC_T10DIF=y 159 + CONFIG_PRINTK_TIME=y 151 160 CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 152 161 CONFIG_MAGIC_SYSRQ=y 153 162 CONFIG_DEBUG_MEMORY_INIT=y ··· 162 163 CONFIG_DEBUG_LIST=y 163 164 CONFIG_RCU_CPU_STALL_TIMEOUT=60 164 165 # CONFIG_FTRACE is not set 165 - CONFIG_CRYPTO_PCBC=m 166 - CONFIG_CRYPTO_MICHAEL_MIC=m 167 - CONFIG_CRYPTO_LZO=m 168 - CONFIG_PRINTK_TIME=y
+4 -9
arch/powerpc/crypto/crc32-vpmsum_core.S
··· 113 113 #endif 114 114 115 115 #ifdef BYTESWAP_DATA 116 - addis r3,r2,.byteswap_constant@toc@ha 117 - addi r3,r3,.byteswap_constant@toc@l 118 - 116 + LOAD_REG_ADDR(r3, .byteswap_constant) 119 117 lvx byteswap,0,r3 120 118 addi r3,r3,16 121 119 #endif ··· 148 150 addi r7,r7,-1 149 151 mtctr r7 150 152 151 - addis r3,r2,.constants@toc@ha 152 - addi r3,r3,.constants@toc@l 153 + LOAD_REG_ADDR(r3, .constants) 153 154 154 155 /* Find the start of our constants */ 155 156 add r3,r3,r8 ··· 503 506 504 507 .Lbarrett_reduction: 505 508 /* Barrett constants */ 506 - addis r3,r2,.barrett_constants@toc@ha 507 - addi r3,r3,.barrett_constants@toc@l 509 + LOAD_REG_ADDR(r3, .barrett_constants) 508 510 509 511 lvx const1,0,r3 510 512 lvx const2,off16,r3 ··· 606 610 cmpdi r5,0 607 611 beq .Lzero 608 612 609 - addis r3,r2,.short_constants@toc@ha 610 - addi r3,r3,.short_constants@toc@l 613 + LOAD_REG_ADDR(r3, .short_constants) 611 614 612 615 /* Calculate where in the constant table we need to start */ 613 616 subfic r6,r5,256
+6 -6
arch/powerpc/include/asm/barrier.h
··· 35 35 * However, on CPUs that don't support lwsync, lwsync actually maps to a 36 36 * heavy-weight sync, so smp_wmb() can be a lighter-weight eieio. 37 37 */ 38 - #define mb() __asm__ __volatile__ ("sync" : : : "memory") 39 - #define rmb() __asm__ __volatile__ ("sync" : : : "memory") 40 - #define wmb() __asm__ __volatile__ ("sync" : : : "memory") 38 + #define __mb() __asm__ __volatile__ ("sync" : : : "memory") 39 + #define __rmb() __asm__ __volatile__ ("sync" : : : "memory") 40 + #define __wmb() __asm__ __volatile__ ("sync" : : : "memory") 41 41 42 42 /* The sub-arch has lwsync */ 43 43 #if defined(CONFIG_PPC64) || defined(CONFIG_PPC_E500MC) ··· 51 51 /* clang defines this macro for a builtin, which will not work with runtime patching */ 52 52 #undef __lwsync 53 53 #define __lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : :"memory") 54 - #define dma_rmb() __lwsync() 55 - #define dma_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory") 54 + #define __dma_rmb() __lwsync() 55 + #define __dma_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory") 56 56 57 57 #define __smp_lwsync() __lwsync() 58 58 59 - #define __smp_mb() mb() 59 + #define __smp_mb() __mb() 60 60 #define __smp_rmb() __lwsync() 61 61 #define __smp_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory") 62 62
+1
arch/powerpc/include/asm/hvcall.h
··· 335 335 #define H_RPT_INVALIDATE 0x448 336 336 #define H_SCM_FLUSH 0x44C 337 337 #define H_GET_ENERGY_SCALE_INFO 0x450 338 + #define H_PKS_SIGNED_UPDATE 0x454 338 339 #define H_WATCHDOG 0x45C 339 340 #define MAX_HCALL_OPCODE H_WATCHDOG 340 341
+4 -2
arch/powerpc/include/asm/hw_irq.h
··· 36 36 #define PACA_IRQ_DEC 0x08 /* Or FIT */ 37 37 #define PACA_IRQ_HMI 0x10 38 38 #define PACA_IRQ_PMI 0x20 39 + #define PACA_IRQ_REPLAYING 0x40 39 40 40 41 /* 41 42 * Some soft-masked interrupts must be hard masked until they are replayed 42 43 * (e.g., because the soft-masked handler does not clear the exception). 44 + * Interrupt replay itself must remain hard masked too. 43 45 */ 44 46 #ifdef CONFIG_PPC_BOOK3S 45 - #define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE|PACA_IRQ_PMI) 47 + #define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE|PACA_IRQ_PMI|PACA_IRQ_REPLAYING) 46 48 #else 47 - #define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE) 49 + #define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE|PACA_IRQ_REPLAYING) 48 50 #endif 49 51 50 52 #endif /* CONFIG_PPC64 */
+8 -27
arch/powerpc/include/asm/interrupt.h
··· 74 74 #include <asm/kprobes.h> 75 75 #include <asm/runlatch.h> 76 76 77 - #ifdef CONFIG_PPC64 77 + #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG 78 78 /* 79 79 * WARN/BUG is handled with a program interrupt so minimise checks here to 80 80 * avoid recursion and maximise the chance of getting the first oops handled. 81 81 */ 82 82 #define INT_SOFT_MASK_BUG_ON(regs, cond) \ 83 83 do { \ 84 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG) && \ 85 - (user_mode(regs) || (TRAP(regs) != INTERRUPT_PROGRAM))) \ 84 + if ((user_mode(regs) || (TRAP(regs) != INTERRUPT_PROGRAM))) \ 86 85 BUG_ON(cond); \ 87 86 } while (0) 87 + #else 88 + #define INT_SOFT_MASK_BUG_ON(regs, cond) 88 89 #endif 89 90 90 91 #ifdef CONFIG_PPC_BOOK3S_64 ··· 152 151 153 152 static inline void interrupt_enter_prepare(struct pt_regs *regs) 154 153 { 155 - #ifdef CONFIG_PPC32 156 - if (!arch_irq_disabled_regs(regs)) 157 - trace_hardirqs_off(); 158 - 159 - if (user_mode(regs)) 160 - kuap_lock(); 161 - else 162 - kuap_save_and_lock(regs); 163 - 164 - if (user_mode(regs)) 165 - account_cpu_user_entry(); 166 - #endif 167 - 168 154 #ifdef CONFIG_PPC64 169 - bool trace_enable = false; 170 - 171 - if (IS_ENABLED(CONFIG_TRACE_IRQFLAGS)) { 172 - if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED) 173 - trace_enable = true; 174 - } else { 175 - irq_soft_mask_set(IRQS_ALL_DISABLED); 176 - } 155 + irq_soft_mask_set(IRQS_ALL_DISABLED); 177 156 178 157 /* 179 158 * If the interrupt was taken with HARD_DIS clear, then enable MSR[EE]. ··· 169 188 } else { 170 189 __hard_RI_enable(); 171 190 } 191 + /* Enable MSR[RI] early, to support kernel SLB and hash faults */ 192 + #endif 172 193 173 - /* Do this when RI=1 because it can cause SLB faults */ 174 - if (trace_enable) 194 + if (!arch_irq_disabled_regs(regs)) 175 195 trace_hardirqs_off(); 176 196 177 197 if (user_mode(regs)) { ··· 197 215 } 198 216 INT_SOFT_MASK_BUG_ON(regs, !arch_irq_disabled_regs(regs) && 199 217 !(regs->msr & MSR_EE)); 200 - #endif 201 218 202 219 booke_restore_dbcr0(); 203 220 }
-3
arch/powerpc/include/asm/irq.h
··· 16 16 17 17 extern atomic_t ppc_n_lost_interrupts; 18 18 19 - /* This number is used when no interrupt has been assigned */ 20 - #define NO_IRQ (0) 21 - 22 19 /* Total number of virq in the platform */ 23 20 #define NR_IRQS CONFIG_NR_IRQS 24 21
+11 -5
arch/powerpc/include/asm/machdep.h
··· 3 3 #define _ASM_POWERPC_MACHDEP_H 4 4 #ifdef __KERNEL__ 5 5 6 + #include <linux/compiler.h> 6 7 #include <linux/seq_file.h> 7 8 #include <linux/init.h> 8 9 #include <linux/dma-mapping.h> ··· 221 220 EXPORT_SYMBOL(mach_##name); \ 222 221 struct machdep_calls mach_##name __machine_desc = 223 222 224 - #define machine_is(name) \ 225 - ({ \ 226 - extern struct machdep_calls mach_##name \ 227 - __attribute__((weak)); \ 228 - machine_id == &mach_##name; \ 223 + static inline bool __machine_is(const struct machdep_calls *md) 224 + { 225 + WARN_ON(!machine_id); // complain if used before probe_machine() 226 + return machine_id == md; 227 + } 228 + 229 + #define machine_is(name) \ 230 + ({ \ 231 + extern struct machdep_calls mach_##name __weak; \ 232 + __machine_is(&mach_##name); \ 229 233 }) 230 234 231 235 static inline void log_error(char *buf, unsigned int err_type, int fatal)
-1
arch/powerpc/include/asm/paca.h
··· 295 295 296 296 #else /* CONFIG_PPC64 */ 297 297 298 - static inline void allocate_paca_ptrs(void) { } 299 298 static inline void allocate_paca(int cpu) { } 300 299 static inline void free_unused_pacas(void) { } 301 300
+38
arch/powerpc/include/asm/papr-sysparm.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + #ifndef _ASM_POWERPC_PAPR_SYSPARM_H 3 + #define _ASM_POWERPC_PAPR_SYSPARM_H 4 + 5 + typedef struct { 6 + const u32 token; 7 + } papr_sysparm_t; 8 + 9 + #define mk_papr_sysparm(x_) ((papr_sysparm_t){ .token = x_, }) 10 + 11 + /* 12 + * Derived from the "Defined Parameters" table in PAPR 7.3.16 System 13 + * Parameters Option. Where the spec says "characteristics", we use 14 + * "attrs" in the symbolic names to keep them from getting too 15 + * unwieldy. 16 + */ 17 + #define PAPR_SYSPARM_SHARED_PROC_LPAR_ATTRS mk_papr_sysparm(20) 18 + #define PAPR_SYSPARM_PROC_MODULE_INFO mk_papr_sysparm(43) 19 + #define PAPR_SYSPARM_COOP_MEM_OVERCOMMIT_ATTRS mk_papr_sysparm(44) 20 + #define PAPR_SYSPARM_TLB_BLOCK_INVALIDATE_ATTRS mk_papr_sysparm(50) 21 + #define PAPR_SYSPARM_LPAR_NAME mk_papr_sysparm(55) 22 + 23 + enum { 24 + PAPR_SYSPARM_MAX_INPUT = 1024, 25 + PAPR_SYSPARM_MAX_OUTPUT = 4000, 26 + }; 27 + 28 + struct papr_sysparm_buf { 29 + __be16 len; 30 + char val[PAPR_SYSPARM_MAX_OUTPUT]; 31 + }; 32 + 33 + struct papr_sysparm_buf *papr_sysparm_buf_alloc(void); 34 + void papr_sysparm_buf_free(struct papr_sysparm_buf *buf); 35 + int papr_sysparm_set(papr_sysparm_t param, const struct papr_sysparm_buf *buf); 36 + int papr_sysparm_get(papr_sysparm_t param, struct papr_sysparm_buf *buf); 37 + 38 + #endif /* _ASM_POWERPC_PAPR_SYSPARM_H */
+3 -1
arch/powerpc/include/asm/pci-bridge.h
··· 176 176 #endif 177 177 #ifndef CONFIG_PPC64 178 178 179 - #ifdef CONFIG_PPC_CHRP 179 + #ifdef CONFIG_PPC_PCI_OF_BUS_MAP 180 180 extern void pci_create_OF_bus_map(void); 181 + #else 182 + static inline void pci_create_OF_bus_map(void) {} 181 183 #endif 182 184 183 185 #else /* CONFIG_PPC64 */
+195
arch/powerpc/include/asm/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 _ASM_POWERPC_PLPKS_H 10 + #define _ASM_POWERPC_PLPKS_H 11 + 12 + #ifdef CONFIG_PSERIES_PLPKS 13 + 14 + #include <linux/types.h> 15 + #include <linux/list.h> 16 + 17 + // Object policy flags from supported_policies 18 + #define PLPKS_OSSECBOOTAUDIT PPC_BIT32(1) // OS secure boot must be audit/enforce 19 + #define PLPKS_OSSECBOOTENFORCE PPC_BIT32(2) // OS secure boot must be enforce 20 + #define PLPKS_PWSET PPC_BIT32(3) // No access without password set 21 + #define PLPKS_WORLDREADABLE PPC_BIT32(4) // Readable without authentication 22 + #define PLPKS_IMMUTABLE PPC_BIT32(5) // Once written, object cannot be removed 23 + #define PLPKS_TRANSIENT PPC_BIT32(6) // Object does not persist through reboot 24 + #define PLPKS_SIGNEDUPDATE PPC_BIT32(7) // Object can only be modified by signed updates 25 + #define PLPKS_HVPROVISIONED PPC_BIT32(28) // Hypervisor has provisioned this object 26 + 27 + // Signature algorithm flags from signed_update_algorithms 28 + #define PLPKS_ALG_RSA2048 PPC_BIT(0) 29 + #define PLPKS_ALG_RSA4096 PPC_BIT(1) 30 + 31 + // Object label OS metadata flags 32 + #define PLPKS_VAR_LINUX 0x02 33 + #define PLPKS_VAR_COMMON 0x04 34 + 35 + // Flags for which consumer owns an object is owned by 36 + #define PLPKS_FW_OWNER 0x1 37 + #define PLPKS_BOOTLOADER_OWNER 0x2 38 + #define PLPKS_OS_OWNER 0x3 39 + 40 + // Flags for label metadata fields 41 + #define PLPKS_LABEL_VERSION 0 42 + #define PLPKS_MAX_LABEL_ATTR_SIZE 16 43 + #define PLPKS_MAX_NAME_SIZE 239 44 + #define PLPKS_MAX_DATA_SIZE 4000 45 + 46 + // Timeouts for PLPKS operations 47 + #define PLPKS_MAX_TIMEOUT 5000 // msec 48 + #define PLPKS_FLUSH_SLEEP 10 // msec 49 + #define PLPKS_FLUSH_SLEEP_RANGE 400 50 + 51 + struct plpks_var { 52 + char *component; 53 + u8 *name; 54 + u8 *data; 55 + u32 policy; 56 + u16 namelen; 57 + u16 datalen; 58 + u8 os; 59 + }; 60 + 61 + struct plpks_var_name { 62 + u8 *name; 63 + u16 namelen; 64 + }; 65 + 66 + struct plpks_var_name_list { 67 + u32 varcount; 68 + struct plpks_var_name varlist[]; 69 + }; 70 + 71 + /** 72 + * Updates the authenticated variable. It expects NULL as the component. 73 + */ 74 + int plpks_signed_update_var(struct plpks_var *var, u64 flags); 75 + 76 + /** 77 + * Writes the specified var and its data to PKS. 78 + * Any caller of PKS driver should present a valid component type for 79 + * their variable. 80 + */ 81 + int plpks_write_var(struct plpks_var var); 82 + 83 + /** 84 + * Removes the specified var and its data from PKS. 85 + */ 86 + int plpks_remove_var(char *component, u8 varos, 87 + struct plpks_var_name vname); 88 + 89 + /** 90 + * Returns the data for the specified os variable. 91 + * 92 + * Caller must allocate a buffer in var->data with length in var->datalen. 93 + * If no buffer is provided, var->datalen will be populated with the object's 94 + * size. 95 + */ 96 + int plpks_read_os_var(struct plpks_var *var); 97 + 98 + /** 99 + * Returns the data for the specified firmware variable. 100 + * 101 + * Caller must allocate a buffer in var->data with length in var->datalen. 102 + * If no buffer is provided, var->datalen will be populated with the object's 103 + * size. 104 + */ 105 + int plpks_read_fw_var(struct plpks_var *var); 106 + 107 + /** 108 + * Returns the data for the specified bootloader variable. 109 + * 110 + * Caller must allocate a buffer in var->data with length in var->datalen. 111 + * If no buffer is provided, var->datalen will be populated with the object's 112 + * size. 113 + */ 114 + int plpks_read_bootloader_var(struct plpks_var *var); 115 + 116 + /** 117 + * Returns if PKS is available on this LPAR. 118 + */ 119 + bool plpks_is_available(void); 120 + 121 + /** 122 + * Returns version of the Platform KeyStore. 123 + */ 124 + u8 plpks_get_version(void); 125 + 126 + /** 127 + * Returns hypervisor storage overhead per object, not including the size of 128 + * the object or label. Only valid for config version >= 2 129 + */ 130 + u16 plpks_get_objoverhead(void); 131 + 132 + /** 133 + * Returns maximum password size. Must be >= 32 bytes 134 + */ 135 + u16 plpks_get_maxpwsize(void); 136 + 137 + /** 138 + * Returns maximum object size supported by Platform KeyStore. 139 + */ 140 + u16 plpks_get_maxobjectsize(void); 141 + 142 + /** 143 + * Returns maximum object label size supported by Platform KeyStore. 144 + */ 145 + u16 plpks_get_maxobjectlabelsize(void); 146 + 147 + /** 148 + * Returns total size of the configured Platform KeyStore. 149 + */ 150 + u32 plpks_get_totalsize(void); 151 + 152 + /** 153 + * Returns used space from the total size of the Platform KeyStore. 154 + */ 155 + u32 plpks_get_usedspace(void); 156 + 157 + /** 158 + * Returns bitmask of policies supported by the hypervisor. 159 + */ 160 + u32 plpks_get_supportedpolicies(void); 161 + 162 + /** 163 + * Returns maximum byte size of a single object supported by the hypervisor. 164 + * Only valid for config version >= 3 165 + */ 166 + u32 plpks_get_maxlargeobjectsize(void); 167 + 168 + /** 169 + * Returns bitmask of signature algorithms supported for signed updates. 170 + * Only valid for config version >= 3 171 + */ 172 + u64 plpks_get_signedupdatealgorithms(void); 173 + 174 + /** 175 + * Returns the length of the PLPKS password in bytes. 176 + */ 177 + u16 plpks_get_passwordlen(void); 178 + 179 + /** 180 + * Called in early init to retrieve and clear the PLPKS password from the DT. 181 + */ 182 + void plpks_early_init_devtree(void); 183 + 184 + /** 185 + * Populates the FDT with the PLPKS password to prepare for kexec. 186 + */ 187 + int plpks_populate_fdt(void *fdt); 188 + #else // CONFIG_PSERIES_PLPKS 189 + static inline bool plpks_is_available(void) { return false; } 190 + static inline u16 plpks_get_passwordlen(void) { BUILD_BUG(); } 191 + static inline void plpks_early_init_devtree(void) { } 192 + static inline int plpks_populate_fdt(void *fdt) { BUILD_BUG(); } 193 + #endif // CONFIG_PSERIES_PLPKS 194 + 195 + #endif // _ASM_POWERPC_PLPKS_H
-2
arch/powerpc/include/asm/rtas-types.h
··· 18 18 unsigned long entry; /* physical address pointer */ 19 19 unsigned long base; /* physical address pointer */ 20 20 unsigned long size; 21 - arch_spinlock_t lock; 22 - struct rtas_args args; 23 21 struct device_node *dev; /* virtual address pointer */ 24 22 }; 25 23
+96
arch/powerpc/include/asm/rtas-work-area.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + #ifndef _ASM_POWERPC_RTAS_WORK_AREA_H 3 + #define _ASM_POWERPC_RTAS_WORK_AREA_H 4 + 5 + #include <linux/build_bug.h> 6 + #include <linux/sizes.h> 7 + #include <linux/types.h> 8 + 9 + #include <asm/page.h> 10 + 11 + /** 12 + * struct rtas_work_area - RTAS work area descriptor. 13 + * 14 + * Descriptor for a "work area" in PAPR terminology that satisfies 15 + * RTAS addressing requirements. 16 + */ 17 + struct rtas_work_area { 18 + /* private: Use the APIs provided below. */ 19 + char *buf; 20 + size_t size; 21 + }; 22 + 23 + enum { 24 + /* Maximum allocation size, enforced at build time. */ 25 + RTAS_WORK_AREA_MAX_ALLOC_SZ = SZ_128K, 26 + }; 27 + 28 + /** 29 + * rtas_work_area_alloc() - Acquire a work area of the requested size. 30 + * @size_: Allocation size. Must be compile-time constant and not more 31 + * than %RTAS_WORK_AREA_MAX_ALLOC_SZ. 32 + * 33 + * Allocate a buffer suitable for passing to RTAS functions that have 34 + * a memory address parameter, often (but not always) referred to as a 35 + * "work area" in PAPR. Although callers are allowed to block while 36 + * holding a work area, the amount of memory reserved for this purpose 37 + * is limited, and allocations should be short-lived. A good guideline 38 + * is to release any allocated work area before returning from a 39 + * system call. 40 + * 41 + * This function does not fail. It blocks until the allocation 42 + * succeeds. To prevent deadlocks, callers are discouraged from 43 + * allocating more than one work area simultaneously in a single task 44 + * context. 45 + * 46 + * Context: This function may sleep. 47 + * Return: A &struct rtas_work_area descriptor for the allocated work area. 48 + */ 49 + #define rtas_work_area_alloc(size_) ({ \ 50 + static_assert(__builtin_constant_p(size_)); \ 51 + static_assert((size_) > 0); \ 52 + static_assert((size_) <= RTAS_WORK_AREA_MAX_ALLOC_SZ); \ 53 + __rtas_work_area_alloc(size_); \ 54 + }) 55 + 56 + /* 57 + * Do not call __rtas_work_area_alloc() directly. Use 58 + * rtas_work_area_alloc(). 59 + */ 60 + struct rtas_work_area *__rtas_work_area_alloc(size_t size); 61 + 62 + /** 63 + * rtas_work_area_free() - Release a work area. 64 + * @area: Work area descriptor as returned from rtas_work_area_alloc(). 65 + * 66 + * Return a work area buffer to the pool. 67 + */ 68 + void rtas_work_area_free(struct rtas_work_area *area); 69 + 70 + static inline char *rtas_work_area_raw_buf(const struct rtas_work_area *area) 71 + { 72 + return area->buf; 73 + } 74 + 75 + static inline size_t rtas_work_area_size(const struct rtas_work_area *area) 76 + { 77 + return area->size; 78 + } 79 + 80 + static inline phys_addr_t rtas_work_area_phys(const struct rtas_work_area *area) 81 + { 82 + return __pa(area->buf); 83 + } 84 + 85 + /* 86 + * Early setup for the work area allocator. Call from 87 + * rtas_initialize() only. 88 + */ 89 + 90 + #ifdef CONFIG_PPC_PSERIES 91 + void rtas_work_area_reserve_arena(phys_addr_t limit); 92 + #else /* CONFIG_PPC_PSERIES */ 93 + static inline void rtas_work_area_reserve_arena(phys_addr_t limit) {} 94 + #endif /* CONFIG_PPC_PSERIES */ 95 + 96 + #endif /* _ASM_POWERPC_RTAS_WORK_AREA_H */
+184
arch/powerpc/include/asm/rtas.h
··· 16 16 * Copyright (C) 2001 PPC 64 Team, IBM Corp 17 17 */ 18 18 19 + enum rtas_function_index { 20 + RTAS_FNIDX__CHECK_EXCEPTION, 21 + RTAS_FNIDX__DISPLAY_CHARACTER, 22 + RTAS_FNIDX__EVENT_SCAN, 23 + RTAS_FNIDX__FREEZE_TIME_BASE, 24 + RTAS_FNIDX__GET_POWER_LEVEL, 25 + RTAS_FNIDX__GET_SENSOR_STATE, 26 + RTAS_FNIDX__GET_TERM_CHAR, 27 + RTAS_FNIDX__GET_TIME_OF_DAY, 28 + RTAS_FNIDX__IBM_ACTIVATE_FIRMWARE, 29 + RTAS_FNIDX__IBM_CBE_START_PTCAL, 30 + RTAS_FNIDX__IBM_CBE_STOP_PTCAL, 31 + RTAS_FNIDX__IBM_CHANGE_MSI, 32 + RTAS_FNIDX__IBM_CLOSE_ERRINJCT, 33 + RTAS_FNIDX__IBM_CONFIGURE_BRIDGE, 34 + RTAS_FNIDX__IBM_CONFIGURE_CONNECTOR, 35 + RTAS_FNIDX__IBM_CONFIGURE_KERNEL_DUMP, 36 + RTAS_FNIDX__IBM_CONFIGURE_PE, 37 + RTAS_FNIDX__IBM_CREATE_PE_DMA_WINDOW, 38 + RTAS_FNIDX__IBM_DISPLAY_MESSAGE, 39 + RTAS_FNIDX__IBM_ERRINJCT, 40 + RTAS_FNIDX__IBM_EXTI2C, 41 + RTAS_FNIDX__IBM_GET_CONFIG_ADDR_INFO, 42 + RTAS_FNIDX__IBM_GET_CONFIG_ADDR_INFO2, 43 + RTAS_FNIDX__IBM_GET_DYNAMIC_SENSOR_STATE, 44 + RTAS_FNIDX__IBM_GET_INDICES, 45 + RTAS_FNIDX__IBM_GET_RIO_TOPOLOGY, 46 + RTAS_FNIDX__IBM_GET_SYSTEM_PARAMETER, 47 + RTAS_FNIDX__IBM_GET_VPD, 48 + RTAS_FNIDX__IBM_GET_XIVE, 49 + RTAS_FNIDX__IBM_INT_OFF, 50 + RTAS_FNIDX__IBM_INT_ON, 51 + RTAS_FNIDX__IBM_IO_QUIESCE_ACK, 52 + RTAS_FNIDX__IBM_LPAR_PERFTOOLS, 53 + RTAS_FNIDX__IBM_MANAGE_FLASH_IMAGE, 54 + RTAS_FNIDX__IBM_MANAGE_STORAGE_PRESERVATION, 55 + RTAS_FNIDX__IBM_NMI_INTERLOCK, 56 + RTAS_FNIDX__IBM_NMI_REGISTER, 57 + RTAS_FNIDX__IBM_OPEN_ERRINJCT, 58 + RTAS_FNIDX__IBM_OPEN_SRIOV_ALLOW_UNFREEZE, 59 + RTAS_FNIDX__IBM_OPEN_SRIOV_MAP_PE_NUMBER, 60 + RTAS_FNIDX__IBM_OS_TERM, 61 + RTAS_FNIDX__IBM_PARTNER_CONTROL, 62 + RTAS_FNIDX__IBM_PHYSICAL_ATTESTATION, 63 + RTAS_FNIDX__IBM_PLATFORM_DUMP, 64 + RTAS_FNIDX__IBM_POWER_OFF_UPS, 65 + RTAS_FNIDX__IBM_QUERY_INTERRUPT_SOURCE_NUMBER, 66 + RTAS_FNIDX__IBM_QUERY_PE_DMA_WINDOW, 67 + RTAS_FNIDX__IBM_READ_PCI_CONFIG, 68 + RTAS_FNIDX__IBM_READ_SLOT_RESET_STATE, 69 + RTAS_FNIDX__IBM_READ_SLOT_RESET_STATE2, 70 + RTAS_FNIDX__IBM_REMOVE_PE_DMA_WINDOW, 71 + RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOWS, 72 + RTAS_FNIDX__IBM_SCAN_LOG_DUMP, 73 + RTAS_FNIDX__IBM_SET_DYNAMIC_INDICATOR, 74 + RTAS_FNIDX__IBM_SET_EEH_OPTION, 75 + RTAS_FNIDX__IBM_SET_SLOT_RESET, 76 + RTAS_FNIDX__IBM_SET_SYSTEM_PARAMETER, 77 + RTAS_FNIDX__IBM_SET_XIVE, 78 + RTAS_FNIDX__IBM_SLOT_ERROR_DETAIL, 79 + RTAS_FNIDX__IBM_SUSPEND_ME, 80 + RTAS_FNIDX__IBM_TUNE_DMA_PARMS, 81 + RTAS_FNIDX__IBM_UPDATE_FLASH_64_AND_REBOOT, 82 + RTAS_FNIDX__IBM_UPDATE_NODES, 83 + RTAS_FNIDX__IBM_UPDATE_PROPERTIES, 84 + RTAS_FNIDX__IBM_VALIDATE_FLASH_IMAGE, 85 + RTAS_FNIDX__IBM_WRITE_PCI_CONFIG, 86 + RTAS_FNIDX__NVRAM_FETCH, 87 + RTAS_FNIDX__NVRAM_STORE, 88 + RTAS_FNIDX__POWER_OFF, 89 + RTAS_FNIDX__PUT_TERM_CHAR, 90 + RTAS_FNIDX__QUERY_CPU_STOPPED_STATE, 91 + RTAS_FNIDX__READ_PCI_CONFIG, 92 + RTAS_FNIDX__RTAS_LAST_ERROR, 93 + RTAS_FNIDX__SET_INDICATOR, 94 + RTAS_FNIDX__SET_POWER_LEVEL, 95 + RTAS_FNIDX__SET_TIME_FOR_POWER_ON, 96 + RTAS_FNIDX__SET_TIME_OF_DAY, 97 + RTAS_FNIDX__START_CPU, 98 + RTAS_FNIDX__STOP_SELF, 99 + RTAS_FNIDX__SYSTEM_REBOOT, 100 + RTAS_FNIDX__THAW_TIME_BASE, 101 + RTAS_FNIDX__WRITE_PCI_CONFIG, 102 + }; 103 + 104 + /* 105 + * Opaque handle for client code to refer to RTAS functions. All valid 106 + * function handles are build-time constants prefixed with RTAS_FN_. 107 + */ 108 + typedef struct { 109 + const enum rtas_function_index index; 110 + } rtas_fn_handle_t; 111 + 112 + 113 + #define rtas_fn_handle(x_) ((const rtas_fn_handle_t) { .index = x_, }) 114 + 115 + #define RTAS_FN_CHECK_EXCEPTION rtas_fn_handle(RTAS_FNIDX__CHECK_EXCEPTION) 116 + #define RTAS_FN_DISPLAY_CHARACTER rtas_fn_handle(RTAS_FNIDX__DISPLAY_CHARACTER) 117 + #define RTAS_FN_EVENT_SCAN rtas_fn_handle(RTAS_FNIDX__EVENT_SCAN) 118 + #define RTAS_FN_FREEZE_TIME_BASE rtas_fn_handle(RTAS_FNIDX__FREEZE_TIME_BASE) 119 + #define RTAS_FN_GET_POWER_LEVEL rtas_fn_handle(RTAS_FNIDX__GET_POWER_LEVEL) 120 + #define RTAS_FN_GET_SENSOR_STATE rtas_fn_handle(RTAS_FNIDX__GET_SENSOR_STATE) 121 + #define RTAS_FN_GET_TERM_CHAR rtas_fn_handle(RTAS_FNIDX__GET_TERM_CHAR) 122 + #define RTAS_FN_GET_TIME_OF_DAY rtas_fn_handle(RTAS_FNIDX__GET_TIME_OF_DAY) 123 + #define RTAS_FN_IBM_ACTIVATE_FIRMWARE rtas_fn_handle(RTAS_FNIDX__IBM_ACTIVATE_FIRMWARE) 124 + #define RTAS_FN_IBM_CBE_START_PTCAL rtas_fn_handle(RTAS_FNIDX__IBM_CBE_START_PTCAL) 125 + #define RTAS_FN_IBM_CBE_STOP_PTCAL rtas_fn_handle(RTAS_FNIDX__IBM_CBE_STOP_PTCAL) 126 + #define RTAS_FN_IBM_CHANGE_MSI rtas_fn_handle(RTAS_FNIDX__IBM_CHANGE_MSI) 127 + #define RTAS_FN_IBM_CLOSE_ERRINJCT rtas_fn_handle(RTAS_FNIDX__IBM_CLOSE_ERRINJCT) 128 + #define RTAS_FN_IBM_CONFIGURE_BRIDGE rtas_fn_handle(RTAS_FNIDX__IBM_CONFIGURE_BRIDGE) 129 + #define RTAS_FN_IBM_CONFIGURE_CONNECTOR rtas_fn_handle(RTAS_FNIDX__IBM_CONFIGURE_CONNECTOR) 130 + #define RTAS_FN_IBM_CONFIGURE_KERNEL_DUMP rtas_fn_handle(RTAS_FNIDX__IBM_CONFIGURE_KERNEL_DUMP) 131 + #define RTAS_FN_IBM_CONFIGURE_PE rtas_fn_handle(RTAS_FNIDX__IBM_CONFIGURE_PE) 132 + #define RTAS_FN_IBM_CREATE_PE_DMA_WINDOW rtas_fn_handle(RTAS_FNIDX__IBM_CREATE_PE_DMA_WINDOW) 133 + #define RTAS_FN_IBM_DISPLAY_MESSAGE rtas_fn_handle(RTAS_FNIDX__IBM_DISPLAY_MESSAGE) 134 + #define RTAS_FN_IBM_ERRINJCT rtas_fn_handle(RTAS_FNIDX__IBM_ERRINJCT) 135 + #define RTAS_FN_IBM_EXTI2C rtas_fn_handle(RTAS_FNIDX__IBM_EXTI2C) 136 + #define RTAS_FN_IBM_GET_CONFIG_ADDR_INFO rtas_fn_handle(RTAS_FNIDX__IBM_GET_CONFIG_ADDR_INFO) 137 + #define RTAS_FN_IBM_GET_CONFIG_ADDR_INFO2 rtas_fn_handle(RTAS_FNIDX__IBM_GET_CONFIG_ADDR_INFO2) 138 + #define RTAS_FN_IBM_GET_DYNAMIC_SENSOR_STATE rtas_fn_handle(RTAS_FNIDX__IBM_GET_DYNAMIC_SENSOR_STATE) 139 + #define RTAS_FN_IBM_GET_INDICES rtas_fn_handle(RTAS_FNIDX__IBM_GET_INDICES) 140 + #define RTAS_FN_IBM_GET_RIO_TOPOLOGY rtas_fn_handle(RTAS_FNIDX__IBM_GET_RIO_TOPOLOGY) 141 + #define RTAS_FN_IBM_GET_SYSTEM_PARAMETER rtas_fn_handle(RTAS_FNIDX__IBM_GET_SYSTEM_PARAMETER) 142 + #define RTAS_FN_IBM_GET_VPD rtas_fn_handle(RTAS_FNIDX__IBM_GET_VPD) 143 + #define RTAS_FN_IBM_GET_XIVE rtas_fn_handle(RTAS_FNIDX__IBM_GET_XIVE) 144 + #define RTAS_FN_IBM_INT_OFF rtas_fn_handle(RTAS_FNIDX__IBM_INT_OFF) 145 + #define RTAS_FN_IBM_INT_ON rtas_fn_handle(RTAS_FNIDX__IBM_INT_ON) 146 + #define RTAS_FN_IBM_IO_QUIESCE_ACK rtas_fn_handle(RTAS_FNIDX__IBM_IO_QUIESCE_ACK) 147 + #define RTAS_FN_IBM_LPAR_PERFTOOLS rtas_fn_handle(RTAS_FNIDX__IBM_LPAR_PERFTOOLS) 148 + #define RTAS_FN_IBM_MANAGE_FLASH_IMAGE rtas_fn_handle(RTAS_FNIDX__IBM_MANAGE_FLASH_IMAGE) 149 + #define RTAS_FN_IBM_MANAGE_STORAGE_PRESERVATION rtas_fn_handle(RTAS_FNIDX__IBM_MANAGE_STORAGE_PRESERVATION) 150 + #define RTAS_FN_IBM_NMI_INTERLOCK rtas_fn_handle(RTAS_FNIDX__IBM_NMI_INTERLOCK) 151 + #define RTAS_FN_IBM_NMI_REGISTER rtas_fn_handle(RTAS_FNIDX__IBM_NMI_REGISTER) 152 + #define RTAS_FN_IBM_OPEN_ERRINJCT rtas_fn_handle(RTAS_FNIDX__IBM_OPEN_ERRINJCT) 153 + #define RTAS_FN_IBM_OPEN_SRIOV_ALLOW_UNFREEZE rtas_fn_handle(RTAS_FNIDX__IBM_OPEN_SRIOV_ALLOW_UNFREEZE) 154 + #define RTAS_FN_IBM_OPEN_SRIOV_MAP_PE_NUMBER rtas_fn_handle(RTAS_FNIDX__IBM_OPEN_SRIOV_MAP_PE_NUMBER) 155 + #define RTAS_FN_IBM_OS_TERM rtas_fn_handle(RTAS_FNIDX__IBM_OS_TERM) 156 + #define RTAS_FN_IBM_PARTNER_CONTROL rtas_fn_handle(RTAS_FNIDX__IBM_PARTNER_CONTROL) 157 + #define RTAS_FN_IBM_PHYSICAL_ATTESTATION rtas_fn_handle(RTAS_FNIDX__IBM_PHYSICAL_ATTESTATION) 158 + #define RTAS_FN_IBM_PLATFORM_DUMP rtas_fn_handle(RTAS_FNIDX__IBM_PLATFORM_DUMP) 159 + #define RTAS_FN_IBM_POWER_OFF_UPS rtas_fn_handle(RTAS_FNIDX__IBM_POWER_OFF_UPS) 160 + #define RTAS_FN_IBM_QUERY_INTERRUPT_SOURCE_NUMBER rtas_fn_handle(RTAS_FNIDX__IBM_QUERY_INTERRUPT_SOURCE_NUMBER) 161 + #define RTAS_FN_IBM_QUERY_PE_DMA_WINDOW rtas_fn_handle(RTAS_FNIDX__IBM_QUERY_PE_DMA_WINDOW) 162 + #define RTAS_FN_IBM_READ_PCI_CONFIG rtas_fn_handle(RTAS_FNIDX__IBM_READ_PCI_CONFIG) 163 + #define RTAS_FN_IBM_READ_SLOT_RESET_STATE rtas_fn_handle(RTAS_FNIDX__IBM_READ_SLOT_RESET_STATE) 164 + #define RTAS_FN_IBM_READ_SLOT_RESET_STATE2 rtas_fn_handle(RTAS_FNIDX__IBM_READ_SLOT_RESET_STATE2) 165 + #define RTAS_FN_IBM_REMOVE_PE_DMA_WINDOW rtas_fn_handle(RTAS_FNIDX__IBM_REMOVE_PE_DMA_WINDOW) 166 + #define RTAS_FN_IBM_RESET_PE_DMA_WINDOWS rtas_fn_handle(RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOWS) 167 + #define RTAS_FN_IBM_SCAN_LOG_DUMP rtas_fn_handle(RTAS_FNIDX__IBM_SCAN_LOG_DUMP) 168 + #define RTAS_FN_IBM_SET_DYNAMIC_INDICATOR rtas_fn_handle(RTAS_FNIDX__IBM_SET_DYNAMIC_INDICATOR) 169 + #define RTAS_FN_IBM_SET_EEH_OPTION rtas_fn_handle(RTAS_FNIDX__IBM_SET_EEH_OPTION) 170 + #define RTAS_FN_IBM_SET_SLOT_RESET rtas_fn_handle(RTAS_FNIDX__IBM_SET_SLOT_RESET) 171 + #define RTAS_FN_IBM_SET_SYSTEM_PARAMETER rtas_fn_handle(RTAS_FNIDX__IBM_SET_SYSTEM_PARAMETER) 172 + #define RTAS_FN_IBM_SET_XIVE rtas_fn_handle(RTAS_FNIDX__IBM_SET_XIVE) 173 + #define RTAS_FN_IBM_SLOT_ERROR_DETAIL rtas_fn_handle(RTAS_FNIDX__IBM_SLOT_ERROR_DETAIL) 174 + #define RTAS_FN_IBM_SUSPEND_ME rtas_fn_handle(RTAS_FNIDX__IBM_SUSPEND_ME) 175 + #define RTAS_FN_IBM_TUNE_DMA_PARMS rtas_fn_handle(RTAS_FNIDX__IBM_TUNE_DMA_PARMS) 176 + #define RTAS_FN_IBM_UPDATE_FLASH_64_AND_REBOOT rtas_fn_handle(RTAS_FNIDX__IBM_UPDATE_FLASH_64_AND_REBOOT) 177 + #define RTAS_FN_IBM_UPDATE_NODES rtas_fn_handle(RTAS_FNIDX__IBM_UPDATE_NODES) 178 + #define RTAS_FN_IBM_UPDATE_PROPERTIES rtas_fn_handle(RTAS_FNIDX__IBM_UPDATE_PROPERTIES) 179 + #define RTAS_FN_IBM_VALIDATE_FLASH_IMAGE rtas_fn_handle(RTAS_FNIDX__IBM_VALIDATE_FLASH_IMAGE) 180 + #define RTAS_FN_IBM_WRITE_PCI_CONFIG rtas_fn_handle(RTAS_FNIDX__IBM_WRITE_PCI_CONFIG) 181 + #define RTAS_FN_NVRAM_FETCH rtas_fn_handle(RTAS_FNIDX__NVRAM_FETCH) 182 + #define RTAS_FN_NVRAM_STORE rtas_fn_handle(RTAS_FNIDX__NVRAM_STORE) 183 + #define RTAS_FN_POWER_OFF rtas_fn_handle(RTAS_FNIDX__POWER_OFF) 184 + #define RTAS_FN_PUT_TERM_CHAR rtas_fn_handle(RTAS_FNIDX__PUT_TERM_CHAR) 185 + #define RTAS_FN_QUERY_CPU_STOPPED_STATE rtas_fn_handle(RTAS_FNIDX__QUERY_CPU_STOPPED_STATE) 186 + #define RTAS_FN_READ_PCI_CONFIG rtas_fn_handle(RTAS_FNIDX__READ_PCI_CONFIG) 187 + #define RTAS_FN_RTAS_LAST_ERROR rtas_fn_handle(RTAS_FNIDX__RTAS_LAST_ERROR) 188 + #define RTAS_FN_SET_INDICATOR rtas_fn_handle(RTAS_FNIDX__SET_INDICATOR) 189 + #define RTAS_FN_SET_POWER_LEVEL rtas_fn_handle(RTAS_FNIDX__SET_POWER_LEVEL) 190 + #define RTAS_FN_SET_TIME_FOR_POWER_ON rtas_fn_handle(RTAS_FNIDX__SET_TIME_FOR_POWER_ON) 191 + #define RTAS_FN_SET_TIME_OF_DAY rtas_fn_handle(RTAS_FNIDX__SET_TIME_OF_DAY) 192 + #define RTAS_FN_START_CPU rtas_fn_handle(RTAS_FNIDX__START_CPU) 193 + #define RTAS_FN_STOP_SELF rtas_fn_handle(RTAS_FNIDX__STOP_SELF) 194 + #define RTAS_FN_SYSTEM_REBOOT rtas_fn_handle(RTAS_FNIDX__SYSTEM_REBOOT) 195 + #define RTAS_FN_THAW_TIME_BASE rtas_fn_handle(RTAS_FNIDX__THAW_TIME_BASE) 196 + #define RTAS_FN_WRITE_PCI_CONFIG rtas_fn_handle(RTAS_FNIDX__WRITE_PCI_CONFIG) 197 + 19 198 #define RTAS_UNKNOWN_SERVICE (-1) 20 199 #define RTAS_INSTANTIATE_MAX (1ULL<<30) /* Don't instantiate rtas at/above this value */ 21 200 ··· 401 222 402 223 extern struct rtas_t rtas; 403 224 225 + s32 rtas_function_token(const rtas_fn_handle_t handle); 226 + static inline bool rtas_function_implemented(const rtas_fn_handle_t handle) 227 + { 228 + return rtas_function_token(handle) != RTAS_UNKNOWN_SERVICE; 229 + } 404 230 extern int rtas_token(const char *service); 405 231 extern int rtas_service_present(const char *service); 406 232 extern int rtas_call(int token, int, int, int *, ...);
+13 -8
arch/powerpc/include/asm/secvar.h
··· 10 10 11 11 #include <linux/types.h> 12 12 #include <linux/errno.h> 13 + #include <linux/sysfs.h> 13 14 14 15 extern const struct secvar_operations *secvar_ops; 15 16 16 17 struct secvar_operations { 17 - int (*get)(const char *key, uint64_t key_len, u8 *data, 18 - uint64_t *data_size); 19 - int (*get_next)(const char *key, uint64_t *key_len, 20 - uint64_t keybufsize); 21 - int (*set)(const char *key, uint64_t key_len, u8 *data, 22 - uint64_t data_size); 18 + int (*get)(const char *key, u64 key_len, u8 *data, u64 *data_size); 19 + int (*get_next)(const char *key, u64 *key_len, u64 keybufsize); 20 + int (*set)(const char *key, u64 key_len, u8 *data, u64 data_size); 21 + ssize_t (*format)(char *buf, size_t bufsize); 22 + int (*max_size)(u64 *max_size); 23 + const struct attribute **config_attrs; 24 + 25 + // NULL-terminated array of fixed variable names 26 + // Only used if get_next() isn't provided 27 + const char * const *var_names; 23 28 }; 24 29 25 30 #ifdef CONFIG_PPC_SECURE_BOOT 26 31 27 - extern void set_secvar_ops(const struct secvar_operations *ops); 32 + int set_secvar_ops(const struct secvar_operations *ops); 28 33 29 34 #else 30 35 31 - static inline void set_secvar_ops(const struct secvar_operations *ops) { } 36 + static inline int set_secvar_ops(const struct secvar_operations *ops) { return 0; } 32 37 33 38 #endif 34 39
+1
arch/powerpc/include/asm/smp.h
··· 26 26 #include <asm/percpu.h> 27 27 28 28 extern int boot_cpuid; 29 + extern int boot_cpu_hwid; /* PPC64 only */ 29 30 extern int spinning_secondaries; 30 31 extern u32 *cpu_to_phys_id; 31 32 extern bool coregroup_enabled;
+103
arch/powerpc/include/asm/trace.h
··· 119 119 ); 120 120 #endif 121 121 122 + #ifdef CONFIG_PPC_RTAS 123 + 124 + #include <asm/rtas-types.h> 125 + 126 + TRACE_EVENT(rtas_input, 127 + 128 + TP_PROTO(struct rtas_args *rtas_args, const char *name), 129 + 130 + TP_ARGS(rtas_args, name), 131 + 132 + TP_STRUCT__entry( 133 + __field(__u32, nargs) 134 + __string(name, name) 135 + __dynamic_array(__u32, inputs, be32_to_cpu(rtas_args->nargs)) 136 + ), 137 + 138 + TP_fast_assign( 139 + __entry->nargs = be32_to_cpu(rtas_args->nargs); 140 + __assign_str(name, name); 141 + be32_to_cpu_array(__get_dynamic_array(inputs), rtas_args->args, __entry->nargs); 142 + ), 143 + 144 + TP_printk("%s arguments: %s", __get_str(name), 145 + __print_array(__get_dynamic_array(inputs), __entry->nargs, 4) 146 + ) 147 + ); 148 + 149 + TRACE_EVENT(rtas_output, 150 + 151 + TP_PROTO(struct rtas_args *rtas_args, const char *name), 152 + 153 + TP_ARGS(rtas_args, name), 154 + 155 + TP_STRUCT__entry( 156 + __field(__u32, nr_other) 157 + __field(__s32, status) 158 + __string(name, name) 159 + __dynamic_array(__u32, other_outputs, be32_to_cpu(rtas_args->nret) - 1) 160 + ), 161 + 162 + TP_fast_assign( 163 + __entry->nr_other = be32_to_cpu(rtas_args->nret) - 1; 164 + __entry->status = be32_to_cpu(rtas_args->rets[0]); 165 + __assign_str(name, name); 166 + be32_to_cpu_array(__get_dynamic_array(other_outputs), 167 + &rtas_args->rets[1], __entry->nr_other); 168 + ), 169 + 170 + TP_printk("%s status: %d, other outputs: %s", __get_str(name), __entry->status, 171 + __print_array(__get_dynamic_array(other_outputs), 172 + __entry->nr_other, 4) 173 + ) 174 + ); 175 + 176 + DECLARE_EVENT_CLASS(rtas_parameter_block, 177 + 178 + TP_PROTO(struct rtas_args *rtas_args), 179 + 180 + TP_ARGS(rtas_args), 181 + 182 + TP_STRUCT__entry( 183 + __field(u32, token) 184 + __field(u32, nargs) 185 + __field(u32, nret) 186 + __array(__u32, params, 16) 187 + ), 188 + 189 + TP_fast_assign( 190 + __entry->token = be32_to_cpu(rtas_args->token); 191 + __entry->nargs = be32_to_cpu(rtas_args->nargs); 192 + __entry->nret = be32_to_cpu(rtas_args->nret); 193 + be32_to_cpu_array(__entry->params, rtas_args->args, ARRAY_SIZE(rtas_args->args)); 194 + ), 195 + 196 + TP_printk("token=%u nargs=%u nret=%u params:" 197 + " [0]=0x%08x [1]=0x%08x [2]=0x%08x [3]=0x%08x" 198 + " [4]=0x%08x [5]=0x%08x [6]=0x%08x [7]=0x%08x" 199 + " [8]=0x%08x [9]=0x%08x [10]=0x%08x [11]=0x%08x" 200 + " [12]=0x%08x [13]=0x%08x [14]=0x%08x [15]=0x%08x", 201 + __entry->token, __entry->nargs, __entry->nret, 202 + __entry->params[0], __entry->params[1], __entry->params[2], __entry->params[3], 203 + __entry->params[4], __entry->params[5], __entry->params[6], __entry->params[7], 204 + __entry->params[8], __entry->params[9], __entry->params[10], __entry->params[11], 205 + __entry->params[12], __entry->params[13], __entry->params[14], __entry->params[15] 206 + ) 207 + ); 208 + 209 + DEFINE_EVENT(rtas_parameter_block, rtas_ll_entry, 210 + 211 + TP_PROTO(struct rtas_args *rtas_args), 212 + 213 + TP_ARGS(rtas_args) 214 + ); 215 + 216 + DEFINE_EVENT(rtas_parameter_block, rtas_ll_exit, 217 + 218 + TP_PROTO(struct rtas_args *rtas_args), 219 + 220 + TP_ARGS(rtas_args) 221 + ); 222 + 223 + #endif /* CONFIG_PPC_RTAS */ 224 + 122 225 #ifdef CONFIG_PPC_POWERNV 123 226 extern int opal_tracepoint_regfunc(void); 124 227 extern void opal_tracepoint_unregfunc(void);
+10
arch/powerpc/kernel/Makefile
··· 54 54 CFLAGS_btext.o += -DDISABLE_BRANCH_PROFILING 55 55 endif 56 56 57 + KCSAN_SANITIZE_early_32.o := n 58 + KCSAN_SANITIZE_early_64.o := n 59 + KCSAN_SANITIZE_cputable.o := n 60 + KCSAN_SANITIZE_btext.o := n 61 + KCSAN_SANITIZE_paca.o := n 62 + KCSAN_SANITIZE_setup_64.o := n 63 + 57 64 #ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET 58 65 # Remove stack protector to avoid triggering unneeded stack canary 59 66 # checks due to randomize_kstack_offset. ··· 184 177 # Disable GCOV, KCOV & sanitizers in odd or sensitive code 185 178 GCOV_PROFILE_prom_init.o := n 186 179 KCOV_INSTRUMENT_prom_init.o := n 180 + KCSAN_SANITIZE_prom_init.o := n 187 181 UBSAN_SANITIZE_prom_init.o := n 188 182 GCOV_PROFILE_kprobes.o := n 189 183 KCOV_INSTRUMENT_kprobes.o := n 184 + KCSAN_SANITIZE_kprobes.o := n 190 185 UBSAN_SANITIZE_kprobes.o := n 191 186 GCOV_PROFILE_kprobes-ftrace.o := n 192 187 KCOV_INSTRUMENT_kprobes-ftrace.o := n 188 + KCSAN_SANITIZE_kprobes-ftrace.o := n 193 189 UBSAN_SANITIZE_kprobes-ftrace.o := n 194 190 GCOV_PROFILE_syscall_64.o := n 195 191 KCOV_INSTRUMENT_syscall_64.o := n
+2 -2
arch/powerpc/kernel/eeh_driver.c
··· 1065 1065 eeh_slot_error_detail(pe, EEH_LOG_PERM); 1066 1066 1067 1067 /* Notify all devices that they're about to go down. */ 1068 - eeh_set_channel_state(pe, pci_channel_io_perm_failure); 1069 1068 eeh_set_irq_state(pe, false); 1070 1069 eeh_pe_report("error_detected(permanent failure)", pe, 1071 1070 eeh_report_failure, NULL); 1071 + eeh_set_channel_state(pe, pci_channel_io_perm_failure); 1072 1072 1073 1073 /* Mark the PE to be removed permanently */ 1074 1074 eeh_pe_state_mark(pe, EEH_PE_REMOVED); ··· 1185 1185 1186 1186 /* Notify all devices to be down */ 1187 1187 eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true); 1188 - eeh_set_channel_state(pe, pci_channel_io_perm_failure); 1189 1188 eeh_pe_report( 1190 1189 "error_detected(permanent failure)", pe, 1191 1190 eeh_report_failure, NULL); 1191 + eeh_set_channel_state(pe, pci_channel_io_perm_failure); 1192 1192 1193 1193 pci_lock_rescan_remove(); 1194 1194 list_for_each_entry(hose, &hose_list, list_node) {
+6
arch/powerpc/kernel/epapr_hcalls.S
··· 21 21 ori r4, r4,_TLF_NAPPING /* so when we take an exception */ 22 22 PPC_STL r4, TI_LOCAL_FLAGS(r2) /* it will return to our caller */ 23 23 24 + #ifdef CONFIG_BOOKE_OR_40x 24 25 wrteei 1 26 + #else 27 + mfmsr r4 28 + ori r4, r4, MSR_EE 29 + mtmsr r4 30 + #endif 25 31 26 32 idle_loop: 27 33 LOAD_REG_IMMEDIATE(r11, EV_HCALL_TOKEN(EV_IDLE))
+27 -24
arch/powerpc/kernel/head_64.S
··· 160 160 std r24,(ABS_ADDR(__secondary_hold_acknowledge, first_256B))(0) 161 161 sync 162 162 163 - li r26,0 164 - #ifdef CONFIG_PPC_BOOK3E_64 165 - tovirt(r26,r26) 166 - #endif 167 163 /* All secondary cpus wait here until told to start. */ 168 - 100: ld r12,(ABS_ADDR(__secondary_hold_spinloop, first_256B))(r26) 164 + 100: ld r12,(ABS_ADDR(__secondary_hold_spinloop, first_256B))(0) 169 165 cmpdi 0,r12,0 170 166 beq 100b 171 167 ··· 471 475 rfid 472 476 b . /* prevent speculative execution */ 473 477 SYM_FUNC_END(__mmu_off) 474 - #endif 475 478 479 + SYM_FUNC_START_LOCAL(start_initialization_book3s) 480 + mflr r25 481 + 482 + /* Setup some critical 970 SPRs before switching MMU off */ 483 + mfspr r0,SPRN_PVR 484 + srwi r0,r0,16 485 + cmpwi r0,0x39 /* 970 */ 486 + beq 1f 487 + cmpwi r0,0x3c /* 970FX */ 488 + beq 1f 489 + cmpwi r0,0x44 /* 970MP */ 490 + beq 1f 491 + cmpwi r0,0x45 /* 970GX */ 492 + bne 2f 493 + 1: bl __cpu_preinit_ppc970 494 + 2: 495 + 496 + /* Switch off MMU if not already off */ 497 + bl __mmu_off 498 + 499 + mtlr r25 500 + blr 501 + SYM_FUNC_END(start_initialization_book3s) 502 + #endif 476 503 477 504 /* 478 505 * Here is our main kernel entry point. We support currently 2 kind of entries ··· 542 523 543 524 #ifdef CONFIG_PPC_BOOK3E_64 544 525 bl start_initialization_book3e 545 - b __after_prom_start 546 526 #else 547 - /* Setup some critical 970 SPRs before switching MMU off */ 548 - mfspr r0,SPRN_PVR 549 - srwi r0,r0,16 550 - cmpwi r0,0x39 /* 970 */ 551 - beq 1f 552 - cmpwi r0,0x3c /* 970FX */ 553 - beq 1f 554 - cmpwi r0,0x44 /* 970MP */ 555 - beq 1f 556 - cmpwi r0,0x45 /* 970GX */ 557 - bne 2f 558 - 1: bl __cpu_preinit_ppc970 559 - 2: 560 - 561 - /* Switch off MMU if not already off */ 562 - bl __mmu_off 563 - b __after_prom_start 527 + bl start_initialization_book3s 564 528 #endif /* CONFIG_PPC_BOOK3E_64 */ 529 + b __after_prom_start 565 530 566 531 __REF 567 532 __boot_from_prom:
+1 -3
arch/powerpc/kernel/iommu.c
··· 67 67 static void iommu_debugfs_del(struct iommu_table *tbl) 68 68 { 69 69 char name[10]; 70 - struct dentry *liobn_entry; 71 70 72 71 sprintf(name, "%08lx", tbl->it_index); 73 - liobn_entry = debugfs_lookup(name, iommu_debugfs_dir); 74 - debugfs_remove(liobn_entry); 72 + debugfs_lookup_and_remove(name, iommu_debugfs_dir); 75 73 } 76 74 #else 77 75 static void iommu_debugfs_add(struct iommu_table *tbl){}
+68 -37
arch/powerpc/kernel/irq_64.c
··· 70 70 71 71 static inline void next_interrupt(struct pt_regs *regs) 72 72 { 73 - /* 74 - * Softirq processing can enable/disable irqs, which will leave 75 - * MSR[EE] enabled and the soft mask set to IRQS_DISABLED. Fix 76 - * this up. 77 - */ 78 - if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) 79 - hard_irq_disable(); 80 - else 81 - irq_soft_mask_set(IRQS_ALL_DISABLED); 73 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) { 74 + WARN_ON(!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)); 75 + WARN_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED); 76 + } 82 77 83 78 /* 84 79 * We are responding to the next interrupt, so interrupt-off 85 80 * latencies should be reset here. 86 81 */ 82 + lockdep_hardirq_exit(); 87 83 trace_hardirqs_on(); 88 84 trace_hardirqs_off(); 85 + lockdep_hardirq_enter(); 89 86 } 90 87 91 88 static inline bool irq_happened_test_and_clear(u8 irq) ··· 94 97 return false; 95 98 } 96 99 97 - void replay_soft_interrupts(void) 100 + static __no_kcsan void __replay_soft_interrupts(void) 98 101 { 99 102 struct pt_regs regs; 100 103 101 104 /* 102 - * Be careful here, calling these interrupt handlers can cause 103 - * softirqs to be raised, which they may run when calling irq_exit, 104 - * which will cause local_irq_enable() to be run, which can then 105 - * recurse into this function. Don't keep any state across 106 - * interrupt handler calls which may change underneath us. 107 - * 108 - * Softirqs can not be disabled over replay to stop this recursion 109 - * because interrupts taken in idle code may require RCU softirq 110 - * to run in the irq RCU tracking context. This is a hard problem 111 - * to fix without changes to the softirq or idle layer. 112 - * 113 105 * We use local_paca rather than get_paca() to avoid all the 114 106 * debug_smp_processor_id() business in this low level function. 115 107 */ ··· 106 120 if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) { 107 121 WARN_ON_ONCE(mfmsr() & MSR_EE); 108 122 WARN_ON(!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)); 123 + WARN_ON(local_paca->irq_happened & PACA_IRQ_REPLAYING); 109 124 } 125 + 126 + /* 127 + * PACA_IRQ_REPLAYING prevents interrupt handlers from enabling 128 + * MSR[EE] to get PMIs, which can result in more IRQs becoming 129 + * pending. 130 + */ 131 + local_paca->irq_happened |= PACA_IRQ_REPLAYING; 110 132 111 133 ppc_save_regs(&regs); 112 134 regs.softe = IRQS_ENABLED; 113 135 regs.msr |= MSR_EE; 114 136 115 - again: 116 137 /* 117 138 * Force the delivery of pending soft-disabled interrupts on PS3. 118 139 * Any HV call will have this side effect. ··· 168 175 next_interrupt(&regs); 169 176 } 170 177 171 - /* 172 - * Softirq processing can enable and disable interrupts, which can 173 - * result in new irqs becoming pending. Must keep looping until we 174 - * have cleared out all pending interrupts. 175 - */ 176 - if (local_paca->irq_happened & ~PACA_IRQ_HARD_DIS) 177 - goto again; 178 + local_paca->irq_happened &= ~PACA_IRQ_REPLAYING; 179 + } 180 + 181 + __no_kcsan void replay_soft_interrupts(void) 182 + { 183 + irq_enter(); /* See comment in arch_local_irq_restore */ 184 + __replay_soft_interrupts(); 185 + irq_exit(); 178 186 } 179 187 180 188 #if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_KUAP) 181 - static inline void replay_soft_interrupts_irqrestore(void) 189 + static inline __no_kcsan void replay_soft_interrupts_irqrestore(void) 182 190 { 183 191 unsigned long kuap_state = get_kuap(); 184 192 ··· 194 200 if (kuap_state != AMR_KUAP_BLOCKED) 195 201 set_kuap(AMR_KUAP_BLOCKED); 196 202 197 - replay_soft_interrupts(); 203 + __replay_soft_interrupts(); 198 204 199 205 if (kuap_state != AMR_KUAP_BLOCKED) 200 206 set_kuap(kuap_state); 201 207 } 202 208 #else 203 - #define replay_soft_interrupts_irqrestore() replay_soft_interrupts() 209 + #define replay_soft_interrupts_irqrestore() __replay_soft_interrupts() 204 210 #endif 205 211 206 - notrace void arch_local_irq_restore(unsigned long mask) 212 + notrace __no_kcsan void arch_local_irq_restore(unsigned long mask) 207 213 { 208 214 unsigned char irq_happened; 209 215 ··· 213 219 return; 214 220 } 215 221 216 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 217 - WARN_ON_ONCE(in_nmi() || in_hardirq()); 222 + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) { 223 + WARN_ON_ONCE(in_nmi()); 224 + WARN_ON_ONCE(in_hardirq()); 225 + WARN_ON_ONCE(local_paca->irq_happened & PACA_IRQ_REPLAYING); 226 + } 218 227 228 + again: 219 229 /* 220 230 * After the stb, interrupts are unmasked and there are no interrupts 221 231 * pending replay. The restart sequence makes this atomic with ··· 246 248 if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 247 249 WARN_ON_ONCE(!(mfmsr() & MSR_EE)); 248 250 251 + /* 252 + * If we came here from the replay below, we might have a preempt 253 + * pending (due to preempt_enable_no_resched()). Have to check now. 254 + */ 255 + preempt_check_resched(); 256 + 249 257 return; 250 258 251 259 happened: ··· 265 261 irq_soft_mask_set(IRQS_ENABLED); 266 262 local_paca->irq_happened = 0; 267 263 __hard_irq_enable(); 264 + preempt_check_resched(); 268 265 return; 269 266 } 270 267 ··· 301 296 irq_soft_mask_set(IRQS_ALL_DISABLED); 302 297 trace_hardirqs_off(); 303 298 299 + /* 300 + * Now enter interrupt context. The interrupt handlers themselves 301 + * also call irq_enter/exit (which is okay, they can nest). But call 302 + * it here now to hold off softirqs until the below irq_exit(). If 303 + * we allowed replayed handlers to run softirqs, that enables irqs, 304 + * which must replay interrupts, which recurses in here and makes 305 + * things more complicated. The recursion is limited to 2, and it can 306 + * be made to work, but it's complicated. 307 + * 308 + * local_bh_disable can not be used here because interrupts taken in 309 + * idle are not in the right context (RCU, tick, etc) to run softirqs 310 + * so irq_enter must be called. 311 + */ 312 + irq_enter(); 313 + 304 314 replay_soft_interrupts_irqrestore(); 315 + 316 + irq_exit(); 317 + 318 + if (unlikely(local_paca->irq_happened != PACA_IRQ_HARD_DIS)) { 319 + /* 320 + * The softirq processing in irq_exit() may enable interrupts 321 + * temporarily, which can result in MSR[EE] being enabled and 322 + * more irqs becoming pending. Go around again if that happens. 323 + */ 324 + trace_hardirqs_on(); 325 + preempt_enable_no_resched(); 326 + goto again; 327 + } 305 328 306 329 trace_hardirqs_on(); 307 330 irq_soft_mask_set(IRQS_ENABLED); 308 - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 309 - WARN_ON(local_paca->irq_happened != PACA_IRQ_HARD_DIS); 310 331 local_paca->irq_happened = 0; 311 332 __hard_irq_enable(); 312 333 preempt_enable();
+7 -3
arch/powerpc/kernel/mce.c
··· 131 131 if (mce->error_type == MCE_ERROR_TYPE_UE) 132 132 mce->u.ue_error.ignore_event = mce_err->ignore_event; 133 133 134 + /* 135 + * Raise irq work, So that we don't miss to log the error for 136 + * unrecoverable errors. 137 + */ 138 + if (mce->disposition == MCE_DISPOSITION_NOT_RECOVERED) 139 + mce_irq_work_queue(); 140 + 134 141 if (!addr) 135 142 return; 136 143 ··· 240 233 } 241 234 memcpy(&local_paca->mce_info->mce_ue_event_queue[index], 242 235 evt, sizeof(*evt)); 243 - 244 - /* Queue work to process this event later. */ 245 - mce_irq_work_queue(); 246 236 } 247 237 248 238 /*
+19 -12
arch/powerpc/kernel/module_64.c
··· 502 502 static int restore_r2(const char *name, u32 *instruction, struct module *me) 503 503 { 504 504 u32 *prev_insn = instruction - 1; 505 + u32 insn_val = *instruction; 505 506 506 507 if (is_mprofile_ftrace_call(name)) 507 - return 1; 508 + return 0; 508 509 509 510 /* 510 511 * Make sure the branch isn't a sibling call. Sibling calls aren't ··· 513 512 * restore afterwards. 514 513 */ 515 514 if (!instr_is_relative_link_branch(ppc_inst(*prev_insn))) 516 - return 1; 517 - 518 - if (*instruction != PPC_RAW_NOP()) { 519 - pr_err("%s: Expected nop after call, got %08x at %pS\n", 520 - me->name, *instruction, instruction); 521 515 return 0; 516 + 517 + /* 518 + * For livepatch, the restore r2 instruction might have already been 519 + * written previously, if the referenced symbol is in a previously 520 + * unloaded module which is now being loaded again. In that case, skip 521 + * the warning and the instruction write. 522 + */ 523 + if (insn_val == PPC_INST_LD_TOC) 524 + return 0; 525 + 526 + if (insn_val != PPC_RAW_NOP()) { 527 + pr_err("%s: Expected nop after call, got %08x at %pS\n", 528 + me->name, insn_val, instruction); 529 + return -ENOEXEC; 522 530 } 523 531 524 532 /* ld r2,R2_STACK_OFFSET(r1) */ 525 - if (patch_instruction(instruction, ppc_inst(PPC_INST_LD_TOC))) 526 - return 0; 527 - 528 - return 1; 533 + return patch_instruction(instruction, ppc_inst(PPC_INST_LD_TOC)); 529 534 } 530 535 531 536 int apply_relocate_add(Elf64_Shdr *sechdrs, ··· 655 648 strtab + sym->st_name); 656 649 if (!value) 657 650 return -ENOENT; 658 - if (!restore_r2(strtab + sym->st_name, 659 - (u32 *)location + 1, me)) 651 + if (restore_r2(strtab + sym->st_name, 652 + (u32 *)location + 1, me)) 660 653 return -ENOEXEC; 661 654 } else 662 655 value += local_entry_offset(sym);
+12 -5
arch/powerpc/kernel/pci_32.c
··· 62 62 } 63 63 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64); 64 64 65 - #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_CHRP) 65 + #ifdef CONFIG_PPC_PCI_OF_BUS_MAP 66 66 67 67 static u8* pci_to_OF_bus_map; 68 68 static int pci_bus_count; ··· 152 152 } 153 153 #endif 154 154 } 155 + #endif // CONFIG_PPC_PCI_OF_BUS_MAP 155 156 156 157 157 158 #ifdef CONFIG_PPC_PMAC ··· 161 160 */ 162 161 int pci_device_from_OF_node(struct device_node *node, u8 *bus, u8 *devfn) 163 162 { 163 + #ifdef CONFIG_PPC_PCI_OF_BUS_MAP 164 164 struct pci_dev *dev = NULL; 165 + #endif 165 166 const __be32 *reg; 166 167 int size; 167 168 ··· 178 175 *bus = (be32_to_cpup(&reg[0]) >> 16) & 0xff; 179 176 *devfn = (be32_to_cpup(&reg[0]) >> 8) & 0xff; 180 177 178 + #ifndef CONFIG_PPC_PCI_OF_BUS_MAP 179 + return 0; 180 + #else 181 181 /* Ok, here we need some tweak. If we have already renumbered 182 182 * all busses, we can't rely on the OF bus number any more. 183 183 * the pci_to_OF_bus_map is not enough as several PCI busses ··· 198 192 } 199 193 200 194 return -ENODEV; 195 + #endif // CONFIG_PPC_PCI_OF_BUS_MAP 201 196 } 202 197 EXPORT_SYMBOL(pci_device_from_OF_node); 203 198 #endif 204 199 205 - #ifdef CONFIG_PPC_CHRP 200 + #ifdef CONFIG_PPC_PCI_OF_BUS_MAP 206 201 /* We create the "pci-OF-bus-map" property now so it appears in the 207 202 * /proc device tree 208 203 */ ··· 228 221 of_node_put(dn); 229 222 } 230 223 } 231 - #endif 232 - 233 - #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_CHRP) */ 224 + #endif // CONFIG_PPC_PCI_OF_BUS_MAP 234 225 235 226 void pcibios_setup_phb_io_space(struct pci_controller *hose) 236 227 { ··· 278 273 } 279 274 280 275 #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_CHRP) 276 + #ifdef CONFIG_PPC_PCI_OF_BUS_MAP 281 277 pci_bus_count = next_busno; 282 278 283 279 /* OpenFirmware based machines need a map of OF bus ··· 287 281 */ 288 282 if (pci_assign_all_buses) 289 283 pcibios_make_OF_bus_map(); 284 + #endif 290 285 #endif 291 286 292 287 /* Call common code to handle resource allocation */
+12 -2
arch/powerpc/kernel/process.c
··· 1405 1405 for (i = 0; i < NR_INSN_TO_PRINT; i++) { 1406 1406 int instr; 1407 1407 1408 - if (!__kernel_text_address(pc) || 1409 - get_kernel_nofault(instr, (const void *)pc)) { 1408 + if (get_kernel_nofault(instr, (const void *)pc)) { 1410 1409 pr_cont("XXXXXXXX "); 1411 1410 } else { 1412 1411 if (nip == pc) ··· 2117 2118 unsigned long stack_page; 2118 2119 unsigned long cpu = task_cpu(p); 2119 2120 2121 + if (!hardirq_ctx[cpu] || !softirq_ctx[cpu]) 2122 + return 0; 2123 + 2120 2124 stack_page = (unsigned long)hardirq_ctx[cpu]; 2121 2125 if (sp >= stack_page && sp <= stack_page + THREAD_SIZE - nbytes) 2122 2126 return 1; ··· 2140 2138 2141 2139 if (!paca_ptrs) 2142 2140 return 0; 2141 + 2142 + if (!paca_ptrs[cpu]->emergency_sp) 2143 + return 0; 2144 + 2145 + # ifdef CONFIG_PPC_BOOK3S_64 2146 + if (!paca_ptrs[cpu]->nmi_emergency_sp || !paca_ptrs[cpu]->mc_emergency_sp) 2147 + return 0; 2148 + #endif 2143 2149 2144 2150 stack_page = (unsigned long)paca_ptrs[cpu]->emergency_sp - THREAD_SIZE; 2145 2151 if (sp >= stack_page && sp <= stack_page + THREAD_SIZE - nbytes)
+7 -9
arch/powerpc/kernel/prom.c
··· 56 56 #include <asm/drmem.h> 57 57 #include <asm/ultravisor.h> 58 58 #include <asm/prom.h> 59 + #include <asm/plpks.h> 59 60 60 61 #include <mm/mmu_decl.h> 61 62 ··· 371 370 be32_to_cpu(intserv[found_thread])); 372 371 boot_cpuid = found; 373 372 374 - // Pass the boot CPU's hard CPU id back to our caller 375 - *((u32 *)data) = be32_to_cpu(intserv[found_thread]); 373 + if (IS_ENABLED(CONFIG_PPC64)) 374 + boot_cpu_hwid = be32_to_cpu(intserv[found_thread]); 376 375 377 376 /* 378 377 * PAPR defines "logical" PVR values for cpus that ··· 756 755 757 756 void __init early_init_devtree(void *params) 758 757 { 759 - u32 boot_cpu_hwid; 760 758 phys_addr_t limit; 761 759 762 760 DBG(" -> early_init_devtree(%px)\n", params); ··· 851 851 /* Retrieve CPU related informations from the flat tree 852 852 * (altivec support, boot CPU ID, ...) 853 853 */ 854 - of_scan_flat_dt(early_init_dt_scan_cpus, &boot_cpu_hwid); 854 + of_scan_flat_dt(early_init_dt_scan_cpus, NULL); 855 855 if (boot_cpuid < 0) { 856 856 printk("Failed to identify boot CPU !\n"); 857 857 BUG(); ··· 867 867 #endif 868 868 869 869 mmu_early_init_devtree(); 870 - 871 - // NB. paca is not installed until later in early_setup() 872 - allocate_paca_ptrs(); 873 - allocate_paca(boot_cpuid); 874 - set_hard_smp_processor_id(boot_cpuid, boot_cpu_hwid); 875 870 876 871 #ifdef CONFIG_PPC_POWERNV 877 872 /* Scan and build the list of machine check recoverable ranges */ ··· 887 892 if (of_flat_dt_is_compatible(of_get_flat_dt_root(), "sony,ps3")) 888 893 powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE; 889 894 #endif 895 + 896 + /* If kexec left a PLPKS password in the DT, get it and clear it */ 897 + plpks_early_init_devtree(); 890 898 891 899 tm_init(); 892 900
+12 -12
arch/powerpc/kernel/rtas-proc.c
··· 287 287 288 288 rtc_time64_to_tm(nowtime, &tm); 289 289 290 - error = rtas_call(rtas_token("set-time-for-power-on"), 7, 1, NULL, 291 - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 292 - tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */); 290 + error = rtas_call(rtas_function_token(RTAS_FN_SET_TIME_FOR_POWER_ON), 7, 1, NULL, 291 + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 292 + tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */); 293 293 if (error) 294 294 printk(KERN_WARNING "error: setting poweron time returned: %s\n", 295 295 ppc_rtas_process_error(error)); ··· 350 350 return error; 351 351 352 352 rtc_time64_to_tm(nowtime, &tm); 353 - error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL, 354 - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 355 - tm.tm_hour, tm.tm_min, tm.tm_sec, 0); 353 + error = rtas_call(rtas_function_token(RTAS_FN_SET_TIME_OF_DAY), 7, 1, NULL, 354 + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 355 + tm.tm_hour, tm.tm_min, tm.tm_sec, 0); 356 356 if (error) 357 357 printk(KERN_WARNING "error: setting the clock returned: %s\n", 358 358 ppc_rtas_process_error(error)); ··· 362 362 static int ppc_rtas_clock_show(struct seq_file *m, void *v) 363 363 { 364 364 int ret[8]; 365 - int error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); 365 + int error = rtas_call(rtas_function_token(RTAS_FN_GET_TIME_OF_DAY), 0, 8, ret); 366 366 367 367 if (error) { 368 368 printk(KERN_WARNING "error: reading the clock returned: %s\n", ··· 385 385 { 386 386 int i,j; 387 387 int state, error; 388 - int get_sensor_state = rtas_token("get-sensor-state"); 388 + int get_sensor_state = rtas_function_token(RTAS_FN_GET_SENSOR_STATE); 389 389 390 390 seq_printf(m, "RTAS (RunTime Abstraction Services) Sensor Information\n"); 391 391 seq_printf(m, "Sensor\t\tValue\t\tCondition\tLocation\n"); ··· 708 708 return error; 709 709 710 710 rtas_tone_frequency = freq; /* save it for later */ 711 - error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL, 712 - TONE_FREQUENCY, 0, freq); 711 + error = rtas_call(rtas_function_token(RTAS_FN_SET_INDICATOR), 3, 1, NULL, 712 + TONE_FREQUENCY, 0, freq); 713 713 if (error) 714 714 printk(KERN_WARNING "error: setting tone frequency returned: %s\n", 715 715 ppc_rtas_process_error(error)); ··· 736 736 volume = 100; 737 737 738 738 rtas_tone_volume = volume; /* save it for later */ 739 - error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL, 740 - TONE_VOLUME, 0, volume); 739 + error = rtas_call(rtas_function_token(RTAS_FN_SET_INDICATOR), 3, 1, NULL, 740 + TONE_VOLUME, 0, volume); 741 741 if (error) 742 742 printk(KERN_WARNING "error: setting tone volume returned: %s\n", 743 743 ppc_rtas_process_error(error));
+3 -3
arch/powerpc/kernel/rtas-rtc.c
··· 21 21 22 22 max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; 23 23 do { 24 - error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); 24 + error = rtas_call(rtas_function_token(RTAS_FN_GET_TIME_OF_DAY), 0, 8, ret); 25 25 26 26 wait_time = rtas_busy_delay_time(error); 27 27 if (wait_time) { ··· 53 53 54 54 max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; 55 55 do { 56 - error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); 56 + error = rtas_call(rtas_function_token(RTAS_FN_GET_TIME_OF_DAY), 0, 8, ret); 57 57 58 58 wait_time = rtas_busy_delay_time(error); 59 59 if (wait_time) { ··· 90 90 91 91 max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; 92 92 do { 93 - error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL, 93 + error = rtas_call(rtas_function_token(RTAS_FN_SET_TIME_OF_DAY), 7, 1, NULL, 94 94 tm->tm_year + 1900, tm->tm_mon + 1, 95 95 tm->tm_mday, tm->tm_hour, tm->tm_min, 96 96 tm->tm_sec, 0);
+834 -226
arch/powerpc/kernel/rtas.c
··· 9 9 10 10 #define pr_fmt(fmt) "rtas: " fmt 11 11 12 + #include <linux/bsearch.h> 12 13 #include <linux/capability.h> 13 14 #include <linux/delay.h> 14 15 #include <linux/export.h> 15 16 #include <linux/init.h> 17 + #include <linux/kconfig.h> 16 18 #include <linux/kernel.h> 17 19 #include <linux/memblock.h> 18 20 #include <linux/of.h> ··· 28 26 #include <linux/syscalls.h> 29 27 #include <linux/types.h> 30 28 #include <linux/uaccess.h> 29 + #include <linux/xarray.h> 31 30 32 31 #include <asm/delay.h> 33 32 #include <asm/firmware.h> ··· 36 33 #include <asm/machdep.h> 37 34 #include <asm/mmu.h> 38 35 #include <asm/page.h> 36 + #include <asm/rtas-work-area.h> 39 37 #include <asm/rtas.h> 40 38 #include <asm/time.h> 39 + #include <asm/trace.h> 41 40 #include <asm/udbg.h> 41 + 42 + struct rtas_filter { 43 + /* Indexes into the args buffer, -1 if not used */ 44 + const int buf_idx1; 45 + const int size_idx1; 46 + const int buf_idx2; 47 + const int size_idx2; 48 + /* 49 + * Assumed buffer size per the spec if the function does not 50 + * have a size parameter, e.g. ibm,errinjct. 0 if unused. 51 + */ 52 + const int fixed_size; 53 + }; 54 + 55 + /** 56 + * struct rtas_function - Descriptor for RTAS functions. 57 + * 58 + * @token: Value of @name if it exists under the /rtas node. 59 + * @name: Function name. 60 + * @filter: If non-NULL, invoking this function via the rtas syscall is 61 + * generally allowed, and @filter describes constraints on the 62 + * arguments. See also @banned_for_syscall_on_le. 63 + * @banned_for_syscall_on_le: Set when call via sys_rtas is generally allowed 64 + * but specifically restricted on ppc64le. Such 65 + * functions are believed to have no users on 66 + * ppc64le, and we want to keep it that way. It does 67 + * not make sense for this to be set when @filter 68 + * is false. 69 + */ 70 + struct rtas_function { 71 + s32 token; 72 + const bool banned_for_syscall_on_le:1; 73 + const char * const name; 74 + const struct rtas_filter *filter; 75 + }; 76 + 77 + static struct rtas_function rtas_function_table[] __ro_after_init = { 78 + [RTAS_FNIDX__CHECK_EXCEPTION] = { 79 + .name = "check-exception", 80 + }, 81 + [RTAS_FNIDX__DISPLAY_CHARACTER] = { 82 + .name = "display-character", 83 + .filter = &(const struct rtas_filter) { 84 + .buf_idx1 = -1, .size_idx1 = -1, 85 + .buf_idx2 = -1, .size_idx2 = -1, 86 + }, 87 + }, 88 + [RTAS_FNIDX__EVENT_SCAN] = { 89 + .name = "event-scan", 90 + }, 91 + [RTAS_FNIDX__FREEZE_TIME_BASE] = { 92 + .name = "freeze-time-base", 93 + }, 94 + [RTAS_FNIDX__GET_POWER_LEVEL] = { 95 + .name = "get-power-level", 96 + .filter = &(const struct rtas_filter) { 97 + .buf_idx1 = -1, .size_idx1 = -1, 98 + .buf_idx2 = -1, .size_idx2 = -1, 99 + }, 100 + }, 101 + [RTAS_FNIDX__GET_SENSOR_STATE] = { 102 + .name = "get-sensor-state", 103 + .filter = &(const struct rtas_filter) { 104 + .buf_idx1 = -1, .size_idx1 = -1, 105 + .buf_idx2 = -1, .size_idx2 = -1, 106 + }, 107 + }, 108 + [RTAS_FNIDX__GET_TERM_CHAR] = { 109 + .name = "get-term-char", 110 + }, 111 + [RTAS_FNIDX__GET_TIME_OF_DAY] = { 112 + .name = "get-time-of-day", 113 + .filter = &(const struct rtas_filter) { 114 + .buf_idx1 = -1, .size_idx1 = -1, 115 + .buf_idx2 = -1, .size_idx2 = -1, 116 + }, 117 + }, 118 + [RTAS_FNIDX__IBM_ACTIVATE_FIRMWARE] = { 119 + .name = "ibm,activate-firmware", 120 + .filter = &(const struct rtas_filter) { 121 + .buf_idx1 = -1, .size_idx1 = -1, 122 + .buf_idx2 = -1, .size_idx2 = -1, 123 + }, 124 + }, 125 + [RTAS_FNIDX__IBM_CBE_START_PTCAL] = { 126 + .name = "ibm,cbe-start-ptcal", 127 + }, 128 + [RTAS_FNIDX__IBM_CBE_STOP_PTCAL] = { 129 + .name = "ibm,cbe-stop-ptcal", 130 + }, 131 + [RTAS_FNIDX__IBM_CHANGE_MSI] = { 132 + .name = "ibm,change-msi", 133 + }, 134 + [RTAS_FNIDX__IBM_CLOSE_ERRINJCT] = { 135 + .name = "ibm,close-errinjct", 136 + .filter = &(const struct rtas_filter) { 137 + .buf_idx1 = -1, .size_idx1 = -1, 138 + .buf_idx2 = -1, .size_idx2 = -1, 139 + }, 140 + }, 141 + [RTAS_FNIDX__IBM_CONFIGURE_BRIDGE] = { 142 + .name = "ibm,configure-bridge", 143 + }, 144 + [RTAS_FNIDX__IBM_CONFIGURE_CONNECTOR] = { 145 + .name = "ibm,configure-connector", 146 + .filter = &(const struct rtas_filter) { 147 + .buf_idx1 = 0, .size_idx1 = -1, 148 + .buf_idx2 = 1, .size_idx2 = -1, 149 + .fixed_size = 4096, 150 + }, 151 + }, 152 + [RTAS_FNIDX__IBM_CONFIGURE_KERNEL_DUMP] = { 153 + .name = "ibm,configure-kernel-dump", 154 + }, 155 + [RTAS_FNIDX__IBM_CONFIGURE_PE] = { 156 + .name = "ibm,configure-pe", 157 + }, 158 + [RTAS_FNIDX__IBM_CREATE_PE_DMA_WINDOW] = { 159 + .name = "ibm,create-pe-dma-window", 160 + }, 161 + [RTAS_FNIDX__IBM_DISPLAY_MESSAGE] = { 162 + .name = "ibm,display-message", 163 + .filter = &(const struct rtas_filter) { 164 + .buf_idx1 = 0, .size_idx1 = -1, 165 + .buf_idx2 = -1, .size_idx2 = -1, 166 + }, 167 + }, 168 + [RTAS_FNIDX__IBM_ERRINJCT] = { 169 + .name = "ibm,errinjct", 170 + .filter = &(const struct rtas_filter) { 171 + .buf_idx1 = 2, .size_idx1 = -1, 172 + .buf_idx2 = -1, .size_idx2 = -1, 173 + .fixed_size = 1024, 174 + }, 175 + }, 176 + [RTAS_FNIDX__IBM_EXTI2C] = { 177 + .name = "ibm,exti2c", 178 + }, 179 + [RTAS_FNIDX__IBM_GET_CONFIG_ADDR_INFO] = { 180 + .name = "ibm,get-config-addr-info", 181 + }, 182 + [RTAS_FNIDX__IBM_GET_CONFIG_ADDR_INFO2] = { 183 + .name = "ibm,get-config-addr-info2", 184 + .filter = &(const struct rtas_filter) { 185 + .buf_idx1 = -1, .size_idx1 = -1, 186 + .buf_idx2 = -1, .size_idx2 = -1, 187 + }, 188 + }, 189 + [RTAS_FNIDX__IBM_GET_DYNAMIC_SENSOR_STATE] = { 190 + .name = "ibm,get-dynamic-sensor-state", 191 + .filter = &(const struct rtas_filter) { 192 + .buf_idx1 = 1, .size_idx1 = -1, 193 + .buf_idx2 = -1, .size_idx2 = -1, 194 + }, 195 + }, 196 + [RTAS_FNIDX__IBM_GET_INDICES] = { 197 + .name = "ibm,get-indices", 198 + .filter = &(const struct rtas_filter) { 199 + .buf_idx1 = 2, .size_idx1 = 3, 200 + .buf_idx2 = -1, .size_idx2 = -1, 201 + }, 202 + }, 203 + [RTAS_FNIDX__IBM_GET_RIO_TOPOLOGY] = { 204 + .name = "ibm,get-rio-topology", 205 + }, 206 + [RTAS_FNIDX__IBM_GET_SYSTEM_PARAMETER] = { 207 + .name = "ibm,get-system-parameter", 208 + .filter = &(const struct rtas_filter) { 209 + .buf_idx1 = 1, .size_idx1 = 2, 210 + .buf_idx2 = -1, .size_idx2 = -1, 211 + }, 212 + }, 213 + [RTAS_FNIDX__IBM_GET_VPD] = { 214 + .name = "ibm,get-vpd", 215 + .filter = &(const struct rtas_filter) { 216 + .buf_idx1 = 0, .size_idx1 = -1, 217 + .buf_idx2 = 1, .size_idx2 = 2, 218 + }, 219 + }, 220 + [RTAS_FNIDX__IBM_GET_XIVE] = { 221 + .name = "ibm,get-xive", 222 + }, 223 + [RTAS_FNIDX__IBM_INT_OFF] = { 224 + .name = "ibm,int-off", 225 + }, 226 + [RTAS_FNIDX__IBM_INT_ON] = { 227 + .name = "ibm,int-on", 228 + }, 229 + [RTAS_FNIDX__IBM_IO_QUIESCE_ACK] = { 230 + .name = "ibm,io-quiesce-ack", 231 + }, 232 + [RTAS_FNIDX__IBM_LPAR_PERFTOOLS] = { 233 + .name = "ibm,lpar-perftools", 234 + .filter = &(const struct rtas_filter) { 235 + .buf_idx1 = 2, .size_idx1 = 3, 236 + .buf_idx2 = -1, .size_idx2 = -1, 237 + }, 238 + }, 239 + [RTAS_FNIDX__IBM_MANAGE_FLASH_IMAGE] = { 240 + .name = "ibm,manage-flash-image", 241 + }, 242 + [RTAS_FNIDX__IBM_MANAGE_STORAGE_PRESERVATION] = { 243 + .name = "ibm,manage-storage-preservation", 244 + }, 245 + [RTAS_FNIDX__IBM_NMI_INTERLOCK] = { 246 + .name = "ibm,nmi-interlock", 247 + }, 248 + [RTAS_FNIDX__IBM_NMI_REGISTER] = { 249 + .name = "ibm,nmi-register", 250 + }, 251 + [RTAS_FNIDX__IBM_OPEN_ERRINJCT] = { 252 + .name = "ibm,open-errinjct", 253 + .filter = &(const struct rtas_filter) { 254 + .buf_idx1 = -1, .size_idx1 = -1, 255 + .buf_idx2 = -1, .size_idx2 = -1, 256 + }, 257 + }, 258 + [RTAS_FNIDX__IBM_OPEN_SRIOV_ALLOW_UNFREEZE] = { 259 + .name = "ibm,open-sriov-allow-unfreeze", 260 + }, 261 + [RTAS_FNIDX__IBM_OPEN_SRIOV_MAP_PE_NUMBER] = { 262 + .name = "ibm,open-sriov-map-pe-number", 263 + }, 264 + [RTAS_FNIDX__IBM_OS_TERM] = { 265 + .name = "ibm,os-term", 266 + }, 267 + [RTAS_FNIDX__IBM_PARTNER_CONTROL] = { 268 + .name = "ibm,partner-control", 269 + }, 270 + [RTAS_FNIDX__IBM_PHYSICAL_ATTESTATION] = { 271 + .name = "ibm,physical-attestation", 272 + .filter = &(const struct rtas_filter) { 273 + .buf_idx1 = 0, .size_idx1 = 1, 274 + .buf_idx2 = -1, .size_idx2 = -1, 275 + }, 276 + }, 277 + [RTAS_FNIDX__IBM_PLATFORM_DUMP] = { 278 + .name = "ibm,platform-dump", 279 + .filter = &(const struct rtas_filter) { 280 + .buf_idx1 = 4, .size_idx1 = 5, 281 + .buf_idx2 = -1, .size_idx2 = -1, 282 + }, 283 + }, 284 + [RTAS_FNIDX__IBM_POWER_OFF_UPS] = { 285 + .name = "ibm,power-off-ups", 286 + }, 287 + [RTAS_FNIDX__IBM_QUERY_INTERRUPT_SOURCE_NUMBER] = { 288 + .name = "ibm,query-interrupt-source-number", 289 + }, 290 + [RTAS_FNIDX__IBM_QUERY_PE_DMA_WINDOW] = { 291 + .name = "ibm,query-pe-dma-window", 292 + }, 293 + [RTAS_FNIDX__IBM_READ_PCI_CONFIG] = { 294 + .name = "ibm,read-pci-config", 295 + }, 296 + [RTAS_FNIDX__IBM_READ_SLOT_RESET_STATE] = { 297 + .name = "ibm,read-slot-reset-state", 298 + .filter = &(const struct rtas_filter) { 299 + .buf_idx1 = -1, .size_idx1 = -1, 300 + .buf_idx2 = -1, .size_idx2 = -1, 301 + }, 302 + }, 303 + [RTAS_FNIDX__IBM_READ_SLOT_RESET_STATE2] = { 304 + .name = "ibm,read-slot-reset-state2", 305 + }, 306 + [RTAS_FNIDX__IBM_REMOVE_PE_DMA_WINDOW] = { 307 + .name = "ibm,remove-pe-dma-window", 308 + }, 309 + [RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOWS] = { 310 + .name = "ibm,reset-pe-dma-windows", 311 + }, 312 + [RTAS_FNIDX__IBM_SCAN_LOG_DUMP] = { 313 + .name = "ibm,scan-log-dump", 314 + .filter = &(const struct rtas_filter) { 315 + .buf_idx1 = 0, .size_idx1 = 1, 316 + .buf_idx2 = -1, .size_idx2 = -1, 317 + }, 318 + }, 319 + [RTAS_FNIDX__IBM_SET_DYNAMIC_INDICATOR] = { 320 + .name = "ibm,set-dynamic-indicator", 321 + .filter = &(const struct rtas_filter) { 322 + .buf_idx1 = 2, .size_idx1 = -1, 323 + .buf_idx2 = -1, .size_idx2 = -1, 324 + }, 325 + }, 326 + [RTAS_FNIDX__IBM_SET_EEH_OPTION] = { 327 + .name = "ibm,set-eeh-option", 328 + .filter = &(const struct rtas_filter) { 329 + .buf_idx1 = -1, .size_idx1 = -1, 330 + .buf_idx2 = -1, .size_idx2 = -1, 331 + }, 332 + }, 333 + [RTAS_FNIDX__IBM_SET_SLOT_RESET] = { 334 + .name = "ibm,set-slot-reset", 335 + }, 336 + [RTAS_FNIDX__IBM_SET_SYSTEM_PARAMETER] = { 337 + .name = "ibm,set-system-parameter", 338 + .filter = &(const struct rtas_filter) { 339 + .buf_idx1 = 1, .size_idx1 = -1, 340 + .buf_idx2 = -1, .size_idx2 = -1, 341 + }, 342 + }, 343 + [RTAS_FNIDX__IBM_SET_XIVE] = { 344 + .name = "ibm,set-xive", 345 + }, 346 + [RTAS_FNIDX__IBM_SLOT_ERROR_DETAIL] = { 347 + .name = "ibm,slot-error-detail", 348 + }, 349 + [RTAS_FNIDX__IBM_SUSPEND_ME] = { 350 + .name = "ibm,suspend-me", 351 + .banned_for_syscall_on_le = true, 352 + .filter = &(const struct rtas_filter) { 353 + .buf_idx1 = -1, .size_idx1 = -1, 354 + .buf_idx2 = -1, .size_idx2 = -1, 355 + }, 356 + }, 357 + [RTAS_FNIDX__IBM_TUNE_DMA_PARMS] = { 358 + .name = "ibm,tune-dma-parms", 359 + }, 360 + [RTAS_FNIDX__IBM_UPDATE_FLASH_64_AND_REBOOT] = { 361 + .name = "ibm,update-flash-64-and-reboot", 362 + }, 363 + [RTAS_FNIDX__IBM_UPDATE_NODES] = { 364 + .name = "ibm,update-nodes", 365 + .banned_for_syscall_on_le = true, 366 + .filter = &(const struct rtas_filter) { 367 + .buf_idx1 = 0, .size_idx1 = -1, 368 + .buf_idx2 = -1, .size_idx2 = -1, 369 + .fixed_size = 4096, 370 + }, 371 + }, 372 + [RTAS_FNIDX__IBM_UPDATE_PROPERTIES] = { 373 + .name = "ibm,update-properties", 374 + .banned_for_syscall_on_le = true, 375 + .filter = &(const struct rtas_filter) { 376 + .buf_idx1 = 0, .size_idx1 = -1, 377 + .buf_idx2 = -1, .size_idx2 = -1, 378 + .fixed_size = 4096, 379 + }, 380 + }, 381 + [RTAS_FNIDX__IBM_VALIDATE_FLASH_IMAGE] = { 382 + .name = "ibm,validate-flash-image", 383 + }, 384 + [RTAS_FNIDX__IBM_WRITE_PCI_CONFIG] = { 385 + .name = "ibm,write-pci-config", 386 + }, 387 + [RTAS_FNIDX__NVRAM_FETCH] = { 388 + .name = "nvram-fetch", 389 + }, 390 + [RTAS_FNIDX__NVRAM_STORE] = { 391 + .name = "nvram-store", 392 + }, 393 + [RTAS_FNIDX__POWER_OFF] = { 394 + .name = "power-off", 395 + }, 396 + [RTAS_FNIDX__PUT_TERM_CHAR] = { 397 + .name = "put-term-char", 398 + }, 399 + [RTAS_FNIDX__QUERY_CPU_STOPPED_STATE] = { 400 + .name = "query-cpu-stopped-state", 401 + }, 402 + [RTAS_FNIDX__READ_PCI_CONFIG] = { 403 + .name = "read-pci-config", 404 + }, 405 + [RTAS_FNIDX__RTAS_LAST_ERROR] = { 406 + .name = "rtas-last-error", 407 + }, 408 + [RTAS_FNIDX__SET_INDICATOR] = { 409 + .name = "set-indicator", 410 + .filter = &(const struct rtas_filter) { 411 + .buf_idx1 = -1, .size_idx1 = -1, 412 + .buf_idx2 = -1, .size_idx2 = -1, 413 + }, 414 + }, 415 + [RTAS_FNIDX__SET_POWER_LEVEL] = { 416 + .name = "set-power-level", 417 + .filter = &(const struct rtas_filter) { 418 + .buf_idx1 = -1, .size_idx1 = -1, 419 + .buf_idx2 = -1, .size_idx2 = -1, 420 + }, 421 + }, 422 + [RTAS_FNIDX__SET_TIME_FOR_POWER_ON] = { 423 + .name = "set-time-for-power-on", 424 + .filter = &(const struct rtas_filter) { 425 + .buf_idx1 = -1, .size_idx1 = -1, 426 + .buf_idx2 = -1, .size_idx2 = -1, 427 + }, 428 + }, 429 + [RTAS_FNIDX__SET_TIME_OF_DAY] = { 430 + .name = "set-time-of-day", 431 + .filter = &(const struct rtas_filter) { 432 + .buf_idx1 = -1, .size_idx1 = -1, 433 + .buf_idx2 = -1, .size_idx2 = -1, 434 + }, 435 + }, 436 + [RTAS_FNIDX__START_CPU] = { 437 + .name = "start-cpu", 438 + }, 439 + [RTAS_FNIDX__STOP_SELF] = { 440 + .name = "stop-self", 441 + }, 442 + [RTAS_FNIDX__SYSTEM_REBOOT] = { 443 + .name = "system-reboot", 444 + }, 445 + [RTAS_FNIDX__THAW_TIME_BASE] = { 446 + .name = "thaw-time-base", 447 + }, 448 + [RTAS_FNIDX__WRITE_PCI_CONFIG] = { 449 + .name = "write-pci-config", 450 + }, 451 + }; 452 + 453 + /** 454 + * rtas_function_token() - RTAS function token lookup. 455 + * @handle: Function handle, e.g. RTAS_FN_EVENT_SCAN. 456 + * 457 + * Context: Any context. 458 + * Return: the token value for the function if implemented by this platform, 459 + * otherwise RTAS_UNKNOWN_SERVICE. 460 + */ 461 + s32 rtas_function_token(const rtas_fn_handle_t handle) 462 + { 463 + const size_t index = handle.index; 464 + const bool out_of_bounds = index >= ARRAY_SIZE(rtas_function_table); 465 + 466 + if (WARN_ONCE(out_of_bounds, "invalid function index %zu", index)) 467 + return RTAS_UNKNOWN_SERVICE; 468 + /* 469 + * Various drivers attempt token lookups on non-RTAS 470 + * platforms. 471 + */ 472 + if (!rtas.dev) 473 + return RTAS_UNKNOWN_SERVICE; 474 + 475 + return rtas_function_table[index].token; 476 + } 477 + EXPORT_SYMBOL_GPL(rtas_function_token); 478 + 479 + static int rtas_function_cmp(const void *a, const void *b) 480 + { 481 + const struct rtas_function *f1 = a; 482 + const struct rtas_function *f2 = b; 483 + 484 + return strcmp(f1->name, f2->name); 485 + } 486 + 487 + /* 488 + * Boot-time initialization of the function table needs the lookup to 489 + * return a non-const-qualified object. Use rtas_name_to_function() 490 + * in all other contexts. 491 + */ 492 + static struct rtas_function *__rtas_name_to_function(const char *name) 493 + { 494 + const struct rtas_function key = { 495 + .name = name, 496 + }; 497 + struct rtas_function *found; 498 + 499 + found = bsearch(&key, rtas_function_table, ARRAY_SIZE(rtas_function_table), 500 + sizeof(rtas_function_table[0]), rtas_function_cmp); 501 + 502 + return found; 503 + } 504 + 505 + static const struct rtas_function *rtas_name_to_function(const char *name) 506 + { 507 + return __rtas_name_to_function(name); 508 + } 509 + 510 + static DEFINE_XARRAY(rtas_token_to_function_xarray); 511 + 512 + static int __init rtas_token_to_function_xarray_init(void) 513 + { 514 + int err = 0; 515 + 516 + for (size_t i = 0; i < ARRAY_SIZE(rtas_function_table); ++i) { 517 + const struct rtas_function *func = &rtas_function_table[i]; 518 + const s32 token = func->token; 519 + 520 + if (token == RTAS_UNKNOWN_SERVICE) 521 + continue; 522 + 523 + err = xa_err(xa_store(&rtas_token_to_function_xarray, 524 + token, (void *)func, GFP_KERNEL)); 525 + if (err) 526 + break; 527 + } 528 + 529 + return err; 530 + } 531 + arch_initcall(rtas_token_to_function_xarray_init); 532 + 533 + static const struct rtas_function *rtas_token_to_function(s32 token) 534 + { 535 + const struct rtas_function *func; 536 + 537 + if (WARN_ONCE(token < 0, "invalid token %d", token)) 538 + return NULL; 539 + 540 + func = xa_load(&rtas_token_to_function_xarray, token); 541 + 542 + if (WARN_ONCE(!func, "unexpected failed lookup for token %d", token)) 543 + return NULL; 544 + 545 + return func; 546 + } 42 547 43 548 /* This is here deliberately so it's only used in this file */ 44 549 void enter_rtas(unsigned long); 45 550 46 - static inline void do_enter_rtas(unsigned long args) 551 + static void __do_enter_rtas(struct rtas_args *args) 47 552 { 48 - unsigned long msr; 553 + enter_rtas(__pa(args)); 554 + srr_regs_clobbered(); /* rtas uses SRRs, invalidate */ 555 + } 49 556 557 + static void __do_enter_rtas_trace(struct rtas_args *args) 558 + { 559 + const char *name = NULL; 560 + /* 561 + * If the tracepoints that consume the function name aren't 562 + * active, avoid the lookup. 563 + */ 564 + if ((trace_rtas_input_enabled() || trace_rtas_output_enabled())) { 565 + const s32 token = be32_to_cpu(args->token); 566 + const struct rtas_function *func = rtas_token_to_function(token); 567 + 568 + name = func->name; 569 + } 570 + 571 + trace_rtas_input(args, name); 572 + trace_rtas_ll_entry(args); 573 + 574 + __do_enter_rtas(args); 575 + 576 + trace_rtas_ll_exit(args); 577 + trace_rtas_output(args, name); 578 + } 579 + 580 + static void do_enter_rtas(struct rtas_args *args) 581 + { 582 + const unsigned long msr = mfmsr(); 583 + /* 584 + * Situations where we want to skip any active tracepoints for 585 + * safety reasons: 586 + * 587 + * 1. The last code executed on an offline CPU as it stops, 588 + * i.e. we're about to call stop-self. The tracepoints' 589 + * function name lookup uses xarray, which uses RCU, which 590 + * isn't valid to call on an offline CPU. Any events 591 + * emitted on an offline CPU will be discarded anyway. 592 + * 593 + * 2. In real mode, as when invoking ibm,nmi-interlock from 594 + * the pseries MCE handler. We cannot count on trace 595 + * buffers or the entries in rtas_token_to_function_xarray 596 + * to be contained in the RMO. 597 + */ 598 + const unsigned long mask = MSR_IR | MSR_DR; 599 + const bool can_trace = likely(cpu_online(raw_smp_processor_id()) && 600 + (msr & mask) == mask); 50 601 /* 51 602 * Make sure MSR[RI] is currently enabled as it will be forced later 52 603 * in enter_rtas. 53 604 */ 54 - msr = mfmsr(); 55 605 BUG_ON(!(msr & MSR_RI)); 56 606 57 607 BUG_ON(!irqs_disabled()); 58 608 59 609 hard_irq_disable(); /* Ensure MSR[EE] is disabled on PPC64 */ 60 610 61 - enter_rtas(args); 62 - 63 - srr_regs_clobbered(); /* rtas uses SRRs, invalidate */ 611 + if (can_trace) 612 + __do_enter_rtas_trace(args); 613 + else 614 + __do_enter_rtas(args); 64 615 } 65 616 66 - struct rtas_t rtas = { 67 - .lock = __ARCH_SPIN_LOCK_UNLOCKED 68 - }; 69 - EXPORT_SYMBOL(rtas); 617 + struct rtas_t rtas; 618 + 619 + /* 620 + * Nearly all RTAS calls need to be serialized. All uses of the 621 + * default rtas_args block must hold rtas_lock. 622 + * 623 + * Exceptions to the RTAS serialization requirement (e.g. stop-self) 624 + * must use a separate rtas_args structure. 625 + */ 626 + static DEFINE_RAW_SPINLOCK(rtas_lock); 627 + static struct rtas_args rtas_args; 70 628 71 629 DEFINE_SPINLOCK(rtas_data_buf_lock); 72 - EXPORT_SYMBOL(rtas_data_buf_lock); 630 + EXPORT_SYMBOL_GPL(rtas_data_buf_lock); 73 631 74 - char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; 75 - EXPORT_SYMBOL(rtas_data_buf); 632 + char rtas_data_buf[RTAS_DATA_BUF_SIZE] __aligned(SZ_4K); 633 + EXPORT_SYMBOL_GPL(rtas_data_buf); 76 634 77 635 unsigned long rtas_rmo_buf; 78 636 ··· 642 78 * This is done like this so rtas_flash can be a module. 643 79 */ 644 80 void (*rtas_flash_term_hook)(int); 645 - EXPORT_SYMBOL(rtas_flash_term_hook); 646 - 647 - /* RTAS use home made raw locking instead of spin_lock_irqsave 648 - * because those can be called from within really nasty contexts 649 - * such as having the timebase stopped which would lockup with 650 - * normal locks and spinlock debugging enabled 651 - */ 652 - static unsigned long lock_rtas(void) 653 - { 654 - unsigned long flags; 655 - 656 - local_irq_save(flags); 657 - preempt_disable(); 658 - arch_spin_lock(&rtas.lock); 659 - return flags; 660 - } 661 - 662 - static void unlock_rtas(unsigned long flags) 663 - { 664 - arch_spin_unlock(&rtas.lock); 665 - local_irq_restore(flags); 666 - preempt_enable(); 667 - } 81 + EXPORT_SYMBOL_GPL(rtas_flash_term_hook); 668 82 669 83 /* 670 84 * call_rtas_display_status and call_rtas_display_status_delay ··· 651 109 */ 652 110 static void call_rtas_display_status(unsigned char c) 653 111 { 654 - unsigned long s; 112 + unsigned long flags; 655 113 656 114 if (!rtas.base) 657 115 return; 658 116 659 - s = lock_rtas(); 660 - rtas_call_unlocked(&rtas.args, 10, 1, 1, NULL, c); 661 - unlock_rtas(s); 117 + raw_spin_lock_irqsave(&rtas_lock, flags); 118 + rtas_call_unlocked(&rtas_args, 10, 1, 1, NULL, c); 119 + raw_spin_unlock_irqrestore(&rtas_lock, flags); 662 120 } 663 121 664 122 static void call_rtas_display_status_delay(char c) ··· 782 240 "ibm,display-truncation-length", NULL); 783 241 of_node_put(root); 784 242 } 785 - display_character = rtas_token("display-character"); 786 - set_indicator = rtas_token("set-indicator"); 243 + display_character = rtas_function_token(RTAS_FN_DISPLAY_CHARACTER); 244 + set_indicator = rtas_function_token(RTAS_FN_SET_INDICATOR); 787 245 } 788 246 789 247 if (display_character == RTAS_UNKNOWN_SERVICE) { ··· 868 326 869 327 spin_unlock(&progress_lock); 870 328 } 871 - EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */ 329 + EXPORT_SYMBOL_GPL(rtas_progress); /* needed by rtas_flash module */ 872 330 873 331 int rtas_token(const char *service) 874 332 { 333 + const struct rtas_function *func; 875 334 const __be32 *tokp; 335 + 876 336 if (rtas.dev == NULL) 877 337 return RTAS_UNKNOWN_SERVICE; 338 + 339 + func = rtas_name_to_function(service); 340 + if (func) 341 + return func->token; 342 + /* 343 + * The caller is looking up a name that is not known to be an 344 + * RTAS function. Either it's a function that needs to be 345 + * added to the table, or they're misusing rtas_token() to 346 + * access non-function properties of the /rtas node. Warn and 347 + * fall back to the legacy behavior. 348 + */ 349 + WARN_ONCE(1, "unknown function `%s`, should it be added to rtas_function_table?\n", 350 + service); 351 + 878 352 tokp = of_get_property(rtas.dev, service, NULL); 879 353 return tokp ? be32_to_cpu(*tokp) : RTAS_UNKNOWN_SERVICE; 880 354 } 881 - EXPORT_SYMBOL(rtas_token); 355 + EXPORT_SYMBOL_GPL(rtas_token); 882 356 883 357 int rtas_service_present(const char *service) 884 358 { 885 359 return rtas_token(service) != RTAS_UNKNOWN_SERVICE; 886 360 } 887 - EXPORT_SYMBOL(rtas_service_present); 888 361 889 362 #ifdef CONFIG_RTAS_ERROR_LOGGING 890 363 ··· 914 357 { 915 358 return rtas_error_log_max; 916 359 } 917 - EXPORT_SYMBOL(rtas_get_error_log_max); 918 360 919 361 static void __init init_error_log_max(void) 920 362 { ··· 937 381 938 382 939 383 static char rtas_err_buf[RTAS_ERROR_LOG_MAX]; 940 - static int rtas_last_error_token; 941 384 942 385 /** Return a copy of the detailed error text associated with the 943 386 * most recent failed call to rtas. Because the error text 944 387 * might go stale if there are any other intervening rtas calls, 945 388 * this routine must be called atomically with whatever produced 946 - * the error (i.e. with rtas.lock still held from the previous call). 389 + * the error (i.e. with rtas_lock still held from the previous call). 947 390 */ 948 391 static char *__fetch_rtas_last_error(char *altbuf) 949 392 { 393 + const s32 token = rtas_function_token(RTAS_FN_RTAS_LAST_ERROR); 950 394 struct rtas_args err_args, save_args; 951 395 u32 bufsz; 952 396 char *buf = NULL; 953 397 954 - if (rtas_last_error_token == -1) 398 + if (token == -1) 955 399 return NULL; 956 400 957 401 bufsz = rtas_get_error_log_max(); 958 402 959 - err_args.token = cpu_to_be32(rtas_last_error_token); 403 + err_args.token = cpu_to_be32(token); 960 404 err_args.nargs = cpu_to_be32(2); 961 405 err_args.nret = cpu_to_be32(1); 962 406 err_args.args[0] = cpu_to_be32(__pa(rtas_err_buf)); 963 407 err_args.args[1] = cpu_to_be32(bufsz); 964 408 err_args.args[2] = 0; 965 409 966 - save_args = rtas.args; 967 - rtas.args = err_args; 410 + save_args = rtas_args; 411 + rtas_args = err_args; 968 412 969 - do_enter_rtas(__pa(&rtas.args)); 413 + do_enter_rtas(&rtas_args); 970 414 971 - err_args = rtas.args; 972 - rtas.args = save_args; 415 + err_args = rtas_args; 416 + rtas_args = save_args; 973 417 974 418 /* Log the error in the unlikely case that there was one. */ 975 419 if (unlikely(err_args.args[2] == 0)) { ··· 1013 457 for (i = 0; i < nret; ++i) 1014 458 args->rets[i] = 0; 1015 459 1016 - do_enter_rtas(__pa(args)); 460 + do_enter_rtas(args); 1017 461 } 1018 462 1019 463 void rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret, ...) ··· 1025 469 va_end(list); 1026 470 } 1027 471 1028 - static int ibm_open_errinjct_token; 1029 - static int ibm_errinjct_token; 472 + static bool token_is_restricted_errinjct(s32 token) 473 + { 474 + return token == rtas_function_token(RTAS_FN_IBM_OPEN_ERRINJCT) || 475 + token == rtas_function_token(RTAS_FN_IBM_ERRINJCT); 476 + } 1030 477 1031 478 /** 1032 479 * rtas_call() - Invoke an RTAS firmware function. ··· 1040 481 * @....: List of @nargs input parameters. 1041 482 * 1042 483 * Invokes the RTAS function indicated by @token, which the caller 1043 - * should obtain via rtas_token(). 484 + * should obtain via rtas_function_token(). 1044 485 * 1045 486 * The @nargs and @nret arguments must match the number of input and 1046 487 * output parameters specified for the RTAS function. ··· 1093 534 { 1094 535 va_list list; 1095 536 int i; 1096 - unsigned long s; 1097 - struct rtas_args *rtas_args; 537 + unsigned long flags; 538 + struct rtas_args *args; 1098 539 char *buff_copy = NULL; 1099 540 int ret; 1100 541 1101 542 if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) 1102 543 return -1; 1103 544 1104 - if (token == ibm_open_errinjct_token || token == ibm_errinjct_token) { 545 + if (token_is_restricted_errinjct(token)) { 1105 546 /* 1106 547 * It would be nicer to not discard the error value 1107 548 * from security_locked_down(), but callers expect an ··· 1116 557 return -1; 1117 558 } 1118 559 1119 - s = lock_rtas(); 1120 - 560 + raw_spin_lock_irqsave(&rtas_lock, flags); 1121 561 /* We use the global rtas args buffer */ 1122 - rtas_args = &rtas.args; 562 + args = &rtas_args; 1123 563 1124 564 va_start(list, outputs); 1125 - va_rtas_call_unlocked(rtas_args, token, nargs, nret, list); 565 + va_rtas_call_unlocked(args, token, nargs, nret, list); 1126 566 va_end(list); 1127 567 1128 568 /* A -1 return code indicates that the last command couldn't 1129 569 be completed due to a hardware error. */ 1130 - if (be32_to_cpu(rtas_args->rets[0]) == -1) 570 + if (be32_to_cpu(args->rets[0]) == -1) 1131 571 buff_copy = __fetch_rtas_last_error(NULL); 1132 572 1133 573 if (nret > 1 && outputs != NULL) 1134 574 for (i = 0; i < nret-1; ++i) 1135 - outputs[i] = be32_to_cpu(rtas_args->rets[i+1]); 1136 - ret = (nret > 0)? be32_to_cpu(rtas_args->rets[0]): 0; 575 + outputs[i] = be32_to_cpu(args->rets[i + 1]); 576 + ret = (nret > 0) ? be32_to_cpu(args->rets[0]) : 0; 1137 577 1138 - unlock_rtas(s); 578 + raw_spin_unlock_irqrestore(&rtas_lock, flags); 1139 579 1140 580 if (buff_copy) { 1141 581 log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0); ··· 1143 585 } 1144 586 return ret; 1145 587 } 1146 - EXPORT_SYMBOL(rtas_call); 588 + EXPORT_SYMBOL_GPL(rtas_call); 1147 589 1148 590 /** 1149 591 * rtas_busy_delay_time() - From an RTAS status value, calculate the ··· 1181 623 1182 624 return ms; 1183 625 } 1184 - EXPORT_SYMBOL(rtas_busy_delay_time); 626 + 627 + /* 628 + * Early boot fallback for rtas_busy_delay(). 629 + */ 630 + static bool __init rtas_busy_delay_early(int status) 631 + { 632 + static size_t successive_ext_delays __initdata; 633 + bool retry; 634 + 635 + switch (status) { 636 + case RTAS_EXTENDED_DELAY_MIN...RTAS_EXTENDED_DELAY_MAX: 637 + /* 638 + * In the unlikely case that we receive an extended 639 + * delay status in early boot, the OS is probably not 640 + * the cause, and there's nothing we can do to clear 641 + * the condition. Best we can do is delay for a bit 642 + * and hope it's transient. Lie to the caller if it 643 + * seems like we're stuck in a retry loop. 644 + */ 645 + mdelay(1); 646 + retry = true; 647 + successive_ext_delays += 1; 648 + if (successive_ext_delays > 1000) { 649 + pr_err("too many extended delays, giving up\n"); 650 + dump_stack(); 651 + retry = false; 652 + successive_ext_delays = 0; 653 + } 654 + break; 655 + case RTAS_BUSY: 656 + retry = true; 657 + successive_ext_delays = 0; 658 + break; 659 + default: 660 + retry = false; 661 + successive_ext_delays = 0; 662 + break; 663 + } 664 + 665 + return retry; 666 + } 1185 667 1186 668 /** 1187 669 * rtas_busy_delay() - helper for RTAS busy and extended delay statuses ··· 1241 643 * * false - @status is not @RTAS_BUSY nor an extended delay hint. The 1242 644 * caller is responsible for handling @status. 1243 645 */ 1244 - bool rtas_busy_delay(int status) 646 + bool __ref rtas_busy_delay(int status) 1245 647 { 1246 648 unsigned int ms; 1247 649 bool ret; 650 + 651 + /* 652 + * Can't do timed sleeps before timekeeping is up. 653 + */ 654 + if (system_state < SYSTEM_SCHEDULING) 655 + return rtas_busy_delay_early(status); 1248 656 1249 657 switch (status) { 1250 658 case RTAS_EXTENDED_DELAY_MIN...RTAS_EXTENDED_DELAY_MAX: ··· 1301 697 1302 698 return ret; 1303 699 } 1304 - EXPORT_SYMBOL(rtas_busy_delay); 700 + EXPORT_SYMBOL_GPL(rtas_busy_delay); 1305 701 1306 702 static int rtas_error_rc(int rtas_rc) 1307 703 { ··· 1333 729 1334 730 int rtas_get_power_level(int powerdomain, int *level) 1335 731 { 1336 - int token = rtas_token("get-power-level"); 732 + int token = rtas_function_token(RTAS_FN_GET_POWER_LEVEL); 1337 733 int rc; 1338 734 1339 735 if (token == RTAS_UNKNOWN_SERVICE) ··· 1346 742 return rtas_error_rc(rc); 1347 743 return rc; 1348 744 } 1349 - EXPORT_SYMBOL(rtas_get_power_level); 745 + EXPORT_SYMBOL_GPL(rtas_get_power_level); 1350 746 1351 747 int rtas_set_power_level(int powerdomain, int level, int *setlevel) 1352 748 { 1353 - int token = rtas_token("set-power-level"); 749 + int token = rtas_function_token(RTAS_FN_SET_POWER_LEVEL); 1354 750 int rc; 1355 751 1356 752 if (token == RTAS_UNKNOWN_SERVICE) ··· 1364 760 return rtas_error_rc(rc); 1365 761 return rc; 1366 762 } 1367 - EXPORT_SYMBOL(rtas_set_power_level); 763 + EXPORT_SYMBOL_GPL(rtas_set_power_level); 1368 764 1369 765 int rtas_get_sensor(int sensor, int index, int *state) 1370 766 { 1371 - int token = rtas_token("get-sensor-state"); 767 + int token = rtas_function_token(RTAS_FN_GET_SENSOR_STATE); 1372 768 int rc; 1373 769 1374 770 if (token == RTAS_UNKNOWN_SERVICE) ··· 1382 778 return rtas_error_rc(rc); 1383 779 return rc; 1384 780 } 1385 - EXPORT_SYMBOL(rtas_get_sensor); 781 + EXPORT_SYMBOL_GPL(rtas_get_sensor); 1386 782 1387 783 int rtas_get_sensor_fast(int sensor, int index, int *state) 1388 784 { 1389 - int token = rtas_token("get-sensor-state"); 785 + int token = rtas_function_token(RTAS_FN_GET_SENSOR_STATE); 1390 786 int rc; 1391 787 1392 788 if (token == RTAS_UNKNOWN_SERVICE) ··· 1425 821 1426 822 return false; 1427 823 } 1428 - EXPORT_SYMBOL(rtas_indicator_present); 1429 824 1430 825 int rtas_set_indicator(int indicator, int index, int new_value) 1431 826 { 1432 - int token = rtas_token("set-indicator"); 827 + int token = rtas_function_token(RTAS_FN_SET_INDICATOR); 1433 828 int rc; 1434 829 1435 830 if (token == RTAS_UNKNOWN_SERVICE) ··· 1442 839 return rtas_error_rc(rc); 1443 840 return rc; 1444 841 } 1445 - EXPORT_SYMBOL(rtas_set_indicator); 842 + EXPORT_SYMBOL_GPL(rtas_set_indicator); 1446 843 1447 844 /* 1448 845 * Ignoring RTAS extended delay 1449 846 */ 1450 847 int rtas_set_indicator_fast(int indicator, int index, int new_value) 1451 848 { 849 + int token = rtas_function_token(RTAS_FN_SET_INDICATOR); 1452 850 int rc; 1453 - int token = rtas_token("set-indicator"); 1454 851 1455 852 if (token == RTAS_UNKNOWN_SERVICE) 1456 853 return -ENOENT; ··· 1492 889 */ 1493 890 int rtas_ibm_suspend_me(int *fw_status) 1494 891 { 892 + int token = rtas_function_token(RTAS_FN_IBM_SUSPEND_ME); 1495 893 int fwrc; 1496 894 int ret; 1497 895 1498 - fwrc = rtas_call(rtas_token("ibm,suspend-me"), 0, 1, NULL); 896 + fwrc = rtas_call(token, 0, 1, NULL); 1499 897 1500 898 switch (fwrc) { 1501 899 case 0: ··· 1529 925 if (rtas_flash_term_hook) 1530 926 rtas_flash_term_hook(SYS_RESTART); 1531 927 pr_emerg("system-reboot returned %d\n", 1532 - rtas_call(rtas_token("system-reboot"), 0, 1, NULL)); 928 + rtas_call(rtas_function_token(RTAS_FN_SYSTEM_REBOOT), 0, 1, NULL)); 1533 929 for (;;); 1534 930 } 1535 931 ··· 1539 935 rtas_flash_term_hook(SYS_POWER_OFF); 1540 936 /* allow power on only with power button press */ 1541 937 pr_emerg("power-off returned %d\n", 1542 - rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1)); 938 + rtas_call(rtas_function_token(RTAS_FN_POWER_OFF), 2, 1, NULL, -1, -1)); 1543 939 for (;;); 1544 940 } 1545 941 ··· 1549 945 rtas_flash_term_hook(SYS_HALT); 1550 946 /* allow power on only with power button press */ 1551 947 pr_emerg("power-off returned %d\n", 1552 - rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1)); 948 + rtas_call(rtas_function_token(RTAS_FN_POWER_OFF), 2, 1, NULL, -1, -1)); 1553 949 for (;;); 1554 950 } 1555 951 1556 952 /* Must be in the RMO region, so we place it here */ 1557 953 static char rtas_os_term_buf[2048]; 1558 - static s32 ibm_os_term_token = RTAS_UNKNOWN_SERVICE; 954 + static bool ibm_extended_os_term; 1559 955 1560 956 void rtas_os_term(char *str) 1561 957 { 958 + s32 token = rtas_function_token(RTAS_FN_IBM_OS_TERM); 1562 959 int status; 1563 960 1564 961 /* ··· 1568 963 * this property may terminate the partition which we want to avoid 1569 964 * since it interferes with panic_timeout. 1570 965 */ 1571 - if (ibm_os_term_token == RTAS_UNKNOWN_SERVICE) 966 + 967 + if (token == RTAS_UNKNOWN_SERVICE || !ibm_extended_os_term) 1572 968 return; 1573 969 1574 970 snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str); ··· 1580 974 * schedules. 1581 975 */ 1582 976 do { 1583 - status = rtas_call(ibm_os_term_token, 1, 1, NULL, 1584 - __pa(rtas_os_term_buf)); 977 + status = rtas_call(token, 1, 1, NULL, __pa(rtas_os_term_buf)); 1585 978 } while (rtas_busy_delay_time(status)); 1586 979 1587 980 if (status != 0) ··· 1600 995 */ 1601 996 void rtas_activate_firmware(void) 1602 997 { 1603 - int token; 998 + int token = rtas_function_token(RTAS_FN_IBM_ACTIVATE_FIRMWARE); 1604 999 int fwrc; 1605 1000 1606 - token = rtas_token("ibm,activate-firmware"); 1607 1001 if (token == RTAS_UNKNOWN_SERVICE) { 1608 1002 pr_notice("ibm,activate-firmware method unavailable\n"); 1609 1003 return; ··· 1667 1063 * 1668 1064 * Accordingly, we filter RTAS requests to check that the call is 1669 1065 * permitted, and that provided pointers fall within the RMO buffer. 1670 - * The rtas_filters list contains an entry for each permitted call, 1671 - * with the indexes of the parameters which are expected to contain 1672 - * addresses and sizes of buffers allocated inside the RMO buffer. 1066 + * If a function is allowed to be invoked via the syscall, then its 1067 + * entry in the rtas_functions table points to a rtas_filter that 1068 + * describes its constraints, with the indexes of the parameters which 1069 + * are expected to contain addresses and sizes of buffers allocated 1070 + * inside the RMO buffer. 1673 1071 */ 1674 - struct rtas_filter { 1675 - const char *name; 1676 - int token; 1677 - /* Indexes into the args buffer, -1 if not used */ 1678 - int buf_idx1; 1679 - int size_idx1; 1680 - int buf_idx2; 1681 - int size_idx2; 1682 - 1683 - int fixed_size; 1684 - }; 1685 - 1686 - static struct rtas_filter rtas_filters[] __ro_after_init = { 1687 - { "ibm,activate-firmware", -1, -1, -1, -1, -1 }, 1688 - { "ibm,configure-connector", -1, 0, -1, 1, -1, 4096 }, /* Special cased */ 1689 - { "display-character", -1, -1, -1, -1, -1 }, 1690 - { "ibm,display-message", -1, 0, -1, -1, -1 }, 1691 - { "ibm,errinjct", -1, 2, -1, -1, -1, 1024 }, 1692 - { "ibm,close-errinjct", -1, -1, -1, -1, -1 }, 1693 - { "ibm,open-errinjct", -1, -1, -1, -1, -1 }, 1694 - { "ibm,get-config-addr-info2", -1, -1, -1, -1, -1 }, 1695 - { "ibm,get-dynamic-sensor-state", -1, 1, -1, -1, -1 }, 1696 - { "ibm,get-indices", -1, 2, 3, -1, -1 }, 1697 - { "get-power-level", -1, -1, -1, -1, -1 }, 1698 - { "get-sensor-state", -1, -1, -1, -1, -1 }, 1699 - { "ibm,get-system-parameter", -1, 1, 2, -1, -1 }, 1700 - { "get-time-of-day", -1, -1, -1, -1, -1 }, 1701 - { "ibm,get-vpd", -1, 0, -1, 1, 2 }, 1702 - { "ibm,lpar-perftools", -1, 2, 3, -1, -1 }, 1703 - { "ibm,platform-dump", -1, 4, 5, -1, -1 }, /* Special cased */ 1704 - { "ibm,read-slot-reset-state", -1, -1, -1, -1, -1 }, 1705 - { "ibm,scan-log-dump", -1, 0, 1, -1, -1 }, 1706 - { "ibm,set-dynamic-indicator", -1, 2, -1, -1, -1 }, 1707 - { "ibm,set-eeh-option", -1, -1, -1, -1, -1 }, 1708 - { "set-indicator", -1, -1, -1, -1, -1 }, 1709 - { "set-power-level", -1, -1, -1, -1, -1 }, 1710 - { "set-time-for-power-on", -1, -1, -1, -1, -1 }, 1711 - { "ibm,set-system-parameter", -1, 1, -1, -1, -1 }, 1712 - { "set-time-of-day", -1, -1, -1, -1, -1 }, 1713 - #ifdef CONFIG_CPU_BIG_ENDIAN 1714 - { "ibm,suspend-me", -1, -1, -1, -1, -1 }, 1715 - { "ibm,update-nodes", -1, 0, -1, -1, -1, 4096 }, 1716 - { "ibm,update-properties", -1, 0, -1, -1, -1, 4096 }, 1717 - #endif 1718 - { "ibm,physical-attestation", -1, 0, 1, -1, -1 }, 1719 - }; 1720 1072 1721 1073 static bool in_rmo_buf(u32 base, u32 end) 1722 1074 { ··· 1686 1126 static bool block_rtas_call(int token, int nargs, 1687 1127 struct rtas_args *args) 1688 1128 { 1689 - int i; 1129 + const struct rtas_function *func; 1130 + const struct rtas_filter *f; 1131 + const bool is_platform_dump = token == rtas_function_token(RTAS_FN_IBM_PLATFORM_DUMP); 1132 + const bool is_config_conn = token == rtas_function_token(RTAS_FN_IBM_CONFIGURE_CONNECTOR); 1133 + u32 base, size, end; 1690 1134 1691 - for (i = 0; i < ARRAY_SIZE(rtas_filters); i++) { 1692 - struct rtas_filter *f = &rtas_filters[i]; 1693 - u32 base, size, end; 1135 + /* 1136 + * If this token doesn't correspond to a function the kernel 1137 + * understands, you're not allowed to call it. 1138 + */ 1139 + func = rtas_token_to_function(token); 1140 + if (!func) 1141 + goto err; 1142 + /* 1143 + * And only functions with filters attached are allowed. 1144 + */ 1145 + f = func->filter; 1146 + if (!f) 1147 + goto err; 1148 + /* 1149 + * And some functions aren't allowed on LE. 1150 + */ 1151 + if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) && func->banned_for_syscall_on_le) 1152 + goto err; 1694 1153 1695 - if (token != f->token) 1696 - continue; 1154 + if (f->buf_idx1 != -1) { 1155 + base = be32_to_cpu(args->args[f->buf_idx1]); 1156 + if (f->size_idx1 != -1) 1157 + size = be32_to_cpu(args->args[f->size_idx1]); 1158 + else if (f->fixed_size) 1159 + size = f->fixed_size; 1160 + else 1161 + size = 1; 1697 1162 1698 - if (f->buf_idx1 != -1) { 1699 - base = be32_to_cpu(args->args[f->buf_idx1]); 1700 - if (f->size_idx1 != -1) 1701 - size = be32_to_cpu(args->args[f->size_idx1]); 1702 - else if (f->fixed_size) 1703 - size = f->fixed_size; 1704 - else 1705 - size = 1; 1163 + end = base + size - 1; 1706 1164 1707 - end = base + size - 1; 1165 + /* 1166 + * Special case for ibm,platform-dump - NULL buffer 1167 + * address is used to indicate end of dump processing 1168 + */ 1169 + if (is_platform_dump && base == 0) 1170 + return false; 1708 1171 1709 - /* 1710 - * Special case for ibm,platform-dump - NULL buffer 1711 - * address is used to indicate end of dump processing 1712 - */ 1713 - if (!strcmp(f->name, "ibm,platform-dump") && 1714 - base == 0) 1715 - return false; 1716 - 1717 - if (!in_rmo_buf(base, end)) 1718 - goto err; 1719 - } 1720 - 1721 - if (f->buf_idx2 != -1) { 1722 - base = be32_to_cpu(args->args[f->buf_idx2]); 1723 - if (f->size_idx2 != -1) 1724 - size = be32_to_cpu(args->args[f->size_idx2]); 1725 - else if (f->fixed_size) 1726 - size = f->fixed_size; 1727 - else 1728 - size = 1; 1729 - end = base + size - 1; 1730 - 1731 - /* 1732 - * Special case for ibm,configure-connector where the 1733 - * address can be 0 1734 - */ 1735 - if (!strcmp(f->name, "ibm,configure-connector") && 1736 - base == 0) 1737 - return false; 1738 - 1739 - if (!in_rmo_buf(base, end)) 1740 - goto err; 1741 - } 1742 - 1743 - return false; 1172 + if (!in_rmo_buf(base, end)) 1173 + goto err; 1744 1174 } 1745 1175 1176 + if (f->buf_idx2 != -1) { 1177 + base = be32_to_cpu(args->args[f->buf_idx2]); 1178 + if (f->size_idx2 != -1) 1179 + size = be32_to_cpu(args->args[f->size_idx2]); 1180 + else if (f->fixed_size) 1181 + size = f->fixed_size; 1182 + else 1183 + size = 1; 1184 + end = base + size - 1; 1185 + 1186 + /* 1187 + * Special case for ibm,configure-connector where the 1188 + * address can be 0 1189 + */ 1190 + if (is_config_conn && base == 0) 1191 + return false; 1192 + 1193 + if (!in_rmo_buf(base, end)) 1194 + goto err; 1195 + } 1196 + 1197 + return false; 1746 1198 err: 1747 1199 pr_err_ratelimited("sys_rtas: RTAS call blocked - exploit attempt?\n"); 1748 1200 pr_err_ratelimited("sys_rtas: token=0x%x, nargs=%d (called by %s)\n", 1749 1201 token, nargs, current->comm); 1750 1202 return true; 1751 - } 1752 - 1753 - static void __init rtas_syscall_filter_init(void) 1754 - { 1755 - unsigned int i; 1756 - 1757 - for (i = 0; i < ARRAY_SIZE(rtas_filters); i++) 1758 - rtas_filters[i].token = rtas_token(rtas_filters[i].name); 1759 1203 } 1760 1204 1761 1205 /* We assume to be passed big endian arguments */ ··· 1802 1238 if (block_rtas_call(token, nargs, &args)) 1803 1239 return -EINVAL; 1804 1240 1805 - if (token == ibm_open_errinjct_token || token == ibm_errinjct_token) { 1241 + if (token_is_restricted_errinjct(token)) { 1806 1242 int err; 1807 1243 1808 1244 err = security_locked_down(LOCKDOWN_RTAS_ERROR_INJECTION); ··· 1811 1247 } 1812 1248 1813 1249 /* Need to handle ibm,suspend_me call specially */ 1814 - if (token == rtas_token("ibm,suspend-me")) { 1250 + if (token == rtas_function_token(RTAS_FN_IBM_SUSPEND_ME)) { 1815 1251 1816 1252 /* 1817 1253 * rtas_ibm_suspend_me assumes the streamid handle is in cpu ··· 1832 1268 1833 1269 buff_copy = get_errorlog_buffer(); 1834 1270 1835 - flags = lock_rtas(); 1271 + raw_spin_lock_irqsave(&rtas_lock, flags); 1836 1272 1837 - rtas.args = args; 1838 - do_enter_rtas(__pa(&rtas.args)); 1839 - args = rtas.args; 1273 + rtas_args = args; 1274 + do_enter_rtas(&rtas_args); 1275 + args = rtas_args; 1840 1276 1841 1277 /* A -1 return code indicates that the last command couldn't 1842 1278 be completed due to a hardware error. */ 1843 1279 if (be32_to_cpu(args.rets[0]) == -1) 1844 1280 errbuf = __fetch_rtas_last_error(buff_copy); 1845 1281 1846 - unlock_rtas(flags); 1282 + raw_spin_unlock_irqrestore(&rtas_lock, flags); 1847 1283 1848 1284 if (buff_copy) { 1849 1285 if (errbuf) ··· 1859 1295 return -EFAULT; 1860 1296 1861 1297 return 0; 1298 + } 1299 + 1300 + static void __init rtas_function_table_init(void) 1301 + { 1302 + struct property *prop; 1303 + 1304 + for (size_t i = 0; i < ARRAY_SIZE(rtas_function_table); ++i) { 1305 + struct rtas_function *curr = &rtas_function_table[i]; 1306 + struct rtas_function *prior; 1307 + int cmp; 1308 + 1309 + curr->token = RTAS_UNKNOWN_SERVICE; 1310 + 1311 + if (i == 0) 1312 + continue; 1313 + /* 1314 + * Ensure table is sorted correctly for binary search 1315 + * on function names. 1316 + */ 1317 + prior = &rtas_function_table[i - 1]; 1318 + 1319 + cmp = strcmp(prior->name, curr->name); 1320 + if (cmp < 0) 1321 + continue; 1322 + 1323 + if (cmp == 0) { 1324 + pr_err("'%s' has duplicate function table entries\n", 1325 + curr->name); 1326 + } else { 1327 + pr_err("function table unsorted: '%s' wrongly precedes '%s'\n", 1328 + prior->name, curr->name); 1329 + } 1330 + } 1331 + 1332 + for_each_property_of_node(rtas.dev, prop) { 1333 + struct rtas_function *func; 1334 + 1335 + if (prop->length != sizeof(u32)) 1336 + continue; 1337 + 1338 + func = __rtas_name_to_function(prop->name); 1339 + if (!func) 1340 + continue; 1341 + 1342 + func->token = be32_to_cpup((__be32 *)prop->value); 1343 + 1344 + pr_debug("function %s has token %u\n", func->name, func->token); 1345 + } 1862 1346 } 1863 1347 1864 1348 /* ··· 1942 1330 1943 1331 init_error_log_max(); 1944 1332 1333 + /* Must be called before any function token lookups */ 1334 + rtas_function_table_init(); 1335 + 1945 1336 /* 1946 - * Discover these now to avoid device tree lookups in the 1337 + * Discover this now to avoid a device tree lookup in the 1947 1338 * panic path. 1948 1339 */ 1949 - if (of_property_read_bool(rtas.dev, "ibm,extended-os-term")) 1950 - ibm_os_term_token = rtas_token("ibm,os-term"); 1340 + ibm_extended_os_term = of_property_read_bool(rtas.dev, "ibm,extended-os-term"); 1951 1341 1952 1342 /* If RTAS was found, allocate the RMO buffer for it and look for 1953 1343 * the stop-self token if any ··· 1964 1350 panic("ERROR: RTAS: Failed to allocate %lx bytes below %pa\n", 1965 1351 PAGE_SIZE, &rtas_region); 1966 1352 1967 - #ifdef CONFIG_RTAS_ERROR_LOGGING 1968 - rtas_last_error_token = rtas_token("rtas-last-error"); 1969 - #endif 1970 - ibm_open_errinjct_token = rtas_token("ibm,open-errinjct"); 1971 - ibm_errinjct_token = rtas_token("ibm,errinjct"); 1972 - rtas_syscall_filter_init(); 1353 + rtas_work_area_reserve_arena(rtas_region); 1973 1354 } 1974 1355 1975 1356 int __init early_init_dt_scan_rtas(unsigned long node, ··· 2010 1401 return 1; 2011 1402 } 2012 1403 2013 - static arch_spinlock_t timebase_lock; 1404 + static DEFINE_RAW_SPINLOCK(timebase_lock); 2014 1405 static u64 timebase = 0; 2015 1406 2016 1407 void rtas_give_timebase(void) 2017 1408 { 2018 1409 unsigned long flags; 2019 1410 2020 - local_irq_save(flags); 1411 + raw_spin_lock_irqsave(&timebase_lock, flags); 2021 1412 hard_irq_disable(); 2022 - arch_spin_lock(&timebase_lock); 2023 - rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); 1413 + rtas_call(rtas_function_token(RTAS_FN_FREEZE_TIME_BASE), 0, 1, NULL); 2024 1414 timebase = get_tb(); 2025 - arch_spin_unlock(&timebase_lock); 1415 + raw_spin_unlock(&timebase_lock); 2026 1416 2027 1417 while (timebase) 2028 1418 barrier(); 2029 - rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); 1419 + rtas_call(rtas_function_token(RTAS_FN_THAW_TIME_BASE), 0, 1, NULL); 2030 1420 local_irq_restore(flags); 2031 1421 } 2032 1422 ··· 2033 1425 { 2034 1426 while (!timebase) 2035 1427 barrier(); 2036 - arch_spin_lock(&timebase_lock); 1428 + raw_spin_lock(&timebase_lock); 2037 1429 set_tb(timebase >> 32, timebase & 0xffffffff); 2038 1430 timebase = 0; 2039 - arch_spin_unlock(&timebase_lock); 1431 + raw_spin_unlock(&timebase_lock); 2040 1432 }
+10 -11
arch/powerpc/kernel/rtas_flash.c
··· 376 376 s32 rc; 377 377 378 378 do { 379 - rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 1, 379 + rc = rtas_call(rtas_function_token(RTAS_FN_IBM_MANAGE_FLASH_IMAGE), 1, 1, 380 380 NULL, op); 381 381 } while (rtas_busy_delay(rc)); 382 382 ··· 444 444 */ 445 445 static void validate_flash(struct rtas_validate_flash_t *args_buf) 446 446 { 447 - int token = rtas_token("ibm,validate-flash-image"); 447 + int token = rtas_function_token(RTAS_FN_IBM_VALIDATE_FLASH_IMAGE); 448 448 int update_results; 449 449 s32 rc; 450 450 ··· 570 570 return; 571 571 } 572 572 573 - update_token = rtas_token("ibm,update-flash-64-and-reboot"); 573 + update_token = rtas_function_token(RTAS_FN_IBM_UPDATE_FLASH_64_AND_REBOOT); 574 574 if (update_token == RTAS_UNKNOWN_SERVICE) { 575 575 printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot " 576 576 "is not available -- not a service partition?\n"); ··· 653 653 */ 654 654 struct rtas_flash_file { 655 655 const char *filename; 656 - const char *rtas_call_name; 656 + const rtas_fn_handle_t handle; 657 657 int *status; 658 658 const struct proc_ops ops; 659 659 }; ··· 661 661 static const struct rtas_flash_file rtas_flash_files[] = { 662 662 { 663 663 .filename = "powerpc/rtas/" FIRMWARE_FLASH_NAME, 664 - .rtas_call_name = "ibm,update-flash-64-and-reboot", 664 + .handle = RTAS_FN_IBM_UPDATE_FLASH_64_AND_REBOOT, 665 665 .status = &rtas_update_flash_data.status, 666 666 .ops.proc_read = rtas_flash_read_msg, 667 667 .ops.proc_write = rtas_flash_write, ··· 670 670 }, 671 671 { 672 672 .filename = "powerpc/rtas/" FIRMWARE_UPDATE_NAME, 673 - .rtas_call_name = "ibm,update-flash-64-and-reboot", 673 + .handle = RTAS_FN_IBM_UPDATE_FLASH_64_AND_REBOOT, 674 674 .status = &rtas_update_flash_data.status, 675 675 .ops.proc_read = rtas_flash_read_num, 676 676 .ops.proc_write = rtas_flash_write, ··· 679 679 }, 680 680 { 681 681 .filename = "powerpc/rtas/" VALIDATE_FLASH_NAME, 682 - .rtas_call_name = "ibm,validate-flash-image", 682 + .handle = RTAS_FN_IBM_VALIDATE_FLASH_IMAGE, 683 683 .status = &rtas_validate_flash_data.status, 684 684 .ops.proc_read = validate_flash_read, 685 685 .ops.proc_write = validate_flash_write, ··· 688 688 }, 689 689 { 690 690 .filename = "powerpc/rtas/" MANAGE_FLASH_NAME, 691 - .rtas_call_name = "ibm,manage-flash-image", 691 + .handle = RTAS_FN_IBM_MANAGE_FLASH_IMAGE, 692 692 .status = &rtas_manage_flash_data.status, 693 693 .ops.proc_read = manage_flash_read, 694 694 .ops.proc_write = manage_flash_write, ··· 700 700 { 701 701 int i; 702 702 703 - if (rtas_token("ibm,update-flash-64-and-reboot") == 704 - RTAS_UNKNOWN_SERVICE) { 703 + if (rtas_function_token(RTAS_FN_IBM_UPDATE_FLASH_64_AND_REBOOT) == RTAS_UNKNOWN_SERVICE) { 705 704 pr_info("rtas_flash: no firmware flash support\n"); 706 705 return -EINVAL; 707 706 } ··· 729 730 * This code assumes that the status int is the first member of the 730 731 * struct 731 732 */ 732 - token = rtas_token(f->rtas_call_name); 733 + token = rtas_function_token(f->handle); 733 734 if (token == RTAS_UNKNOWN_SERVICE) 734 735 *f->status = FLASH_AUTH; 735 736 else
+4 -4
arch/powerpc/kernel/rtas_pci.c
··· 191 191 192 192 void __init init_pci_config_tokens(void) 193 193 { 194 - read_pci_config = rtas_token("read-pci-config"); 195 - write_pci_config = rtas_token("write-pci-config"); 196 - ibm_read_pci_config = rtas_token("ibm,read-pci-config"); 197 - ibm_write_pci_config = rtas_token("ibm,write-pci-config"); 194 + read_pci_config = rtas_function_token(RTAS_FN_READ_PCI_CONFIG); 195 + write_pci_config = rtas_function_token(RTAS_FN_WRITE_PCI_CONFIG); 196 + ibm_read_pci_config = rtas_function_token(RTAS_FN_IBM_READ_PCI_CONFIG); 197 + ibm_write_pci_config = rtas_function_token(RTAS_FN_IBM_WRITE_PCI_CONFIG); 198 198 } 199 199 200 200 unsigned long get_phb_buid(struct device_node *phb)
+1 -1
arch/powerpc/kernel/rtasd.c
··· 506 506 return 0; 507 507 508 508 /* No RTAS */ 509 - event_scan = rtas_token("event-scan"); 509 + event_scan = rtas_function_token(RTAS_FN_EVENT_SCAN); 510 510 if (event_scan == RTAS_UNKNOWN_SERVICE) { 511 511 printk(KERN_INFO "rtasd: No event-scan on system\n"); 512 512 return -ENODEV;
+8 -2
arch/powerpc/kernel/secvar-ops.c
··· 8 8 9 9 #include <linux/cache.h> 10 10 #include <asm/secvar.h> 11 + #include <asm/bug.h> 11 12 12 - const struct secvar_operations *secvar_ops __ro_after_init; 13 + const struct secvar_operations *secvar_ops __ro_after_init = NULL; 13 14 14 - void set_secvar_ops(const struct secvar_operations *ops) 15 + int set_secvar_ops(const struct secvar_operations *ops) 15 16 { 17 + if (WARN_ON_ONCE(secvar_ops)) 18 + return -EBUSY; 19 + 16 20 secvar_ops = ops; 21 + 22 + return 0; 17 23 }
+111 -69
arch/powerpc/kernel/secvar-sysfs.c
··· 21 21 static ssize_t format_show(struct kobject *kobj, struct kobj_attribute *attr, 22 22 char *buf) 23 23 { 24 - ssize_t rc = 0; 25 - struct device_node *node; 26 - const char *format; 24 + char tmp[32]; 25 + ssize_t len = secvar_ops->format(tmp, sizeof(tmp)); 27 26 28 - node = of_find_compatible_node(NULL, NULL, "ibm,secvar-backend"); 29 - if (!of_device_is_available(node)) { 30 - rc = -ENODEV; 31 - goto out; 32 - } 27 + if (len > 0) 28 + return sysfs_emit(buf, "%s\n", tmp); 29 + else if (len < 0) 30 + pr_err("Error %zd reading format string\n", len); 31 + else 32 + pr_err("Got empty format string from backend\n"); 33 33 34 - rc = of_property_read_string(node, "format", &format); 35 - if (rc) 36 - goto out; 37 - 38 - rc = sprintf(buf, "%s\n", format); 39 - 40 - out: 41 - of_node_put(node); 42 - 43 - return rc; 34 + return -EIO; 44 35 } 45 36 46 37 47 38 static ssize_t size_show(struct kobject *kobj, struct kobj_attribute *attr, 48 39 char *buf) 49 40 { 50 - uint64_t dsize; 41 + u64 dsize; 51 42 int rc; 52 43 53 44 rc = secvar_ops->get(kobj->name, strlen(kobj->name) + 1, NULL, &dsize); 54 45 if (rc) { 55 - pr_err("Error retrieving %s variable size %d\n", kobj->name, 56 - rc); 46 + if (rc != -ENOENT) 47 + pr_err("Error retrieving %s variable size %d\n", kobj->name, rc); 57 48 return rc; 58 49 } 59 50 60 - return sprintf(buf, "%llu\n", dsize); 51 + return sysfs_emit(buf, "%llu\n", dsize); 61 52 } 62 53 63 54 static ssize_t data_read(struct file *filep, struct kobject *kobj, 64 55 struct bin_attribute *attr, char *buf, loff_t off, 65 56 size_t count) 66 57 { 67 - uint64_t dsize; 68 58 char *data; 59 + u64 dsize; 69 60 int rc; 70 61 71 62 rc = secvar_ops->get(kobj->name, strlen(kobj->name) + 1, NULL, &dsize); 72 63 if (rc) { 73 - pr_err("Error getting %s variable size %d\n", kobj->name, rc); 64 + if (rc != -ENOENT) 65 + pr_err("Error getting %s variable size %d\n", kobj->name, rc); 74 66 return rc; 75 67 } 76 68 pr_debug("dsize is %llu\n", dsize); ··· 133 141 static int update_kobj_size(void) 134 142 { 135 143 136 - struct device_node *node; 137 144 u64 varsize; 138 - int rc = 0; 145 + int rc = secvar_ops->max_size(&varsize); 139 146 140 - node = of_find_compatible_node(NULL, NULL, "ibm,secvar-backend"); 141 - if (!of_device_is_available(node)) { 142 - rc = -ENODEV; 143 - goto out; 144 - } 145 - 146 - rc = of_property_read_u64(node, "max-var-size", &varsize); 147 147 if (rc) 148 - goto out; 148 + return rc; 149 149 150 150 data_attr.size = varsize; 151 151 update_attr.size = varsize; 152 152 153 - out: 154 - of_node_put(node); 153 + return 0; 154 + } 155 155 156 - return rc; 156 + static int secvar_sysfs_config(struct kobject *kobj) 157 + { 158 + struct attribute_group config_group = { 159 + .name = "config", 160 + .attrs = (struct attribute **)secvar_ops->config_attrs, 161 + }; 162 + 163 + if (secvar_ops->config_attrs) 164 + return sysfs_create_group(kobj, &config_group); 165 + 166 + return 0; 167 + } 168 + 169 + static int add_var(const char *name) 170 + { 171 + struct kobject *kobj; 172 + int rc; 173 + 174 + kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); 175 + if (!kobj) 176 + return -ENOMEM; 177 + 178 + kobject_init(kobj, &secvar_ktype); 179 + 180 + rc = kobject_add(kobj, &secvar_kset->kobj, "%s", name); 181 + if (rc) { 182 + pr_warn("kobject_add error %d for attribute: %s\n", rc, 183 + name); 184 + kobject_put(kobj); 185 + return rc; 186 + } 187 + 188 + kobject_uevent(kobj, KOBJ_ADD); 189 + return 0; 157 190 } 158 191 159 192 static int secvar_sysfs_load(void) 160 193 { 194 + u64 namesize = 0; 161 195 char *name; 162 - uint64_t namesize = 0; 163 - struct kobject *kobj; 164 196 int rc; 165 197 166 198 name = kzalloc(NAME_MAX_SIZE, GFP_KERNEL); ··· 195 179 rc = secvar_ops->get_next(name, &namesize, NAME_MAX_SIZE); 196 180 if (rc) { 197 181 if (rc != -ENOENT) 198 - pr_err("error getting secvar from firmware %d\n", 199 - rc); 182 + pr_err("error getting secvar from firmware %d\n", rc); 183 + else 184 + rc = 0; 185 + 200 186 break; 201 187 } 202 188 203 - kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); 204 - if (!kobj) { 205 - rc = -ENOMEM; 206 - break; 207 - } 208 - 209 - kobject_init(kobj, &secvar_ktype); 210 - 211 - rc = kobject_add(kobj, &secvar_kset->kobj, "%s", name); 212 - if (rc) { 213 - pr_warn("kobject_add error %d for attribute: %s\n", rc, 214 - name); 215 - kobject_put(kobj); 216 - kobj = NULL; 217 - } 218 - 219 - if (kobj) 220 - kobject_uevent(kobj, KOBJ_ADD); 221 - 189 + rc = add_var(name); 222 190 } while (!rc); 223 191 224 192 kfree(name); 225 193 return rc; 226 194 } 227 195 196 + static int secvar_sysfs_load_static(void) 197 + { 198 + const char * const *name_ptr = secvar_ops->var_names; 199 + int rc; 200 + 201 + while (*name_ptr) { 202 + rc = add_var(*name_ptr); 203 + if (rc) 204 + return rc; 205 + name_ptr++; 206 + } 207 + 208 + return 0; 209 + } 210 + 228 211 static int secvar_sysfs_init(void) 229 212 { 213 + u64 max_size; 230 214 int rc; 231 215 232 216 if (!secvar_ops) { 233 - pr_warn("secvar: failed to retrieve secvar operations.\n"); 217 + pr_warn("Failed to retrieve secvar operations\n"); 234 218 return -ENODEV; 235 219 } 236 220 237 221 secvar_kobj = kobject_create_and_add("secvar", firmware_kobj); 238 222 if (!secvar_kobj) { 239 - pr_err("secvar: Failed to create firmware kobj\n"); 223 + pr_err("Failed to create firmware kobj\n"); 240 224 return -ENOMEM; 241 225 } 242 226 243 227 rc = sysfs_create_file(secvar_kobj, &format_attr.attr); 244 228 if (rc) { 245 - kobject_put(secvar_kobj); 246 - return -ENOMEM; 229 + pr_err("Failed to create format object\n"); 230 + rc = -ENOMEM; 231 + goto err; 247 232 } 248 233 249 234 secvar_kset = kset_create_and_add("vars", NULL, secvar_kobj); 250 235 if (!secvar_kset) { 251 - pr_err("secvar: sysfs kobject registration failed.\n"); 252 - kobject_put(secvar_kobj); 253 - return -ENOMEM; 236 + pr_err("sysfs kobject registration failed\n"); 237 + rc = -ENOMEM; 238 + goto err; 254 239 } 255 240 256 241 rc = update_kobj_size(); 257 242 if (rc) { 258 243 pr_err("Cannot read the size of the attribute\n"); 259 - return rc; 244 + goto err; 260 245 } 261 246 262 - secvar_sysfs_load(); 247 + rc = secvar_sysfs_config(secvar_kobj); 248 + if (rc) { 249 + pr_err("Failed to create config directory\n"); 250 + goto err; 251 + } 252 + 253 + if (secvar_ops->get_next) 254 + rc = secvar_sysfs_load(); 255 + else 256 + rc = secvar_sysfs_load_static(); 257 + 258 + if (rc) { 259 + pr_err("Failed to create variable attributes\n"); 260 + goto err; 261 + } 262 + 263 + // Due to sysfs limitations, we will only ever get a write buffer of 264 + // up to 1 page in size. Print a warning if this is potentially going 265 + // to cause problems, so that the user is aware. 266 + secvar_ops->max_size(&max_size); 267 + if (max_size > PAGE_SIZE) 268 + pr_warn_ratelimited("PAGE_SIZE (%lu) is smaller than maximum object size (%llu), writes are limited to PAGE_SIZE\n", 269 + PAGE_SIZE, max_size); 263 270 264 271 return 0; 272 + err: 273 + kobject_put(secvar_kobj); 274 + return rc; 265 275 } 266 276 267 277 late_initcall(secvar_sysfs_init);
+4
arch/powerpc/kernel/setup-common.c
··· 87 87 int boot_cpuid = -1; 88 88 EXPORT_SYMBOL_GPL(boot_cpuid); 89 89 90 + #ifdef CONFIG_PPC64 91 + int boot_cpu_hwid = -1; 92 + #endif 93 + 90 94 /* 91 95 * These are used in binfmt_elf.c to put aux entries on the stack 92 96 * for each elf executable being started.
+10 -6
arch/powerpc/kernel/setup_64.c
··· 385 385 /* 386 386 * Do early initialization using the flattened device 387 387 * tree, such as retrieving the physical memory map or 388 - * calculating/retrieving the hash table size. 388 + * calculating/retrieving the hash table size, discover 389 + * boot_cpuid and boot_cpu_hwid. 389 390 */ 390 391 early_init_devtree(__va(dt_ptr)); 391 392 392 - /* Now we know the logical id of our boot cpu, setup the paca. */ 393 - if (boot_cpuid != 0) { 394 - /* Poison paca_ptrs[0] again if it's not the boot cpu */ 395 - memset(&paca_ptrs[0], 0x88, sizeof(paca_ptrs[0])); 396 - } 393 + allocate_paca_ptrs(); 394 + allocate_paca(boot_cpuid); 395 + set_hard_smp_processor_id(boot_cpuid, boot_cpu_hwid); 397 396 fixup_boot_paca(paca_ptrs[boot_cpuid]); 398 397 setup_paca(paca_ptrs[boot_cpuid]); /* install the paca into registers */ 398 + // smp_processor_id() now reports boot_cpuid 399 + 400 + #ifdef CONFIG_SMP 401 + task_thread_info(current)->cpu = boot_cpuid; // fix task_cpu(current) 402 + #endif 399 403 400 404 /* 401 405 * Configure exception handlers. This include setting up trampolines
+2 -2
arch/powerpc/kernel/time.c
··· 356 356 } 357 357 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ 358 358 359 - void __delay(unsigned long loops) 359 + void __no_kcsan __delay(unsigned long loops) 360 360 { 361 361 unsigned long start; 362 362 ··· 377 377 } 378 378 EXPORT_SYMBOL(__delay); 379 379 380 - void udelay(unsigned long usecs) 380 + void __no_kcsan udelay(unsigned long usecs) 381 381 { 382 382 __delay(tb_ticks_per_usec * usecs); 383 383 }
+1
arch/powerpc/kernel/trace/Makefile
··· 23 23 # Disable GCOV, KCOV & sanitizers in odd or sensitive code 24 24 GCOV_PROFILE_ftrace.o := n 25 25 KCOV_INSTRUMENT_ftrace.o := n 26 + KCSAN_SANITIZE_ftrace.o := n 26 27 UBSAN_SANITIZE_ftrace.o := n
+1
arch/powerpc/kernel/vdso/Makefile
··· 46 46 KCOV_INSTRUMENT := n 47 47 UBSAN_SANITIZE := n 48 48 KASAN_SANITIZE := n 49 + KCSAN_SANITIZE := n 49 50 50 51 ccflags-y := -shared -fno-common -fno-builtin -nostdlib -Wl,--hash-style=both 51 52 ccflags-$(CONFIG_LD_IS_LLD) += $(call cc-option,--ld-path=$(LD),-fuse-ld=lld)
+15 -6
arch/powerpc/kexec/file_load_64.c
··· 28 28 #include <asm/crashdump-ppc64.h> 29 29 #include <asm/mmzone.h> 30 30 #include <asm/prom.h> 31 + #include <asm/plpks.h> 31 32 32 33 struct umem_info { 33 34 u64 *buf; /* data buffer for usable-memory property */ ··· 690 689 ret = fdt_setprop(fdt, node, "linux,drconf-usable-memory", 691 690 um_info.buf, (um_info.idx * sizeof(u64))); 692 691 if (ret) { 693 - pr_err("Failed to update fdt with linux,drconf-usable-memory property"); 692 + pr_err("Failed to update fdt with linux,drconf-usable-memory property: %s", 693 + fdt_strerror(ret)); 694 694 goto out; 695 695 } 696 696 } ··· 980 978 */ 981 979 unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image) 982 980 { 983 - unsigned int cpu_nodes, extra_size; 981 + unsigned int cpu_nodes, extra_size = 0; 984 982 struct device_node *dn; 985 983 u64 usm_entries; 986 984 985 + // Budget some space for the password blob. There's already extra space 986 + // for the key name 987 + if (plpks_is_available()) 988 + extra_size += (unsigned int)plpks_get_passwordlen(); 989 + 987 990 if (image->type != KEXEC_TYPE_CRASH) 988 - return 0; 991 + return extra_size; 989 992 990 993 /* 991 994 * For kdump kernel, account for linux,usable-memory and ··· 1000 993 if (drmem_lmb_size()) { 1001 994 usm_entries = ((memory_hotplug_max() / drmem_lmb_size()) + 1002 995 (2 * (resource_size(&crashk_res) / drmem_lmb_size()))); 1003 - extra_size = (unsigned int)(usm_entries * sizeof(u64)); 1004 - } else { 1005 - extra_size = 0; 996 + extra_size += (unsigned int)(usm_entries * sizeof(u64)); 1006 997 } 1007 998 1008 999 /* ··· 1238 1233 goto out; 1239 1234 } 1240 1235 } 1236 + 1237 + // If we have PLPKS active, we need to provide the password to the new kernel 1238 + if (plpks_is_available()) 1239 + ret = plpks_populate_fdt(fdt); 1241 1240 1242 1241 out: 1243 1242 kfree(rmem);
+2
arch/powerpc/lib/Makefile
··· 16 16 # restart_table.o contains functions called in the NMI interrupt path 17 17 # which can be in real mode. Disable KASAN. 18 18 KASAN_SANITIZE_restart_table.o := n 19 + KCSAN_SANITIZE_code-patching.o := n 20 + KCSAN_SANITIZE_feature-fixups.o := n 19 21 20 22 ifdef CONFIG_KASAN 21 23 CFLAGS_code-patching.o += -DDISABLE_BRANCH_PROFILING
+2 -1
arch/powerpc/mm/book3s64/hash_utils.c
··· 1051 1051 static_branch_enable(&stress_hpt_key); 1052 1052 // Too early to use nr_cpu_ids, so use NR_CPUS 1053 1053 tmp = memblock_phys_alloc_range(sizeof(struct stress_hpt_struct) * NR_CPUS, 1054 - 0, 0, MEMBLOCK_ALLOC_ANYWHERE); 1054 + __alignof__(struct stress_hpt_struct), 1055 + 0, MEMBLOCK_ALLOC_ANYWHERE); 1055 1056 memset((void *)tmp, 0xff, sizeof(struct stress_hpt_struct) * NR_CPUS); 1056 1057 stress_hpt_struct = __va(tmp); 1057 1058
+36 -37
arch/powerpc/mm/book3s64/radix_tlb.c
··· 700 700 */ 701 701 void radix__local_flush_tlb_mm(struct mm_struct *mm) 702 702 { 703 - unsigned long pid; 703 + unsigned long pid = mm->context.id; 704 + 705 + if (WARN_ON_ONCE(pid == MMU_NO_CONTEXT)) 706 + return; 704 707 705 708 preempt_disable(); 706 - pid = mm->context.id; 707 - if (pid != MMU_NO_CONTEXT) 708 - _tlbiel_pid(pid, RIC_FLUSH_TLB); 709 + _tlbiel_pid(pid, RIC_FLUSH_TLB); 709 710 preempt_enable(); 710 711 } 711 712 EXPORT_SYMBOL(radix__local_flush_tlb_mm); ··· 714 713 #ifndef CONFIG_SMP 715 714 void radix__local_flush_all_mm(struct mm_struct *mm) 716 715 { 717 - unsigned long pid; 716 + unsigned long pid = mm->context.id; 717 + 718 + if (WARN_ON_ONCE(pid == MMU_NO_CONTEXT)) 719 + return; 718 720 719 721 preempt_disable(); 720 - pid = mm->context.id; 721 - if (pid != MMU_NO_CONTEXT) 722 - _tlbiel_pid(pid, RIC_FLUSH_ALL); 722 + _tlbiel_pid(pid, RIC_FLUSH_ALL); 723 723 preempt_enable(); 724 724 } 725 725 EXPORT_SYMBOL(radix__local_flush_all_mm); ··· 734 732 void radix__local_flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, 735 733 int psize) 736 734 { 737 - unsigned long pid; 735 + unsigned long pid = mm->context.id; 736 + 737 + if (WARN_ON_ONCE(pid == MMU_NO_CONTEXT)) 738 + return; 738 739 739 740 preempt_disable(); 740 - pid = mm->context.id; 741 - if (pid != MMU_NO_CONTEXT) 742 - _tlbiel_va(vmaddr, pid, psize, RIC_FLUSH_TLB); 741 + _tlbiel_va(vmaddr, pid, psize, RIC_FLUSH_TLB); 743 742 preempt_enable(); 744 743 } 745 744 ··· 948 945 enum tlb_flush_type type; 949 946 950 947 pid = mm->context.id; 951 - if (unlikely(pid == MMU_NO_CONTEXT)) 948 + if (WARN_ON_ONCE(pid == MMU_NO_CONTEXT)) 952 949 return; 953 950 954 951 preempt_disable(); ··· 988 985 enum tlb_flush_type type; 989 986 990 987 pid = mm->context.id; 991 - if (unlikely(pid == MMU_NO_CONTEXT)) 988 + if (WARN_ON_ONCE(pid == MMU_NO_CONTEXT)) 992 989 return; 993 990 994 991 preempt_disable(); ··· 1027 1024 enum tlb_flush_type type; 1028 1025 1029 1026 pid = mm->context.id; 1030 - if (unlikely(pid == MMU_NO_CONTEXT)) 1027 + if (WARN_ON_ONCE(pid == MMU_NO_CONTEXT)) 1031 1028 return; 1032 1029 1033 1030 preempt_disable(); ··· 1107 1104 } 1108 1105 EXPORT_SYMBOL(radix__flush_tlb_kernel_range); 1109 1106 1107 + /* 1108 + * Doesn't appear to be used anywhere. Remove. 1109 + */ 1110 1110 #define TLB_FLUSH_ALL -1UL 1111 1111 1112 1112 /* ··· 1131 1125 unsigned int page_shift = mmu_psize_defs[mmu_virtual_psize].shift; 1132 1126 unsigned long page_size = 1UL << page_shift; 1133 1127 unsigned long nr_pages = (end - start) >> page_shift; 1134 - bool fullmm = (end == TLB_FLUSH_ALL); 1135 1128 bool flush_pid, flush_pwc = false; 1136 1129 enum tlb_flush_type type; 1137 1130 1138 1131 pid = mm->context.id; 1139 - if (unlikely(pid == MMU_NO_CONTEXT)) 1132 + if (WARN_ON_ONCE(pid == MMU_NO_CONTEXT)) 1140 1133 return; 1134 + 1135 + WARN_ON_ONCE(end == TLB_FLUSH_ALL); 1141 1136 1142 1137 preempt_disable(); 1143 1138 smp_mb(); /* see radix__flush_tlb_mm */ 1144 - type = flush_type_needed(mm, fullmm); 1139 + type = flush_type_needed(mm, false); 1145 1140 if (type == FLUSH_TYPE_NONE) 1146 1141 goto out; 1147 1142 1148 - if (fullmm) 1149 - flush_pid = true; 1150 - else if (type == FLUSH_TYPE_GLOBAL) 1143 + if (type == FLUSH_TYPE_GLOBAL) 1151 1144 flush_pid = nr_pages > tlb_single_page_flush_ceiling; 1152 1145 else 1153 1146 flush_pid = nr_pages > tlb_local_single_page_flush_ceiling; ··· 1184 1179 } 1185 1180 } 1186 1181 } else { 1187 - bool hflush = false; 1182 + bool hflush; 1188 1183 unsigned long hstart, hend; 1189 1184 1190 - if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { 1191 - hstart = (start + PMD_SIZE - 1) & PMD_MASK; 1192 - hend = end & PMD_MASK; 1193 - if (hstart < hend) 1194 - hflush = true; 1195 - } 1185 + hstart = (start + PMD_SIZE - 1) & PMD_MASK; 1186 + hend = end & PMD_MASK; 1187 + hflush = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && hstart < hend; 1196 1188 1197 1189 if (type == FLUSH_TYPE_LOCAL) { 1198 1190 asm volatile("ptesync": : :"memory"); ··· 1304 1302 * that flushes the process table entry cache upon process teardown. 1305 1303 * See the comment for radix in arch_exit_mmap(). 1306 1304 */ 1307 - if (tlb->fullmm || tlb->need_flush_all) { 1305 + if (tlb->fullmm) { 1308 1306 __flush_all_mm(mm, true); 1309 1307 } else if ( (psize = radix_get_mmu_psize(page_size)) == -1) { 1310 1308 if (!tlb->freed_tables) ··· 1327 1325 unsigned int page_shift = mmu_psize_defs[psize].shift; 1328 1326 unsigned long page_size = 1UL << page_shift; 1329 1327 unsigned long nr_pages = (end - start) >> page_shift; 1330 - bool fullmm = (end == TLB_FLUSH_ALL); 1331 1328 bool flush_pid; 1332 1329 enum tlb_flush_type type; 1333 1330 1334 1331 pid = mm->context.id; 1335 - if (unlikely(pid == MMU_NO_CONTEXT)) 1332 + if (WARN_ON_ONCE(pid == MMU_NO_CONTEXT)) 1336 1333 return; 1337 1334 1338 - fullmm = (end == TLB_FLUSH_ALL); 1335 + WARN_ON_ONCE(end == TLB_FLUSH_ALL); 1339 1336 1340 1337 preempt_disable(); 1341 1338 smp_mb(); /* see radix__flush_tlb_mm */ 1342 - type = flush_type_needed(mm, fullmm); 1339 + type = flush_type_needed(mm, false); 1343 1340 if (type == FLUSH_TYPE_NONE) 1344 1341 goto out; 1345 1342 1346 - if (fullmm) 1347 - flush_pid = true; 1348 - else if (type == FLUSH_TYPE_GLOBAL) 1343 + if (type == FLUSH_TYPE_GLOBAL) 1349 1344 flush_pid = nr_pages > tlb_single_page_flush_ceiling; 1350 1345 else 1351 1346 flush_pid = nr_pages > tlb_local_single_page_flush_ceiling; ··· 1405 1406 enum tlb_flush_type type; 1406 1407 1407 1408 pid = mm->context.id; 1408 - if (unlikely(pid == MMU_NO_CONTEXT)) 1409 + if (WARN_ON_ONCE(pid == MMU_NO_CONTEXT)) 1409 1410 return; 1410 1411 1411 1412 /* 4k page size, just blow the world */
+1
arch/powerpc/mm/mmu_decl.h
··· 120 120 extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu); 121 121 void create_kaslr_tlb_entry(int entry, unsigned long virt, phys_addr_t phys); 122 122 void reloc_kernel_entry(void *fdt, int addr); 123 + void relocate_init(u64 dt_ptr, phys_addr_t start); 123 124 extern int is_second_reloc; 124 125 #endif 125 126 extern void loadcam_entry(unsigned int index);
+4 -1
arch/powerpc/mm/nohash/e500_hugetlbpage.c
··· 45 45 if (!cpu_has_feature(CPU_FTR_SMT)) 46 46 return; 47 47 48 - asm volatile("1: lbarx %0, 0, %1;" 48 + asm volatile(".machine push;" 49 + ".machine e6500;" 50 + "1: lbarx %0, 0, %1;" 49 51 "cmpwi %0, 0;" 50 52 "bne 2f;" 51 53 "stbcx. %2, 0, %1;" ··· 58 56 "bne 2b;" 59 57 "b 1b;" 60 58 "3:" 59 + ".machine pop;" 61 60 : "=&r" (tmp) 62 61 : "r" (&paca->tcd_ptr->lock), "r" (token) 63 62 : "memory");
+1 -1
arch/powerpc/mm/nohash/tlb_low_64e.S
··· 351 351 352 352 mfspr r15,SPRN_MAS2 353 353 isync 354 - tlbilxva 0,r15 354 + PPC_TLBILX_VA(0,R15) 355 355 isync 356 356 357 357 mtspr SPRN_MAS6,r10
+1 -1
arch/powerpc/net/bpf_jit.h
··· 169 169 void bpf_jit_init_reg_mapping(struct codegen_context *ctx); 170 170 int bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 func); 171 171 int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *ctx, 172 - u32 *addrs, int pass); 172 + u32 *addrs, int pass, bool extra_pass); 173 173 void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx); 174 174 void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx); 175 175 void bpf_jit_realloc_regs(struct codegen_context *ctx);
+3 -88
arch/powerpc/net/bpf_jit_comp.c
··· 23 23 memset32(area, BREAKPOINT_INSTRUCTION, size / 4); 24 24 } 25 25 26 - /* Fix updated addresses (for subprog calls, ldimm64, et al) during extra pass */ 27 - static int bpf_jit_fixup_addresses(struct bpf_prog *fp, u32 *image, 28 - struct codegen_context *ctx, u32 *addrs) 29 - { 30 - const struct bpf_insn *insn = fp->insnsi; 31 - bool func_addr_fixed; 32 - u64 func_addr; 33 - u32 tmp_idx; 34 - int i, j, ret; 35 - 36 - for (i = 0; i < fp->len; i++) { 37 - /* 38 - * During the extra pass, only the branch target addresses for 39 - * the subprog calls need to be fixed. All other instructions 40 - * can left untouched. 41 - * 42 - * The JITed image length does not change because we already 43 - * ensure that the JITed instruction sequence for these calls 44 - * are of fixed length by padding them with NOPs. 45 - */ 46 - if (insn[i].code == (BPF_JMP | BPF_CALL) && 47 - insn[i].src_reg == BPF_PSEUDO_CALL) { 48 - ret = bpf_jit_get_func_addr(fp, &insn[i], true, 49 - &func_addr, 50 - &func_addr_fixed); 51 - if (ret < 0) 52 - return ret; 53 - 54 - /* 55 - * Save ctx->idx as this would currently point to the 56 - * end of the JITed image and set it to the offset of 57 - * the instruction sequence corresponding to the 58 - * subprog call temporarily. 59 - */ 60 - tmp_idx = ctx->idx; 61 - ctx->idx = addrs[i] / 4; 62 - ret = bpf_jit_emit_func_call_rel(image, ctx, func_addr); 63 - if (ret) 64 - return ret; 65 - 66 - /* 67 - * Restore ctx->idx here. This is safe as the length 68 - * of the JITed sequence remains unchanged. 69 - */ 70 - ctx->idx = tmp_idx; 71 - } else if (insn[i].code == (BPF_LD | BPF_IMM | BPF_DW)) { 72 - tmp_idx = ctx->idx; 73 - ctx->idx = addrs[i] / 4; 74 - #ifdef CONFIG_PPC32 75 - PPC_LI32(bpf_to_ppc(insn[i].dst_reg) - 1, (u32)insn[i + 1].imm); 76 - PPC_LI32(bpf_to_ppc(insn[i].dst_reg), (u32)insn[i].imm); 77 - for (j = ctx->idx - addrs[i] / 4; j < 4; j++) 78 - EMIT(PPC_RAW_NOP()); 79 - #else 80 - func_addr = ((u64)(u32)insn[i].imm) | (((u64)(u32)insn[i + 1].imm) << 32); 81 - PPC_LI64(bpf_to_ppc(insn[i].dst_reg), func_addr); 82 - /* overwrite rest with nops */ 83 - for (j = ctx->idx - addrs[i] / 4; j < 5; j++) 84 - EMIT(PPC_RAW_NOP()); 85 - #endif 86 - ctx->idx = tmp_idx; 87 - i++; 88 - } 89 - } 90 - 91 - return 0; 92 - } 93 - 94 26 int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr) 95 27 { 96 28 if (!exit_addr || is_offset_in_branch_range(exit_addr - (ctx->idx * 4))) { ··· 117 185 cgctx.stack_size = round_up(fp->aux->stack_depth, 16); 118 186 119 187 /* Scouting faux-generate pass 0 */ 120 - if (bpf_jit_build_body(fp, 0, &cgctx, addrs, 0)) { 188 + if (bpf_jit_build_body(fp, 0, &cgctx, addrs, 0, false)) { 121 189 /* We hit something illegal or unsupported. */ 122 190 fp = org_fp; 123 191 goto out_addrs; ··· 132 200 */ 133 201 if (cgctx.seen & SEEN_TAILCALL || !is_offset_in_branch_range((long)cgctx.idx * 4)) { 134 202 cgctx.idx = 0; 135 - if (bpf_jit_build_body(fp, 0, &cgctx, addrs, 0)) { 203 + if (bpf_jit_build_body(fp, 0, &cgctx, addrs, 0, false)) { 136 204 fp = org_fp; 137 205 goto out_addrs; 138 206 } ··· 166 234 skip_init_ctx: 167 235 code_base = (u32 *)(image + FUNCTION_DESCR_SIZE); 168 236 169 - if (extra_pass) { 170 - /* 171 - * Do not touch the prologue and epilogue as they will remain 172 - * unchanged. Only fix the branch target address for subprog 173 - * calls in the body, and ldimm64 instructions. 174 - * 175 - * This does not change the offsets and lengths of the subprog 176 - * call instruction sequences and hence, the size of the JITed 177 - * image as well. 178 - */ 179 - bpf_jit_fixup_addresses(fp, code_base, &cgctx, addrs); 180 - 181 - /* There is no need to perform the usual passes. */ 182 - goto skip_codegen_passes; 183 - } 184 - 185 237 /* Code generation passes 1-2 */ 186 238 for (pass = 1; pass < 3; pass++) { 187 239 /* Now build the prologue, body code & epilogue for real. */ 188 240 cgctx.idx = 0; 189 241 cgctx.alt_exit_addr = 0; 190 242 bpf_jit_build_prologue(code_base, &cgctx); 191 - if (bpf_jit_build_body(fp, code_base, &cgctx, addrs, pass)) { 243 + if (bpf_jit_build_body(fp, code_base, &cgctx, addrs, pass, extra_pass)) { 192 244 bpf_jit_binary_free(bpf_hdr); 193 245 fp = org_fp; 194 246 goto out_addrs; ··· 184 268 proglen - (cgctx.idx * 4), cgctx.seen); 185 269 } 186 270 187 - skip_codegen_passes: 188 271 if (bpf_jit_enable > 1) 189 272 /* 190 273 * Note that we output the base address of the code_base
+227 -173
arch/powerpc/net/bpf_jit_comp32.c
··· 79 79 #define SEEN_NVREG_FULL_MASK 0x0003ffff /* Non volatile registers r14-r31 */ 80 80 #define SEEN_NVREG_TEMP_MASK 0x00001e01 /* BPF_REG_5, BPF_REG_AX, TMP_REG */ 81 81 82 + static inline bool bpf_has_stack_frame(struct codegen_context *ctx) 83 + { 84 + /* 85 + * We only need a stack frame if: 86 + * - we call other functions (kernel helpers), or 87 + * - we use non volatile registers, or 88 + * - we use tail call counter 89 + * - the bpf program uses its stack area 90 + * The latter condition is deduced from the usage of BPF_REG_FP 91 + */ 92 + return ctx->seen & (SEEN_FUNC | SEEN_TAILCALL | SEEN_NVREG_FULL_MASK) || 93 + bpf_is_seen_register(ctx, bpf_to_ppc(BPF_REG_FP)); 94 + } 95 + 82 96 void bpf_jit_realloc_regs(struct codegen_context *ctx) 83 97 { 84 98 unsigned int nvreg_mask; ··· 128 114 int i; 129 115 130 116 /* Initialize tail_call_cnt, to be skipped if we do tail calls. */ 131 - EMIT(PPC_RAW_LI(_R4, 0)); 117 + if (ctx->seen & SEEN_TAILCALL) 118 + EMIT(PPC_RAW_LI(_R4, 0)); 119 + else 120 + EMIT(PPC_RAW_NOP()); 132 121 133 122 #define BPF_TAILCALL_PROLOGUE_SIZE 4 134 123 135 - EMIT(PPC_RAW_STWU(_R1, _R1, -BPF_PPC_STACKFRAME(ctx))); 124 + if (bpf_has_stack_frame(ctx)) 125 + EMIT(PPC_RAW_STWU(_R1, _R1, -BPF_PPC_STACKFRAME(ctx))); 136 126 137 127 if (ctx->seen & SEEN_TAILCALL) 138 128 EMIT(PPC_RAW_STW(_R4, _R1, bpf_jit_stack_offsetof(ctx, BPF_PPC_TC))); ··· 158 140 for (i = BPF_PPC_NVR_MIN; i <= 31; i++) 159 141 if (bpf_is_seen_register(ctx, i)) 160 142 EMIT(PPC_RAW_STW(i, _R1, bpf_jit_stack_offsetof(ctx, i))); 161 - 162 - /* If needed retrieve arguments 9 and 10, ie 5th 64 bits arg.*/ 163 - if (bpf_is_seen_register(ctx, bpf_to_ppc(BPF_REG_5))) { 164 - EMIT(PPC_RAW_LWZ(bpf_to_ppc(BPF_REG_5) - 1, _R1, BPF_PPC_STACKFRAME(ctx)) + 8); 165 - EMIT(PPC_RAW_LWZ(bpf_to_ppc(BPF_REG_5), _R1, BPF_PPC_STACKFRAME(ctx)) + 12); 166 - } 167 143 168 144 /* Setup frame pointer to point to the bpf stack area */ 169 145 if (bpf_is_seen_register(ctx, bpf_to_ppc(BPF_REG_FP))) { ··· 183 171 EMIT(PPC_RAW_LWZ(_R0, _R1, BPF_PPC_STACKFRAME(ctx) + PPC_LR_STKOFF)); 184 172 185 173 /* Tear down our stack frame */ 186 - EMIT(PPC_RAW_ADDI(_R1, _R1, BPF_PPC_STACKFRAME(ctx))); 174 + if (bpf_has_stack_frame(ctx)) 175 + EMIT(PPC_RAW_ADDI(_R1, _R1, BPF_PPC_STACKFRAME(ctx))); 187 176 188 177 if (ctx->seen & SEEN_FUNC) 189 178 EMIT(PPC_RAW_MTLR(_R0)); ··· 206 193 207 194 if (image && rel < 0x2000000 && rel >= -0x2000000) { 208 195 PPC_BL(func); 209 - EMIT(PPC_RAW_NOP()); 210 - EMIT(PPC_RAW_NOP()); 211 - EMIT(PPC_RAW_NOP()); 212 196 } else { 213 197 /* Load function address into r0 */ 214 198 EMIT(PPC_RAW_LIS(_R0, IMM_H(func))); ··· 279 269 280 270 /* Assemble the body code between the prologue & epilogue */ 281 271 int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *ctx, 282 - u32 *addrs, int pass) 272 + u32 *addrs, int pass, bool extra_pass) 283 273 { 284 274 const struct bpf_insn *insn = fp->insnsi; 285 275 int flen = fp->len; ··· 290 280 291 281 for (i = 0; i < flen; i++) { 292 282 u32 code = insn[i].code; 283 + u32 prevcode = i ? insn[i - 1].code : 0; 293 284 u32 dst_reg = bpf_to_ppc(insn[i].dst_reg); 294 285 u32 dst_reg_h = dst_reg - 1; 295 286 u32 src_reg = bpf_to_ppc(insn[i].src_reg); 296 287 u32 src_reg_h = src_reg - 1; 288 + u32 src2_reg = dst_reg; 289 + u32 src2_reg_h = dst_reg_h; 297 290 u32 ax_reg = bpf_to_ppc(BPF_REG_AX); 298 291 u32 tmp_reg = bpf_to_ppc(TMP_REG); 299 292 u32 size = BPF_SIZE(code); ··· 308 295 u32 true_cond; 309 296 u32 tmp_idx; 310 297 int j; 298 + 299 + if (i && (BPF_CLASS(code) == BPF_ALU64 || BPF_CLASS(code) == BPF_ALU) && 300 + (BPF_CLASS(prevcode) == BPF_ALU64 || BPF_CLASS(prevcode) == BPF_ALU) && 301 + BPF_OP(prevcode) == BPF_MOV && BPF_SRC(prevcode) == BPF_X && 302 + insn[i - 1].dst_reg == insn[i].dst_reg && insn[i - 1].imm != 1) { 303 + src2_reg = bpf_to_ppc(insn[i - 1].src_reg); 304 + src2_reg_h = src2_reg - 1; 305 + ctx->idx = addrs[i - 1] / 4; 306 + } 311 307 312 308 /* 313 309 * addrs[] maps a BPF bytecode address into a real offset from ··· 350 328 * Arithmetic operations: ADD/SUB/MUL/DIV/MOD/NEG 351 329 */ 352 330 case BPF_ALU | BPF_ADD | BPF_X: /* (u32) dst += (u32) src */ 353 - EMIT(PPC_RAW_ADD(dst_reg, dst_reg, src_reg)); 331 + EMIT(PPC_RAW_ADD(dst_reg, src2_reg, src_reg)); 354 332 break; 355 333 case BPF_ALU64 | BPF_ADD | BPF_X: /* dst += src */ 356 - EMIT(PPC_RAW_ADDC(dst_reg, dst_reg, src_reg)); 357 - EMIT(PPC_RAW_ADDE(dst_reg_h, dst_reg_h, src_reg_h)); 334 + EMIT(PPC_RAW_ADDC(dst_reg, src2_reg, src_reg)); 335 + EMIT(PPC_RAW_ADDE(dst_reg_h, src2_reg_h, src_reg_h)); 358 336 break; 359 337 case BPF_ALU | BPF_SUB | BPF_X: /* (u32) dst -= (u32) src */ 360 - EMIT(PPC_RAW_SUB(dst_reg, dst_reg, src_reg)); 338 + EMIT(PPC_RAW_SUB(dst_reg, src2_reg, src_reg)); 361 339 break; 362 340 case BPF_ALU64 | BPF_SUB | BPF_X: /* dst -= src */ 363 - EMIT(PPC_RAW_SUBFC(dst_reg, src_reg, dst_reg)); 364 - EMIT(PPC_RAW_SUBFE(dst_reg_h, src_reg_h, dst_reg_h)); 341 + EMIT(PPC_RAW_SUBFC(dst_reg, src_reg, src2_reg)); 342 + EMIT(PPC_RAW_SUBFE(dst_reg_h, src_reg_h, src2_reg_h)); 365 343 break; 366 344 case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */ 367 345 imm = -imm; 368 346 fallthrough; 369 347 case BPF_ALU | BPF_ADD | BPF_K: /* (u32) dst += (u32) imm */ 370 - if (IMM_HA(imm) & 0xffff) 371 - EMIT(PPC_RAW_ADDIS(dst_reg, dst_reg, IMM_HA(imm))); 348 + if (!imm) { 349 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 350 + } else if (IMM_HA(imm) & 0xffff) { 351 + EMIT(PPC_RAW_ADDIS(dst_reg, src2_reg, IMM_HA(imm))); 352 + src2_reg = dst_reg; 353 + } 372 354 if (IMM_L(imm)) 373 - EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm))); 355 + EMIT(PPC_RAW_ADDI(dst_reg, src2_reg, IMM_L(imm))); 374 356 break; 375 357 case BPF_ALU64 | BPF_SUB | BPF_K: /* dst -= imm */ 376 358 imm = -imm; 377 359 fallthrough; 378 360 case BPF_ALU64 | BPF_ADD | BPF_K: /* dst += imm */ 379 - if (!imm) 361 + if (!imm) { 362 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 363 + EMIT(PPC_RAW_MR(dst_reg_h, src2_reg_h)); 380 364 break; 381 - 365 + } 382 366 if (imm >= -32768 && imm < 32768) { 383 - EMIT(PPC_RAW_ADDIC(dst_reg, dst_reg, imm)); 367 + EMIT(PPC_RAW_ADDIC(dst_reg, src2_reg, imm)); 384 368 } else { 385 369 PPC_LI32(_R0, imm); 386 - EMIT(PPC_RAW_ADDC(dst_reg, dst_reg, _R0)); 370 + EMIT(PPC_RAW_ADDC(dst_reg, src2_reg, _R0)); 387 371 } 388 372 if (imm >= 0 || (BPF_OP(code) == BPF_SUB && imm == 0x80000000)) 389 - EMIT(PPC_RAW_ADDZE(dst_reg_h, dst_reg_h)); 373 + EMIT(PPC_RAW_ADDZE(dst_reg_h, src2_reg_h)); 390 374 else 391 - EMIT(PPC_RAW_ADDME(dst_reg_h, dst_reg_h)); 375 + EMIT(PPC_RAW_ADDME(dst_reg_h, src2_reg_h)); 392 376 break; 393 377 case BPF_ALU64 | BPF_MUL | BPF_X: /* dst *= src */ 394 378 bpf_set_seen_register(ctx, tmp_reg); 395 - EMIT(PPC_RAW_MULW(_R0, dst_reg, src_reg_h)); 396 - EMIT(PPC_RAW_MULW(dst_reg_h, dst_reg_h, src_reg)); 397 - EMIT(PPC_RAW_MULHWU(tmp_reg, dst_reg, src_reg)); 398 - EMIT(PPC_RAW_MULW(dst_reg, dst_reg, src_reg)); 379 + EMIT(PPC_RAW_MULW(_R0, src2_reg, src_reg_h)); 380 + EMIT(PPC_RAW_MULW(dst_reg_h, src2_reg_h, src_reg)); 381 + EMIT(PPC_RAW_MULHWU(tmp_reg, src2_reg, src_reg)); 382 + EMIT(PPC_RAW_MULW(dst_reg, src2_reg, src_reg)); 399 383 EMIT(PPC_RAW_ADD(dst_reg_h, dst_reg_h, _R0)); 400 384 EMIT(PPC_RAW_ADD(dst_reg_h, dst_reg_h, tmp_reg)); 401 385 break; 402 386 case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */ 403 - EMIT(PPC_RAW_MULW(dst_reg, dst_reg, src_reg)); 387 + EMIT(PPC_RAW_MULW(dst_reg, src2_reg, src_reg)); 404 388 break; 405 389 case BPF_ALU | BPF_MUL | BPF_K: /* (u32) dst *= (u32) imm */ 406 - if (imm >= -32768 && imm < 32768) { 407 - EMIT(PPC_RAW_MULI(dst_reg, dst_reg, imm)); 390 + if (imm == 1) { 391 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 392 + } else if (imm == -1) { 393 + EMIT(PPC_RAW_SUBFIC(dst_reg, src2_reg, 0)); 394 + } else if (is_power_of_2((u32)imm)) { 395 + EMIT(PPC_RAW_SLWI(dst_reg, src2_reg, ilog2(imm))); 396 + } else if (imm >= -32768 && imm < 32768) { 397 + EMIT(PPC_RAW_MULI(dst_reg, src2_reg, imm)); 408 398 } else { 409 399 PPC_LI32(_R0, imm); 410 - EMIT(PPC_RAW_MULW(dst_reg, dst_reg, _R0)); 400 + EMIT(PPC_RAW_MULW(dst_reg, src2_reg, _R0)); 411 401 } 412 402 break; 413 403 case BPF_ALU64 | BPF_MUL | BPF_K: /* dst *= imm */ 414 404 if (!imm) { 415 405 PPC_LI32(dst_reg, 0); 416 406 PPC_LI32(dst_reg_h, 0); 417 - break; 407 + } else if (imm == 1) { 408 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 409 + EMIT(PPC_RAW_MR(dst_reg_h, src2_reg_h)); 410 + } else if (imm == -1) { 411 + EMIT(PPC_RAW_SUBFIC(dst_reg, src2_reg, 0)); 412 + EMIT(PPC_RAW_SUBFZE(dst_reg_h, src2_reg_h)); 413 + } else if (imm > 0 && is_power_of_2(imm)) { 414 + imm = ilog2(imm); 415 + EMIT(PPC_RAW_RLWINM(dst_reg_h, src2_reg_h, imm, 0, 31 - imm)); 416 + EMIT(PPC_RAW_RLWIMI(dst_reg_h, dst_reg, imm, 32 - imm, 31)); 417 + EMIT(PPC_RAW_SLWI(dst_reg, src2_reg, imm)); 418 + } else { 419 + bpf_set_seen_register(ctx, tmp_reg); 420 + PPC_LI32(tmp_reg, imm); 421 + EMIT(PPC_RAW_MULW(dst_reg_h, src2_reg_h, tmp_reg)); 422 + if (imm < 0) 423 + EMIT(PPC_RAW_SUB(dst_reg_h, dst_reg_h, src2_reg)); 424 + EMIT(PPC_RAW_MULHWU(_R0, src2_reg, tmp_reg)); 425 + EMIT(PPC_RAW_MULW(dst_reg, src2_reg, tmp_reg)); 426 + EMIT(PPC_RAW_ADD(dst_reg_h, dst_reg_h, _R0)); 418 427 } 419 - if (imm == 1) 420 - break; 421 - if (imm == -1) { 422 - EMIT(PPC_RAW_SUBFIC(dst_reg, dst_reg, 0)); 423 - EMIT(PPC_RAW_SUBFZE(dst_reg_h, dst_reg_h)); 424 - break; 425 - } 426 - bpf_set_seen_register(ctx, tmp_reg); 427 - PPC_LI32(tmp_reg, imm); 428 - EMIT(PPC_RAW_MULW(dst_reg_h, dst_reg_h, tmp_reg)); 429 - if (imm < 0) 430 - EMIT(PPC_RAW_SUB(dst_reg_h, dst_reg_h, dst_reg)); 431 - EMIT(PPC_RAW_MULHWU(_R0, dst_reg, tmp_reg)); 432 - EMIT(PPC_RAW_MULW(dst_reg, dst_reg, tmp_reg)); 433 - EMIT(PPC_RAW_ADD(dst_reg_h, dst_reg_h, _R0)); 434 428 break; 435 429 case BPF_ALU | BPF_DIV | BPF_X: /* (u32) dst /= (u32) src */ 436 - EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, src_reg)); 430 + EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, src_reg)); 437 431 break; 438 432 case BPF_ALU | BPF_MOD | BPF_X: /* (u32) dst %= (u32) src */ 439 - EMIT(PPC_RAW_DIVWU(_R0, dst_reg, src_reg)); 433 + EMIT(PPC_RAW_DIVWU(_R0, src2_reg, src_reg)); 440 434 EMIT(PPC_RAW_MULW(_R0, src_reg, _R0)); 441 - EMIT(PPC_RAW_SUB(dst_reg, dst_reg, _R0)); 435 + EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0)); 442 436 break; 443 437 case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */ 444 438 return -EOPNOTSUPP; ··· 463 425 case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */ 464 426 if (!imm) 465 427 return -EINVAL; 466 - if (imm == 1) 467 - break; 468 - 469 - PPC_LI32(_R0, imm); 470 - EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, _R0)); 428 + if (imm == 1) { 429 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 430 + } else if (is_power_of_2((u32)imm)) { 431 + EMIT(PPC_RAW_SRWI(dst_reg, src2_reg, ilog2(imm))); 432 + } else { 433 + PPC_LI32(_R0, imm); 434 + EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, _R0)); 435 + } 471 436 break; 472 437 case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */ 473 438 if (!imm) ··· 479 438 if (!is_power_of_2((u32)imm)) { 480 439 bpf_set_seen_register(ctx, tmp_reg); 481 440 PPC_LI32(tmp_reg, imm); 482 - EMIT(PPC_RAW_DIVWU(_R0, dst_reg, tmp_reg)); 441 + EMIT(PPC_RAW_DIVWU(_R0, src2_reg, tmp_reg)); 483 442 EMIT(PPC_RAW_MULW(_R0, tmp_reg, _R0)); 484 - EMIT(PPC_RAW_SUB(dst_reg, dst_reg, _R0)); 485 - break; 486 - } 487 - if (imm == 1) 443 + EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0)); 444 + } else if (imm == 1) { 488 445 EMIT(PPC_RAW_LI(dst_reg, 0)); 489 - else 490 - EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 32 - ilog2((u32)imm), 31)); 491 - 446 + } else { 447 + imm = ilog2((u32)imm); 448 + EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 0, 32 - imm, 31)); 449 + } 492 450 break; 493 451 case BPF_ALU64 | BPF_MOD | BPF_K: /* dst %= imm */ 494 452 if (!imm) ··· 499 459 if (imm == 1) 500 460 EMIT(PPC_RAW_LI(dst_reg, 0)); 501 461 else 502 - EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 32 - ilog2(imm), 31)); 462 + EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 0, 32 - ilog2(imm), 31)); 503 463 EMIT(PPC_RAW_LI(dst_reg_h, 0)); 504 464 break; 505 465 case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */ ··· 509 469 return -EOPNOTSUPP; 510 470 511 471 if (imm < 0) { 512 - EMIT(PPC_RAW_SUBFIC(dst_reg, dst_reg, 0)); 513 - EMIT(PPC_RAW_SUBFZE(dst_reg_h, dst_reg_h)); 472 + EMIT(PPC_RAW_SUBFIC(dst_reg, src2_reg, 0)); 473 + EMIT(PPC_RAW_SUBFZE(dst_reg_h, src2_reg_h)); 514 474 imm = -imm; 475 + src2_reg = dst_reg; 515 476 } 516 - if (imm == 1) 517 - break; 518 - imm = ilog2(imm); 519 - EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 32 - imm, imm, 31)); 520 - EMIT(PPC_RAW_RLWIMI(dst_reg, dst_reg_h, 32 - imm, 0, imm - 1)); 521 - EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg_h, imm)); 477 + if (imm == 1) { 478 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 479 + EMIT(PPC_RAW_MR(dst_reg_h, src2_reg_h)); 480 + } else { 481 + imm = ilog2(imm); 482 + EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 32 - imm, imm, 31)); 483 + EMIT(PPC_RAW_RLWIMI(dst_reg, src2_reg_h, 32 - imm, 0, imm - 1)); 484 + EMIT(PPC_RAW_SRAWI(dst_reg_h, src2_reg_h, imm)); 485 + } 522 486 break; 523 487 case BPF_ALU | BPF_NEG: /* (u32) dst = -dst */ 524 - EMIT(PPC_RAW_NEG(dst_reg, dst_reg)); 488 + EMIT(PPC_RAW_NEG(dst_reg, src2_reg)); 525 489 break; 526 490 case BPF_ALU64 | BPF_NEG: /* dst = -dst */ 527 - EMIT(PPC_RAW_SUBFIC(dst_reg, dst_reg, 0)); 528 - EMIT(PPC_RAW_SUBFZE(dst_reg_h, dst_reg_h)); 491 + EMIT(PPC_RAW_SUBFIC(dst_reg, src2_reg, 0)); 492 + EMIT(PPC_RAW_SUBFZE(dst_reg_h, src2_reg_h)); 529 493 break; 530 494 531 495 /* 532 496 * Logical operations: AND/OR/XOR/[A]LSH/[A]RSH 533 497 */ 534 498 case BPF_ALU64 | BPF_AND | BPF_X: /* dst = dst & src */ 535 - EMIT(PPC_RAW_AND(dst_reg, dst_reg, src_reg)); 536 - EMIT(PPC_RAW_AND(dst_reg_h, dst_reg_h, src_reg_h)); 499 + EMIT(PPC_RAW_AND(dst_reg, src2_reg, src_reg)); 500 + EMIT(PPC_RAW_AND(dst_reg_h, src2_reg_h, src_reg_h)); 537 501 break; 538 502 case BPF_ALU | BPF_AND | BPF_X: /* (u32) dst = dst & src */ 539 - EMIT(PPC_RAW_AND(dst_reg, dst_reg, src_reg)); 503 + EMIT(PPC_RAW_AND(dst_reg, src2_reg, src_reg)); 540 504 break; 541 505 case BPF_ALU64 | BPF_AND | BPF_K: /* dst = dst & imm */ 542 506 if (imm >= 0) ··· 548 504 fallthrough; 549 505 case BPF_ALU | BPF_AND | BPF_K: /* (u32) dst = dst & imm */ 550 506 if (!IMM_H(imm)) { 551 - EMIT(PPC_RAW_ANDI(dst_reg, dst_reg, IMM_L(imm))); 507 + EMIT(PPC_RAW_ANDI(dst_reg, src2_reg, IMM_L(imm))); 552 508 } else if (!IMM_L(imm)) { 553 - EMIT(PPC_RAW_ANDIS(dst_reg, dst_reg, IMM_H(imm))); 509 + EMIT(PPC_RAW_ANDIS(dst_reg, src2_reg, IMM_H(imm))); 554 510 } else if (imm == (((1 << fls(imm)) - 1) ^ ((1 << (ffs(i) - 1)) - 1))) { 555 - EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 511 + EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 0, 556 512 32 - fls(imm), 32 - ffs(imm))); 557 513 } else { 558 514 PPC_LI32(_R0, imm); 559 - EMIT(PPC_RAW_AND(dst_reg, dst_reg, _R0)); 515 + EMIT(PPC_RAW_AND(dst_reg, src2_reg, _R0)); 560 516 } 561 517 break; 562 518 case BPF_ALU64 | BPF_OR | BPF_X: /* dst = dst | src */ 563 - EMIT(PPC_RAW_OR(dst_reg, dst_reg, src_reg)); 564 - EMIT(PPC_RAW_OR(dst_reg_h, dst_reg_h, src_reg_h)); 519 + EMIT(PPC_RAW_OR(dst_reg, src2_reg, src_reg)); 520 + EMIT(PPC_RAW_OR(dst_reg_h, src2_reg_h, src_reg_h)); 565 521 break; 566 522 case BPF_ALU | BPF_OR | BPF_X: /* dst = (u32) dst | (u32) src */ 567 - EMIT(PPC_RAW_OR(dst_reg, dst_reg, src_reg)); 523 + EMIT(PPC_RAW_OR(dst_reg, src2_reg, src_reg)); 568 524 break; 569 525 case BPF_ALU64 | BPF_OR | BPF_K:/* dst = dst | imm */ 570 526 /* Sign-extended */ ··· 572 528 EMIT(PPC_RAW_LI(dst_reg_h, -1)); 573 529 fallthrough; 574 530 case BPF_ALU | BPF_OR | BPF_K:/* dst = (u32) dst | (u32) imm */ 575 - if (IMM_L(imm)) 576 - EMIT(PPC_RAW_ORI(dst_reg, dst_reg, IMM_L(imm))); 531 + if (IMM_L(imm)) { 532 + EMIT(PPC_RAW_ORI(dst_reg, src2_reg, IMM_L(imm))); 533 + src2_reg = dst_reg; 534 + } 577 535 if (IMM_H(imm)) 578 - EMIT(PPC_RAW_ORIS(dst_reg, dst_reg, IMM_H(imm))); 536 + EMIT(PPC_RAW_ORIS(dst_reg, src2_reg, IMM_H(imm))); 579 537 break; 580 538 case BPF_ALU64 | BPF_XOR | BPF_X: /* dst ^= src */ 581 539 if (dst_reg == src_reg) { 582 540 EMIT(PPC_RAW_LI(dst_reg, 0)); 583 541 EMIT(PPC_RAW_LI(dst_reg_h, 0)); 584 542 } else { 585 - EMIT(PPC_RAW_XOR(dst_reg, dst_reg, src_reg)); 586 - EMIT(PPC_RAW_XOR(dst_reg_h, dst_reg_h, src_reg_h)); 543 + EMIT(PPC_RAW_XOR(dst_reg, src2_reg, src_reg)); 544 + EMIT(PPC_RAW_XOR(dst_reg_h, src2_reg_h, src_reg_h)); 587 545 } 588 546 break; 589 547 case BPF_ALU | BPF_XOR | BPF_X: /* (u32) dst ^= src */ 590 548 if (dst_reg == src_reg) 591 549 EMIT(PPC_RAW_LI(dst_reg, 0)); 592 550 else 593 - EMIT(PPC_RAW_XOR(dst_reg, dst_reg, src_reg)); 551 + EMIT(PPC_RAW_XOR(dst_reg, src2_reg, src_reg)); 594 552 break; 595 553 case BPF_ALU64 | BPF_XOR | BPF_K: /* dst ^= imm */ 596 554 if (imm < 0) 597 - EMIT(PPC_RAW_NOR(dst_reg_h, dst_reg_h, dst_reg_h)); 555 + EMIT(PPC_RAW_NOR(dst_reg_h, src2_reg_h, src2_reg_h)); 598 556 fallthrough; 599 557 case BPF_ALU | BPF_XOR | BPF_K: /* (u32) dst ^= (u32) imm */ 600 - if (IMM_L(imm)) 601 - EMIT(PPC_RAW_XORI(dst_reg, dst_reg, IMM_L(imm))); 558 + if (IMM_L(imm)) { 559 + EMIT(PPC_RAW_XORI(dst_reg, src2_reg, IMM_L(imm))); 560 + src2_reg = dst_reg; 561 + } 602 562 if (IMM_H(imm)) 603 - EMIT(PPC_RAW_XORIS(dst_reg, dst_reg, IMM_H(imm))); 563 + EMIT(PPC_RAW_XORIS(dst_reg, src2_reg, IMM_H(imm))); 604 564 break; 605 565 case BPF_ALU | BPF_LSH | BPF_X: /* (u32) dst <<= (u32) src */ 606 - EMIT(PPC_RAW_SLW(dst_reg, dst_reg, src_reg)); 566 + EMIT(PPC_RAW_SLW(dst_reg, src2_reg, src_reg)); 607 567 break; 608 568 case BPF_ALU64 | BPF_LSH | BPF_X: /* dst <<= src; */ 609 569 bpf_set_seen_register(ctx, tmp_reg); 610 570 EMIT(PPC_RAW_SUBFIC(_R0, src_reg, 32)); 611 - EMIT(PPC_RAW_SLW(dst_reg_h, dst_reg_h, src_reg)); 571 + EMIT(PPC_RAW_SLW(dst_reg_h, src2_reg_h, src_reg)); 612 572 EMIT(PPC_RAW_ADDI(tmp_reg, src_reg, 32)); 613 - EMIT(PPC_RAW_SRW(_R0, dst_reg, _R0)); 614 - EMIT(PPC_RAW_SLW(tmp_reg, dst_reg, tmp_reg)); 573 + EMIT(PPC_RAW_SRW(_R0, src2_reg, _R0)); 574 + EMIT(PPC_RAW_SLW(tmp_reg, src2_reg, tmp_reg)); 615 575 EMIT(PPC_RAW_OR(dst_reg_h, dst_reg_h, _R0)); 616 - EMIT(PPC_RAW_SLW(dst_reg, dst_reg, src_reg)); 576 + EMIT(PPC_RAW_SLW(dst_reg, src2_reg, src_reg)); 617 577 EMIT(PPC_RAW_OR(dst_reg_h, dst_reg_h, tmp_reg)); 618 578 break; 619 579 case BPF_ALU | BPF_LSH | BPF_K: /* (u32) dst <<= (u32) imm */ 620 - if (!imm) 621 - break; 622 - EMIT(PPC_RAW_SLWI(dst_reg, dst_reg, imm)); 580 + if (imm) 581 + EMIT(PPC_RAW_SLWI(dst_reg, src2_reg, imm)); 582 + else 583 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 623 584 break; 624 585 case BPF_ALU64 | BPF_LSH | BPF_K: /* dst <<= imm */ 625 586 if (imm < 0) 626 587 return -EINVAL; 627 - if (!imm) 628 - break; 629 - if (imm < 32) { 630 - EMIT(PPC_RAW_RLWINM(dst_reg_h, dst_reg_h, imm, 0, 31 - imm)); 631 - EMIT(PPC_RAW_RLWIMI(dst_reg_h, dst_reg, imm, 32 - imm, 31)); 632 - EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, imm, 0, 31 - imm)); 633 - break; 634 - } 635 - if (imm < 64) 636 - EMIT(PPC_RAW_RLWINM(dst_reg_h, dst_reg, imm, 0, 31 - imm)); 637 - else 588 + if (!imm) { 589 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 590 + } else if (imm < 32) { 591 + EMIT(PPC_RAW_RLWINM(dst_reg_h, src2_reg_h, imm, 0, 31 - imm)); 592 + EMIT(PPC_RAW_RLWIMI(dst_reg_h, src2_reg, imm, 32 - imm, 31)); 593 + EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, imm, 0, 31 - imm)); 594 + } else if (imm < 64) { 595 + EMIT(PPC_RAW_RLWINM(dst_reg_h, src2_reg, imm, 0, 31 - imm)); 596 + EMIT(PPC_RAW_LI(dst_reg, 0)); 597 + } else { 638 598 EMIT(PPC_RAW_LI(dst_reg_h, 0)); 639 - EMIT(PPC_RAW_LI(dst_reg, 0)); 599 + EMIT(PPC_RAW_LI(dst_reg, 0)); 600 + } 640 601 break; 641 602 case BPF_ALU | BPF_RSH | BPF_X: /* (u32) dst >>= (u32) src */ 642 - EMIT(PPC_RAW_SRW(dst_reg, dst_reg, src_reg)); 603 + EMIT(PPC_RAW_SRW(dst_reg, src2_reg, src_reg)); 643 604 break; 644 605 case BPF_ALU64 | BPF_RSH | BPF_X: /* dst >>= src */ 645 606 bpf_set_seen_register(ctx, tmp_reg); 646 607 EMIT(PPC_RAW_SUBFIC(_R0, src_reg, 32)); 647 - EMIT(PPC_RAW_SRW(dst_reg, dst_reg, src_reg)); 608 + EMIT(PPC_RAW_SRW(dst_reg, src2_reg, src_reg)); 648 609 EMIT(PPC_RAW_ADDI(tmp_reg, src_reg, 32)); 649 - EMIT(PPC_RAW_SLW(_R0, dst_reg_h, _R0)); 610 + EMIT(PPC_RAW_SLW(_R0, src2_reg_h, _R0)); 650 611 EMIT(PPC_RAW_SRW(tmp_reg, dst_reg_h, tmp_reg)); 651 612 EMIT(PPC_RAW_OR(dst_reg, dst_reg, _R0)); 652 - EMIT(PPC_RAW_SRW(dst_reg_h, dst_reg_h, src_reg)); 613 + EMIT(PPC_RAW_SRW(dst_reg_h, src2_reg_h, src_reg)); 653 614 EMIT(PPC_RAW_OR(dst_reg, dst_reg, tmp_reg)); 654 615 break; 655 616 case BPF_ALU | BPF_RSH | BPF_K: /* (u32) dst >>= (u32) imm */ 656 - if (!imm) 657 - break; 658 - EMIT(PPC_RAW_SRWI(dst_reg, dst_reg, imm)); 617 + if (imm) 618 + EMIT(PPC_RAW_SRWI(dst_reg, src2_reg, imm)); 619 + else 620 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 659 621 break; 660 622 case BPF_ALU64 | BPF_RSH | BPF_K: /* dst >>= imm */ 661 623 if (imm < 0) 662 624 return -EINVAL; 663 - if (!imm) 664 - break; 665 - if (imm < 32) { 666 - EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 32 - imm, imm, 31)); 667 - EMIT(PPC_RAW_RLWIMI(dst_reg, dst_reg_h, 32 - imm, 0, imm - 1)); 668 - EMIT(PPC_RAW_RLWINM(dst_reg_h, dst_reg_h, 32 - imm, imm, 31)); 669 - break; 670 - } 671 - if (imm < 64) 672 - EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg_h, 64 - imm, imm - 32, 31)); 673 - else 625 + if (!imm) { 626 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 627 + EMIT(PPC_RAW_MR(dst_reg_h, src2_reg_h)); 628 + } else if (imm < 32) { 629 + EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 32 - imm, imm, 31)); 630 + EMIT(PPC_RAW_RLWIMI(dst_reg, src2_reg_h, 32 - imm, 0, imm - 1)); 631 + EMIT(PPC_RAW_RLWINM(dst_reg_h, src2_reg_h, 32 - imm, imm, 31)); 632 + } else if (imm < 64) { 633 + EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg_h, 64 - imm, imm - 32, 31)); 634 + EMIT(PPC_RAW_LI(dst_reg_h, 0)); 635 + } else { 674 636 EMIT(PPC_RAW_LI(dst_reg, 0)); 675 - EMIT(PPC_RAW_LI(dst_reg_h, 0)); 637 + EMIT(PPC_RAW_LI(dst_reg_h, 0)); 638 + } 676 639 break; 677 640 case BPF_ALU | BPF_ARSH | BPF_X: /* (s32) dst >>= src */ 678 - EMIT(PPC_RAW_SRAW(dst_reg, dst_reg, src_reg)); 641 + EMIT(PPC_RAW_SRAW(dst_reg, src2_reg, src_reg)); 679 642 break; 680 643 case BPF_ALU64 | BPF_ARSH | BPF_X: /* (s64) dst >>= src */ 681 644 bpf_set_seen_register(ctx, tmp_reg); 682 645 EMIT(PPC_RAW_SUBFIC(_R0, src_reg, 32)); 683 - EMIT(PPC_RAW_SRW(dst_reg, dst_reg, src_reg)); 684 - EMIT(PPC_RAW_SLW(_R0, dst_reg_h, _R0)); 646 + EMIT(PPC_RAW_SRW(dst_reg, src2_reg, src_reg)); 647 + EMIT(PPC_RAW_SLW(_R0, src2_reg_h, _R0)); 685 648 EMIT(PPC_RAW_ADDI(tmp_reg, src_reg, 32)); 686 649 EMIT(PPC_RAW_OR(dst_reg, dst_reg, _R0)); 687 650 EMIT(PPC_RAW_RLWINM(_R0, tmp_reg, 0, 26, 26)); 688 - EMIT(PPC_RAW_SRAW(tmp_reg, dst_reg_h, tmp_reg)); 689 - EMIT(PPC_RAW_SRAW(dst_reg_h, dst_reg_h, src_reg)); 651 + EMIT(PPC_RAW_SRAW(tmp_reg, src2_reg_h, tmp_reg)); 652 + EMIT(PPC_RAW_SRAW(dst_reg_h, src2_reg_h, src_reg)); 690 653 EMIT(PPC_RAW_SLW(tmp_reg, tmp_reg, _R0)); 691 654 EMIT(PPC_RAW_OR(dst_reg, dst_reg, tmp_reg)); 692 655 break; 693 656 case BPF_ALU | BPF_ARSH | BPF_K: /* (s32) dst >>= imm */ 694 - if (!imm) 695 - break; 696 - EMIT(PPC_RAW_SRAWI(dst_reg, dst_reg, imm)); 657 + if (imm) 658 + EMIT(PPC_RAW_SRAWI(dst_reg, src2_reg, imm)); 659 + else 660 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 697 661 break; 698 662 case BPF_ALU64 | BPF_ARSH | BPF_K: /* (s64) dst >>= imm */ 699 663 if (imm < 0) 700 664 return -EINVAL; 701 - if (!imm) 702 - break; 703 - if (imm < 32) { 704 - EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 32 - imm, imm, 31)); 705 - EMIT(PPC_RAW_RLWIMI(dst_reg, dst_reg_h, 32 - imm, 0, imm - 1)); 706 - EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg_h, imm)); 707 - break; 665 + if (!imm) { 666 + EMIT(PPC_RAW_MR(dst_reg, src2_reg)); 667 + EMIT(PPC_RAW_MR(dst_reg_h, src2_reg_h)); 668 + } else if (imm < 32) { 669 + EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 32 - imm, imm, 31)); 670 + EMIT(PPC_RAW_RLWIMI(dst_reg, src2_reg_h, 32 - imm, 0, imm - 1)); 671 + EMIT(PPC_RAW_SRAWI(dst_reg_h, src2_reg_h, imm)); 672 + } else if (imm < 64) { 673 + EMIT(PPC_RAW_SRAWI(dst_reg, src2_reg_h, imm - 32)); 674 + EMIT(PPC_RAW_SRAWI(dst_reg_h, src2_reg_h, 31)); 675 + } else { 676 + EMIT(PPC_RAW_SRAWI(dst_reg, src2_reg_h, 31)); 677 + EMIT(PPC_RAW_SRAWI(dst_reg_h, src2_reg_h, 31)); 708 678 } 709 - if (imm < 64) 710 - EMIT(PPC_RAW_SRAWI(dst_reg, dst_reg_h, imm - 32)); 711 - else 712 - EMIT(PPC_RAW_SRAWI(dst_reg, dst_reg_h, 31)); 713 - EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg_h, 31)); 714 679 break; 715 680 716 681 /* ··· 753 700 switch (imm) { 754 701 case 16: 755 702 /* Copy 16 bits to upper part */ 756 - EMIT(PPC_RAW_RLWIMI(dst_reg, dst_reg, 16, 0, 15)); 703 + EMIT(PPC_RAW_RLWIMI(dst_reg, src2_reg, 16, 0, 15)); 757 704 /* Rotate 8 bits right & mask */ 758 705 EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 24, 16, 31)); 759 706 break; ··· 763 710 * 2 bytes are already in their final position 764 711 * -- byte 2 and 4 (of bytes 1, 2, 3 and 4) 765 712 */ 766 - EMIT(PPC_RAW_RLWINM(_R0, dst_reg, 8, 0, 31)); 713 + EMIT(PPC_RAW_RLWINM(_R0, src2_reg, 8, 0, 31)); 767 714 /* Rotate 24 bits and insert byte 1 */ 768 - EMIT(PPC_RAW_RLWIMI(_R0, dst_reg, 24, 0, 7)); 715 + EMIT(PPC_RAW_RLWIMI(_R0, src2_reg, 24, 0, 7)); 769 716 /* Rotate 24 bits and insert byte 3 */ 770 - EMIT(PPC_RAW_RLWIMI(_R0, dst_reg, 24, 16, 23)); 717 + EMIT(PPC_RAW_RLWIMI(_R0, src2_reg, 24, 16, 23)); 771 718 EMIT(PPC_RAW_MR(dst_reg, _R0)); 772 719 break; 773 720 case 64: 774 721 bpf_set_seen_register(ctx, tmp_reg); 775 - EMIT(PPC_RAW_RLWINM(tmp_reg, dst_reg, 8, 0, 31)); 776 - EMIT(PPC_RAW_RLWINM(_R0, dst_reg_h, 8, 0, 31)); 722 + EMIT(PPC_RAW_RLWINM(tmp_reg, src2_reg, 8, 0, 31)); 723 + EMIT(PPC_RAW_RLWINM(_R0, src2_reg_h, 8, 0, 31)); 777 724 /* Rotate 24 bits and insert byte 1 */ 778 - EMIT(PPC_RAW_RLWIMI(tmp_reg, dst_reg, 24, 0, 7)); 779 - EMIT(PPC_RAW_RLWIMI(_R0, dst_reg_h, 24, 0, 7)); 725 + EMIT(PPC_RAW_RLWIMI(tmp_reg, src2_reg, 24, 0, 7)); 726 + EMIT(PPC_RAW_RLWIMI(_R0, src2_reg_h, 24, 0, 7)); 780 727 /* Rotate 24 bits and insert byte 3 */ 781 - EMIT(PPC_RAW_RLWIMI(tmp_reg, dst_reg, 24, 16, 23)); 782 - EMIT(PPC_RAW_RLWIMI(_R0, dst_reg_h, 24, 16, 23)); 728 + EMIT(PPC_RAW_RLWIMI(tmp_reg, src2_reg, 24, 16, 23)); 729 + EMIT(PPC_RAW_RLWIMI(_R0, src2_reg_h, 24, 16, 23)); 783 730 EMIT(PPC_RAW_MR(dst_reg, _R0)); 784 731 EMIT(PPC_RAW_MR(dst_reg_h, tmp_reg)); 785 732 break; ··· 789 736 switch (imm) { 790 737 case 16: 791 738 /* zero-extend 16 bits into 32 bits */ 792 - EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 16, 31)); 739 + EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 0, 16, 31)); 793 740 break; 794 741 case 32: 795 742 case 64: ··· 1013 960 PPC_LI32(dst_reg_h, (u32)insn[i + 1].imm); 1014 961 PPC_LI32(dst_reg, (u32)insn[i].imm); 1015 962 /* padding to allow full 4 instructions for later patching */ 1016 - for (j = ctx->idx - tmp_idx; j < 4; j++) 1017 - EMIT(PPC_RAW_NOP()); 963 + if (!image) 964 + for (j = ctx->idx - tmp_idx; j < 4; j++) 965 + EMIT(PPC_RAW_NOP()); 1018 966 /* Adjust for two bpf instructions */ 1019 967 addrs[++i] = ctx->idx * 4; 1020 968 break; ··· 1043 989 case BPF_JMP | BPF_CALL: 1044 990 ctx->seen |= SEEN_FUNC; 1045 991 1046 - ret = bpf_jit_get_func_addr(fp, &insn[i], false, 992 + ret = bpf_jit_get_func_addr(fp, &insn[i], extra_pass, 1047 993 &func_addr, &func_addr_fixed); 1048 994 if (ret < 0) 1049 995 return ret;
+9 -7
arch/powerpc/net/bpf_jit_comp64.c
··· 240 240 * load the callee's address, but this may optimize the number of 241 241 * instructions required based on the nature of the address. 242 242 * 243 - * Since we don't want the number of instructions emitted to change, 243 + * Since we don't want the number of instructions emitted to increase, 244 244 * we pad the optimized PPC_LI64() call with NOPs to guarantee that 245 245 * we always have a five-instruction sequence, which is the maximum 246 246 * that PPC_LI64() can emit. 247 247 */ 248 - for (i = ctx->idx - ctx_idx; i < 5; i++) 249 - EMIT(PPC_RAW_NOP()); 248 + if (!image) 249 + for (i = ctx->idx - ctx_idx; i < 5; i++) 250 + EMIT(PPC_RAW_NOP()); 250 251 251 252 EMIT(PPC_RAW_MTCTR(_R12)); 252 253 EMIT(PPC_RAW_BCTRL()); ··· 344 343 345 344 /* Assemble the body code between the prologue & epilogue */ 346 345 int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *ctx, 347 - u32 *addrs, int pass) 346 + u32 *addrs, int pass, bool extra_pass) 348 347 { 349 348 enum stf_barrier_type stf_barrier = stf_barrier_type_get(); 350 349 const struct bpf_insn *insn = fp->insnsi; ··· 939 938 tmp_idx = ctx->idx; 940 939 PPC_LI64(dst_reg, imm64); 941 940 /* padding to allow full 5 instructions for later patching */ 942 - for (j = ctx->idx - tmp_idx; j < 5; j++) 943 - EMIT(PPC_RAW_NOP()); 941 + if (!image) 942 + for (j = ctx->idx - tmp_idx; j < 5; j++) 943 + EMIT(PPC_RAW_NOP()); 944 944 /* Adjust for two bpf instructions */ 945 945 addrs[++i] = ctx->idx * 4; 946 946 break; ··· 969 967 case BPF_JMP | BPF_CALL: 970 968 ctx->seen |= SEEN_FUNC; 971 969 972 - ret = bpf_jit_get_func_addr(fp, &insn[i], false, 970 + ret = bpf_jit_get_func_addr(fp, &insn[i], extra_pass, 973 971 &func_addr, &func_addr_fixed); 974 972 if (ret < 0) 975 973 return ret;
+16 -28
arch/powerpc/perf/hv-24x7.c
··· 18 18 #include <asm/firmware.h> 19 19 #include <asm/hvcall.h> 20 20 #include <asm/io.h> 21 + #include <asm/papr-sysparm.h> 21 22 #include <linux/byteorder/generic.h> 22 23 23 24 #include <asm/rtas.h> ··· 67 66 * Refer PAPR+ document to get parameter token value as '43'. 68 67 */ 69 68 70 - #define PROCESSOR_MODULE_INFO 43 71 - 72 69 static u32 phys_sockets; /* Physical sockets */ 73 70 static u32 phys_chipspersocket; /* Physical chips per socket*/ 74 71 static u32 phys_coresperchip; /* Physical cores per chip */ ··· 78 79 */ 79 80 void read_24x7_sys_info(void) 80 81 { 81 - int call_status, len, ntypes; 82 - 83 - spin_lock(&rtas_data_buf_lock); 82 + struct papr_sysparm_buf *buf; 84 83 85 84 /* 86 85 * Making system parameter: chips and sockets and cores per chip ··· 88 91 phys_chipspersocket = 1; 89 92 phys_coresperchip = 1; 90 93 91 - call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, 92 - NULL, 93 - PROCESSOR_MODULE_INFO, 94 - __pa(rtas_data_buf), 95 - RTAS_DATA_BUF_SIZE); 94 + buf = papr_sysparm_buf_alloc(); 95 + if (!buf) 96 + return; 96 97 97 - if (call_status != 0) { 98 - pr_err("Error calling get-system-parameter %d\n", 99 - call_status); 100 - } else { 101 - len = be16_to_cpup((__be16 *)&rtas_data_buf[0]); 102 - if (len < 8) 103 - goto out; 98 + if (!papr_sysparm_get(PAPR_SYSPARM_PROC_MODULE_INFO, buf)) { 99 + int ntypes = be16_to_cpup((__be16 *)&buf->val[0]); 100 + int len = be16_to_cpu(buf->len); 104 101 105 - ntypes = be16_to_cpup((__be16 *)&rtas_data_buf[2]); 106 - 107 - if (!ntypes) 108 - goto out; 109 - 110 - phys_sockets = be16_to_cpup((__be16 *)&rtas_data_buf[4]); 111 - phys_chipspersocket = be16_to_cpup((__be16 *)&rtas_data_buf[6]); 112 - phys_coresperchip = be16_to_cpup((__be16 *)&rtas_data_buf[8]); 102 + if (len >= 8 && ntypes != 0) { 103 + phys_sockets = be16_to_cpup((__be16 *)&buf->val[2]); 104 + phys_chipspersocket = be16_to_cpup((__be16 *)&buf->val[4]); 105 + phys_coresperchip = be16_to_cpup((__be16 *)&buf->val[6]); 106 + } 113 107 } 114 108 115 - out: 116 - spin_unlock(&rtas_data_buf_lock); 109 + papr_sysparm_buf_free(buf); 117 110 } 118 111 119 112 /* Domains for which more than one result element are returned for each event. */ ··· 1714 1727 } 1715 1728 1716 1729 /* POWER8 only supports v1, while POWER9 only supports v2. */ 1717 - if (PVR_VER(pvr) == PVR_POWER8) 1730 + if (PVR_VER(pvr) == PVR_POWER8 || PVR_VER(pvr) == PVR_POWER8E || 1731 + PVR_VER(pvr) == PVR_POWER8NVL) 1718 1732 interface_version = 1; 1719 1733 else { 1720 1734 interface_version = 2;
+1 -1
arch/powerpc/platforms/44x/fsp2.c
··· 205 205 206 206 for_each_compatible_node(np, NULL, compat) { 207 207 irq = irq_of_parse_and_map(np, 0); 208 - if (irq == NO_IRQ) { 208 + if (!irq) { 209 209 pr_err("device tree node %pOFn is missing a interrupt", 210 210 np); 211 211 of_node_put(np);
+2 -2
arch/powerpc/platforms/52xx/efika.c
··· 41 41 int ret = -1; 42 42 int rval; 43 43 44 - rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len); 44 + rval = rtas_call(rtas_function_token(RTAS_FN_READ_PCI_CONFIG), 2, 2, &ret, addr, len); 45 45 *val = ret; 46 46 return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 47 47 } ··· 55 55 | (hose->global_number << 24); 56 56 int rval; 57 57 58 - rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, 58 + rval = rtas_call(rtas_function_token(RTAS_FN_WRITE_PCI_CONFIG), 3, 1, NULL, 59 59 addr, len, val); 60 60 return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 61 61 }
+15 -5
arch/powerpc/platforms/Kconfig.cputype
··· 118 118 119 119 choice 120 120 prompt "CPU selection" 121 - default GENERIC_CPU 122 121 help 123 122 This will create a kernel which is optimised for a particular CPU. 124 123 The resulting kernel may not run on other CPUs, so use this with care. 125 124 126 125 If unsure, select Generic. 127 126 128 - config GENERIC_CPU 127 + config POWERPC64_CPU 129 128 bool "Generic (POWER5 and PowerPC 970 and above)" 130 129 depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN 131 130 select PPC_64S_HASH_MMU 132 131 133 - config GENERIC_CPU 132 + config POWERPC64_CPU 134 133 bool "Generic (POWER8 and above)" 135 134 depends on PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN 136 135 select ARCH_HAS_FAST_MULTIPLIER ··· 143 144 config CELL_CPU 144 145 bool "Cell Broadband Engine" 145 146 depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN 147 + depends on !CC_IS_CLANG 146 148 select PPC_64S_HASH_MMU 147 149 148 150 config PPC_970_CPU ··· 188 188 config E6500_CPU 189 189 bool "Freescale e6500" 190 190 depends on PPC64 && PPC_E500 191 + depends on !CC_IS_CLANG 191 192 select PPC_HAS_LBARX_LHARX 192 193 193 194 config 405_CPU 194 195 bool "40x family" 195 196 depends on 40x 197 + depends on !CC_IS_CLANG 196 198 197 199 config 440_CPU 198 200 bool "440 (44x family)" ··· 203 201 config 464_CPU 204 202 bool "464 (44x family)" 205 203 depends on 44x 204 + depends on !CC_IS_CLANG 206 205 207 206 config 476_CPU 208 207 bool "476 (47x family)" 209 208 depends on PPC_47x 209 + depends on !CC_IS_CLANG 210 210 211 211 config 860_CPU 212 212 bool "8xx family" 213 213 depends on PPC_8xx 214 + depends on !CC_IS_CLANG 214 215 215 216 config E300C2_CPU 216 217 bool "e300c2 (832x)" 217 218 depends on PPC_BOOK3S_32 219 + depends on !CC_IS_CLANG 218 220 219 221 config E300C3_CPU 220 222 bool "e300c3 (831x)" 221 223 depends on PPC_BOOK3S_32 224 + depends on !CC_IS_CLANG 222 225 223 226 config G4_CPU 224 227 bool "G4 (74xx)" ··· 240 233 241 234 config TOOLCHAIN_DEFAULT_CPU 242 235 bool "Rely on the toolchain's implicit default CPU" 243 - depends on PPC32 244 236 245 237 endchoice 246 238 247 239 config TARGET_CPU_BOOL 248 240 bool 249 - default !GENERIC_CPU && !TOOLCHAIN_DEFAULT_CPU 241 + default !TOOLCHAIN_DEFAULT_CPU 250 242 251 243 config TARGET_CPU 252 244 string ··· 257 251 default "power8" if POWER8_CPU 258 252 default "power9" if POWER9_CPU 259 253 default "power10" if POWER10_CPU 254 + default "e5500" if E5500_CPU 255 + default "e6500" if E6500_CPU 256 + default "power4" if POWERPC64_CPU && !CPU_LITTLE_ENDIAN 257 + default "power8" if POWERPC64_CPU && CPU_LITTLE_ENDIAN 260 258 default "405" if 405_CPU 261 259 default "440" if 440_CPU 262 260 default "464" if 464_CPU
+2 -2
arch/powerpc/platforms/cell/ras.c
··· 297 297 static int __init cbe_ptcal_init(void) 298 298 { 299 299 int ret; 300 - ptcal_start_tok = rtas_token("ibm,cbe-start-ptcal"); 301 - ptcal_stop_tok = rtas_token("ibm,cbe-stop-ptcal"); 300 + ptcal_start_tok = rtas_function_token(RTAS_FN_IBM_CBE_START_PTCAL); 301 + ptcal_stop_tok = rtas_function_token(RTAS_FN_IBM_CBE_STOP_PTCAL); 302 302 303 303 if (ptcal_start_tok == RTAS_UNKNOWN_SERVICE 304 304 || ptcal_stop_tok == RTAS_UNKNOWN_SERVICE)
+2 -2
arch/powerpc/platforms/cell/smp.c
··· 81 81 * If the RTAS start-cpu token does not exist then presume the 82 82 * cpu is already spinning. 83 83 */ 84 - start_cpu = rtas_token("start-cpu"); 84 + start_cpu = rtas_function_token(RTAS_FN_START_CPU); 85 85 if (start_cpu == RTAS_UNKNOWN_SERVICE) 86 86 return 1; 87 87 ··· 152 152 cpumask_clear_cpu(boot_cpuid, &of_spin_map); 153 153 154 154 /* Non-lpar has additional take/give timebase */ 155 - if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { 155 + if (rtas_function_token(RTAS_FN_FREEZE_TIME_BASE) != RTAS_UNKNOWN_SERVICE) { 156 156 smp_ops->give_timebase = rtas_give_timebase; 157 157 smp_ops->take_timebase = rtas_take_timebase; 158 158 }
+2 -2
arch/powerpc/platforms/chrp/nvram.c
··· 31 31 return 0xff; 32 32 } 33 33 spin_lock_irqsave(&nvram_lock, flags); 34 - if ((rtas_call(rtas_token("nvram-fetch"), 3, 2, &done, addr, 34 + if ((rtas_call(rtas_function_token(RTAS_FN_NVRAM_FETCH), 3, 2, &done, addr, 35 35 __pa(nvram_buf), 1) != 0) || 1 != done) 36 36 ret = 0xff; 37 37 else ··· 53 53 } 54 54 spin_lock_irqsave(&nvram_lock, flags); 55 55 nvram_buf[0] = val; 56 - if ((rtas_call(rtas_token("nvram-store"), 3, 2, &done, addr, 56 + if ((rtas_call(rtas_function_token(RTAS_FN_NVRAM_STORE), 3, 2, &done, addr, 57 57 __pa(nvram_buf), 1) != 0) || 1 != done) 58 58 printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr); 59 59 spin_unlock_irqrestore(&nvram_lock, flags);
+2 -2
arch/powerpc/platforms/chrp/pci.c
··· 104 104 int ret = -1; 105 105 int rval; 106 106 107 - rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len); 107 + rval = rtas_call(rtas_function_token(RTAS_FN_READ_PCI_CONFIG), 2, 2, &ret, addr, len); 108 108 *val = ret; 109 109 return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; 110 110 } ··· 118 118 | (hose->global_number << 24); 119 119 int rval; 120 120 121 - rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, 121 + rval = rtas_call(rtas_function_token(RTAS_FN_WRITE_PCI_CONFIG), 3, 1, NULL, 122 122 addr, len, val); 123 123 return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; 124 124 }
+2 -2
arch/powerpc/platforms/chrp/setup.c
··· 323 323 printk("chrp type = %x [%s]\n", _chrp_type, chrp_names[_chrp_type]); 324 324 325 325 rtas_initialize(); 326 - if (rtas_token("display-character") >= 0) 326 + if (rtas_function_token(RTAS_FN_DISPLAY_CHARACTER) >= 0) 327 327 ppc_md.progress = rtas_progress; 328 328 329 329 /* use RTAS time-of-day routines if available */ 330 - if (rtas_token("get-time-of-day") != RTAS_UNKNOWN_SERVICE) { 330 + if (rtas_function_token(RTAS_FN_GET_TIME_OF_DAY) != RTAS_UNKNOWN_SERVICE) { 331 331 ppc_md.get_boot_time = rtas_get_boot_time; 332 332 ppc_md.get_rtc_time = rtas_get_rtc_time; 333 333 ppc_md.set_rtc_time = rtas_set_rtc_time;
+2 -2
arch/powerpc/platforms/maple/setup.c
··· 162 162 163 163 static void __init maple_use_rtas_reboot_and_halt_if_present(void) 164 164 { 165 - if (rtas_service_present("system-reboot") && 166 - rtas_service_present("power-off")) { 165 + if (rtas_function_implemented(RTAS_FN_SYSTEM_REBOOT) && 166 + rtas_function_implemented(RTAS_FN_POWER_OFF)) { 167 167 ppc_md.restart = rtas_restart; 168 168 pm_power_off = rtas_power_off; 169 169 ppc_md.halt = rtas_halt;
+51 -9
arch/powerpc/platforms/powernv/opal-secvar.c
··· 54 54 return err; 55 55 } 56 56 57 - static int opal_get_variable(const char *key, uint64_t ksize, 58 - u8 *data, uint64_t *dsize) 57 + static int opal_get_variable(const char *key, u64 ksize, u8 *data, u64 *dsize) 59 58 { 60 59 int rc; 61 60 ··· 70 71 return opal_status_to_err(rc); 71 72 } 72 73 73 - static int opal_get_next_variable(const char *key, uint64_t *keylen, 74 - uint64_t keybufsize) 74 + static int opal_get_next_variable(const char *key, u64 *keylen, u64 keybufsize) 75 75 { 76 76 int rc; 77 77 ··· 86 88 return opal_status_to_err(rc); 87 89 } 88 90 89 - static int opal_set_variable(const char *key, uint64_t ksize, u8 *data, 90 - uint64_t dsize) 91 + static int opal_set_variable(const char *key, u64 ksize, u8 *data, u64 dsize) 91 92 { 92 93 int rc; 93 94 ··· 98 101 return opal_status_to_err(rc); 99 102 } 100 103 104 + static ssize_t opal_secvar_format(char *buf, size_t bufsize) 105 + { 106 + ssize_t rc = 0; 107 + struct device_node *node; 108 + const char *format; 109 + 110 + node = of_find_compatible_node(NULL, NULL, "ibm,secvar-backend"); 111 + if (!of_device_is_available(node)) { 112 + rc = -ENODEV; 113 + goto out; 114 + } 115 + 116 + rc = of_property_read_string(node, "format", &format); 117 + if (rc) 118 + goto out; 119 + 120 + rc = snprintf(buf, bufsize, "%s", format); 121 + 122 + out: 123 + of_node_put(node); 124 + 125 + return rc; 126 + } 127 + 128 + static int opal_secvar_max_size(u64 *max_size) 129 + { 130 + int rc; 131 + struct device_node *node; 132 + 133 + node = of_find_compatible_node(NULL, NULL, "ibm,secvar-backend"); 134 + if (!node) 135 + return -ENODEV; 136 + 137 + if (!of_device_is_available(node)) { 138 + rc = -ENODEV; 139 + goto out; 140 + } 141 + 142 + rc = of_property_read_u64(node, "max-var-size", max_size); 143 + 144 + out: 145 + of_node_put(node); 146 + return rc; 147 + } 148 + 101 149 static const struct secvar_operations opal_secvar_ops = { 102 150 .get = opal_get_variable, 103 151 .get_next = opal_get_next_variable, 104 152 .set = opal_set_variable, 153 + .format = opal_secvar_format, 154 + .max_size = opal_secvar_max_size, 105 155 }; 106 156 107 157 static int opal_secvar_probe(struct platform_device *pdev) ··· 160 116 return -ENODEV; 161 117 } 162 118 163 - set_secvar_ops(&opal_secvar_ops); 164 - 165 - return 0; 119 + return set_secvar_ops(&opal_secvar_ops); 166 120 } 167 121 168 122 static const struct of_device_id opal_secvar_match[] = {
+2 -1
arch/powerpc/platforms/powernv/pci-ioda.c
··· 2325 2325 int index; 2326 2326 int64_t rc; 2327 2327 2328 - if (!res || !res->flags || res->start > res->end) 2328 + if (!res || !res->flags || res->start > res->end || 2329 + res->flags & IORESOURCE_UNSET) 2329 2330 return; 2330 2331 2331 2332 if (res->flags & IORESOURCE_IO) {
+1 -1
arch/powerpc/platforms/ps3/htab.c
··· 146 146 static void ps3_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, 147 147 int psize, int ssize) 148 148 { 149 - panic("ps3_hpte_updateboltedpp() not implemented"); 149 + pr_info("ps3_hpte_updateboltedpp() not implemented"); 150 150 } 151 151 152 152 static void ps3_hpte_invalidate(unsigned long slot, unsigned long vpn,
+10 -10
arch/powerpc/platforms/pseries/Kconfig
··· 151 151 152 152 config PSERIES_PLPKS 153 153 depends on PPC_PSERIES 154 - bool "Support for the Platform Key Storage" 155 - help 156 - PowerVM provides an isolated Platform Keystore(PKS) storage 157 - allocation for each LPAR with individually managed access 158 - controls to store sensitive information securely. It can be 159 - used to store asymmetric public keys or secrets as required 160 - by different usecases. Select this config to enable 161 - operating system interface to hypervisor to access this space. 162 - 163 - If unsure, select N. 154 + select NLS 155 + bool 156 + # PowerVM provides an isolated Platform Keystore (PKS) storage 157 + # allocation for each LPAR with individually managed access 158 + # controls to store sensitive information securely. It can be 159 + # used to store asymmetric public keys or secrets as required 160 + # by different usecases. 161 + # 162 + # This option is selected by in-kernel consumers that require 163 + # access to the PKS. 164 164 165 165 config PAPR_SCM 166 166 depends on PPC_PSERIES && MEMORY_HOTPLUG && LIBNVDIMM
+3 -3
arch/powerpc/platforms/pseries/Makefile
··· 3 3 ccflags-$(CONFIG_PPC_PSERIES_DEBUG) += -DDEBUG 4 4 5 5 obj-y := lpar.o hvCall.o nvram.o reconfig.o \ 6 - of_helpers.o \ 6 + of_helpers.o rtas-work-area.o papr-sysparm.o \ 7 7 setup.o iommu.o event_sources.o ras.o \ 8 8 firmware.o power.o dlpar.o mobility.o rng.o \ 9 9 pci.o pci_dlpar.o eeh_pseries.o msi.o \ ··· 27 27 obj-$(CONFIG_PPC_SPLPAR) += vphn.o 28 28 obj-$(CONFIG_PPC_SVM) += svm.o 29 29 obj-$(CONFIG_FA_DUMP) += rtas-fadump.o 30 - obj-$(CONFIG_PSERIES_PLPKS) += plpks.o 31 - 30 + obj-$(CONFIG_PSERIES_PLPKS) += plpks.o 31 + obj-$(CONFIG_PPC_SECURE_BOOT) += plpks-secvar.o 32 32 obj-$(CONFIG_SUSPEND) += suspend.o 33 33 obj-$(CONFIG_PPC_VAS) += vas.o vas-sysfs.o 34 34
+10 -19
arch/powerpc/platforms/pseries/dlpar.c
··· 22 22 #include <asm/machdep.h> 23 23 #include <linux/uaccess.h> 24 24 #include <asm/rtas.h> 25 + #include <asm/rtas-work-area.h> 25 26 26 27 static struct workqueue_struct *pseries_hp_wq; 27 28 ··· 138 137 struct property *property; 139 138 struct property *last_property = NULL; 140 139 struct cc_workarea *ccwa; 140 + struct rtas_work_area *work_area; 141 141 char *data_buf; 142 142 int cc_token; 143 143 int rc = -1; 144 144 145 - cc_token = rtas_token("ibm,configure-connector"); 145 + cc_token = rtas_function_token(RTAS_FN_IBM_CONFIGURE_CONNECTOR); 146 146 if (cc_token == RTAS_UNKNOWN_SERVICE) 147 147 return NULL; 148 148 149 - data_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); 150 - if (!data_buf) 151 - return NULL; 149 + work_area = rtas_work_area_alloc(SZ_4K); 150 + data_buf = rtas_work_area_raw_buf(work_area); 152 151 153 152 ccwa = (struct cc_workarea *)&data_buf[0]; 154 153 ccwa->drc_index = drc_index; 155 154 ccwa->zero = 0; 156 155 157 156 do { 158 - /* Since we release the rtas_data_buf lock between configure 159 - * connector calls we want to re-populate the rtas_data_buffer 160 - * with the contents of the previous call. 161 - */ 162 - spin_lock(&rtas_data_buf_lock); 163 - 164 - memcpy(rtas_data_buf, data_buf, RTAS_DATA_BUF_SIZE); 165 - rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); 166 - memcpy(data_buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); 167 - 168 - spin_unlock(&rtas_data_buf_lock); 169 - 170 - if (rtas_busy_delay(rc)) 171 - continue; 157 + do { 158 + rc = rtas_call(cc_token, 2, 1, NULL, 159 + rtas_work_area_phys(work_area), NULL); 160 + } while (rtas_busy_delay(rc)); 172 161 173 162 switch (rc) { 174 163 case COMPLETE: ··· 218 227 } while (rc); 219 228 220 229 cc_error: 221 - kfree(data_buf); 230 + rtas_work_area_free(work_area); 222 231 223 232 if (rc) { 224 233 if (first_dn)
+11 -11
arch/powerpc/platforms/pseries/eeh_pseries.c
··· 699 699 static int pseries_send_allow_unfreeze(struct pci_dn *pdn, u16 *vf_pe_array, int cur_vfs) 700 700 { 701 701 int rc; 702 - int ibm_allow_unfreeze = rtas_token("ibm,open-sriov-allow-unfreeze"); 702 + int ibm_allow_unfreeze = rtas_function_token(RTAS_FN_IBM_OPEN_SRIOV_ALLOW_UNFREEZE); 703 703 unsigned long buid, addr; 704 704 705 705 addr = rtas_config_addr(pdn->busno, pdn->devfn, 0); ··· 774 774 if (!edev) 775 775 return -EEXIST; 776 776 777 - if (rtas_token("ibm,open-sriov-allow-unfreeze") == RTAS_UNKNOWN_SERVICE) 777 + if (rtas_function_token(RTAS_FN_IBM_OPEN_SRIOV_ALLOW_UNFREEZE) == RTAS_UNKNOWN_SERVICE) 778 778 return -EINVAL; 779 779 780 780 if (edev->pdev->is_physfn || edev->pdev->is_virtfn) ··· 815 815 int ret, config_addr; 816 816 817 817 /* figure out EEH RTAS function call tokens */ 818 - ibm_set_eeh_option = rtas_token("ibm,set-eeh-option"); 819 - ibm_set_slot_reset = rtas_token("ibm,set-slot-reset"); 820 - ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2"); 821 - ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state"); 822 - ibm_slot_error_detail = rtas_token("ibm,slot-error-detail"); 823 - ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2"); 824 - ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info"); 825 - ibm_configure_pe = rtas_token("ibm,configure-pe"); 818 + ibm_set_eeh_option = rtas_function_token(RTAS_FN_IBM_SET_EEH_OPTION); 819 + ibm_set_slot_reset = rtas_function_token(RTAS_FN_IBM_SET_SLOT_RESET); 820 + ibm_read_slot_reset_state2 = rtas_function_token(RTAS_FN_IBM_READ_SLOT_RESET_STATE2); 821 + ibm_read_slot_reset_state = rtas_function_token(RTAS_FN_IBM_READ_SLOT_RESET_STATE); 822 + ibm_slot_error_detail = rtas_function_token(RTAS_FN_IBM_SLOT_ERROR_DETAIL); 823 + ibm_get_config_addr_info2 = rtas_function_token(RTAS_FN_IBM_GET_CONFIG_ADDR_INFO2); 824 + ibm_get_config_addr_info = rtas_function_token(RTAS_FN_IBM_GET_CONFIG_ADDR_INFO); 825 + ibm_configure_pe = rtas_function_token(RTAS_FN_IBM_CONFIGURE_PE); 826 826 827 827 /* 828 828 * ibm,configure-pe and ibm,configure-bridge have the same semantics, ··· 830 830 * ibm,configure-pe then fall back to using ibm,configure-bridge. 831 831 */ 832 832 if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE) 833 - ibm_configure_pe = rtas_token("ibm,configure-bridge"); 833 + ibm_configure_pe = rtas_function_token(RTAS_FN_IBM_CONFIGURE_BRIDGE); 834 834 835 835 /* 836 836 * Necessary sanity check. We needn't check "get-config-addr-info"
+2 -2
arch/powerpc/platforms/pseries/hotplug-cpu.c
··· 855 855 ppc_md.cpu_release = dlpar_cpu_release; 856 856 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ 857 857 858 - rtas_stop_self_token = rtas_token("stop-self"); 859 - qcss_tok = rtas_token("query-cpu-stopped-state"); 858 + rtas_stop_self_token = rtas_function_token(RTAS_FN_STOP_SELF); 859 + qcss_tok = rtas_function_token(RTAS_FN_QUERY_CPU_STOPPED_STATE); 860 860 861 861 if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE || 862 862 qcss_tok == RTAS_UNKNOWN_SERVICE) {
+1 -1
arch/powerpc/platforms/pseries/io_event_irq.c
··· 143 143 { 144 144 struct device_node *np; 145 145 146 - ioei_check_exception_token = rtas_token("check-exception"); 146 + ioei_check_exception_token = rtas_function_token(RTAS_FN_CHECK_EXCEPTION); 147 147 if (ioei_check_exception_token == RTAS_UNKNOWN_SERVICE) 148 148 return -ENODEV; 149 149
+9 -28
arch/powerpc/platforms/pseries/lpar.c
··· 32 32 #include <asm/iommu.h> 33 33 #include <asm/tlb.h> 34 34 #include <asm/cputable.h> 35 + #include <asm/papr-sysparm.h> 35 36 #include <asm/udbg.h> 36 37 #include <asm/smp.h> 37 38 #include <asm/trace.h> ··· 1470 1469 } 1471 1470 } 1472 1471 1473 - #define SPLPAR_TLB_BIC_TOKEN 50 1474 - 1475 1472 /* 1476 1473 * The size of the TLB Block Invalidate Characteristics is variable. But at the 1477 1474 * maximum it will be the number of possible page sizes *2 + 10 bytes. ··· 1480 1481 1481 1482 void __init pseries_lpar_read_hblkrm_characteristics(void) 1482 1483 { 1483 - unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH]; 1484 - int call_status, len, idx, bpsize; 1484 + static struct papr_sysparm_buf buf __initdata; 1485 + int len, idx, bpsize; 1485 1486 1486 1487 if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE)) 1487 1488 return; 1488 1489 1489 - spin_lock(&rtas_data_buf_lock); 1490 - memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE); 1491 - call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, 1492 - NULL, 1493 - SPLPAR_TLB_BIC_TOKEN, 1494 - __pa(rtas_data_buf), 1495 - RTAS_DATA_BUF_SIZE); 1496 - memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH); 1497 - local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0'; 1498 - spin_unlock(&rtas_data_buf_lock); 1499 - 1500 - if (call_status != 0) { 1501 - pr_warn("%s %s Error calling get-system-parameter (0x%x)\n", 1502 - __FILE__, __func__, call_status); 1490 + if (papr_sysparm_get(PAPR_SYSPARM_TLB_BLOCK_INVALIDATE_ATTRS, &buf)) 1503 1491 return; 1504 - } 1505 1492 1506 - /* 1507 - * The first two (2) bytes of the data in the buffer are the length of 1508 - * the returned data, not counting these first two (2) bytes. 1509 - */ 1510 - len = be16_to_cpu(*((u16 *)local_buffer)) + 2; 1493 + len = be16_to_cpu(buf.len); 1511 1494 if (len > SPLPAR_TLB_BIC_MAXLENGTH) { 1512 1495 pr_warn("%s too large returned buffer %d", __func__, len); 1513 1496 return; 1514 1497 } 1515 1498 1516 - idx = 2; 1499 + idx = 0; 1517 1500 while (idx < len) { 1518 - u8 block_shift = local_buffer[idx++]; 1501 + u8 block_shift = buf.val[idx++]; 1519 1502 u32 block_size; 1520 1503 unsigned int npsize; 1521 1504 ··· 1506 1525 1507 1526 block_size = 1 << block_shift; 1508 1527 1509 - for (npsize = local_buffer[idx++]; 1528 + for (npsize = buf.val[idx++]; 1510 1529 npsize > 0 && idx < len; npsize--) 1511 - check_lp_set_hblkrm((unsigned int) local_buffer[idx++], 1530 + check_lp_set_hblkrm((unsigned int)buf.val[idx++], 1512 1531 block_size); 1513 1532 } 1514 1533
+24 -80
arch/powerpc/platforms/pseries/lparcfg.c
··· 19 19 #include <linux/errno.h> 20 20 #include <linux/proc_fs.h> 21 21 #include <linux/init.h> 22 + #include <asm/papr-sysparm.h> 22 23 #include <linux/seq_file.h> 23 24 #include <linux/slab.h> 24 25 #include <linux/uaccess.h> ··· 313 312 } 314 313 315 314 /* 316 - * PAPR defines, in section "7.3.16 System Parameters Option", the token 55 to 317 - * read the LPAR name, and the largest output data to 4000 + 2 bytes length. 318 - */ 319 - #define SPLPAR_LPAR_NAME_TOKEN 55 320 - #define GET_SYS_PARM_BUF_SIZE 4002 321 - #if GET_SYS_PARM_BUF_SIZE > RTAS_DATA_BUF_SIZE 322 - #error "GET_SYS_PARM_BUF_SIZE is larger than RTAS_DATA_BUF_SIZE" 323 - #endif 324 - 325 - /* 326 315 * Read the lpar name using the RTAS ibm,get-system-parameter call. 327 316 * 328 317 * The name read through this call is updated if changes are made by the end ··· 323 332 */ 324 333 static int read_rtas_lpar_name(struct seq_file *m) 325 334 { 326 - int rc, len, token; 327 - union { 328 - char raw_buffer[GET_SYS_PARM_BUF_SIZE]; 329 - struct { 330 - __be16 len; 331 - char name[GET_SYS_PARM_BUF_SIZE-2]; 332 - }; 333 - } *local_buffer; 335 + struct papr_sysparm_buf *buf; 336 + int err; 334 337 335 - token = rtas_token("ibm,get-system-parameter"); 336 - if (token == RTAS_UNKNOWN_SERVICE) 337 - return -EINVAL; 338 - 339 - local_buffer = kmalloc(sizeof(*local_buffer), GFP_KERNEL); 340 - if (!local_buffer) 338 + buf = papr_sysparm_buf_alloc(); 339 + if (!buf) 341 340 return -ENOMEM; 342 341 343 - do { 344 - spin_lock(&rtas_data_buf_lock); 345 - memset(rtas_data_buf, 0, sizeof(*local_buffer)); 346 - rc = rtas_call(token, 3, 1, NULL, SPLPAR_LPAR_NAME_TOKEN, 347 - __pa(rtas_data_buf), sizeof(*local_buffer)); 348 - if (!rc) 349 - memcpy(local_buffer->raw_buffer, rtas_data_buf, 350 - sizeof(local_buffer->raw_buffer)); 351 - spin_unlock(&rtas_data_buf_lock); 352 - } while (rtas_busy_delay(rc)); 342 + err = papr_sysparm_get(PAPR_SYSPARM_LPAR_NAME, buf); 343 + if (!err) 344 + seq_printf(m, "partition_name=%s\n", buf->val); 353 345 354 - if (!rc) { 355 - /* Force end of string */ 356 - len = min((int) be16_to_cpu(local_buffer->len), 357 - (int) sizeof(local_buffer->name)-1); 358 - local_buffer->name[len] = '\0'; 359 - 360 - seq_printf(m, "partition_name=%s\n", local_buffer->name); 361 - } else 362 - rc = -ENODATA; 363 - 364 - kfree(local_buffer); 365 - return rc; 346 + papr_sysparm_buf_free(buf); 347 + return err; 366 348 } 367 349 368 350 /* ··· 361 397 pr_err_once("Error can't get the LPAR name"); 362 398 } 363 399 364 - #define SPLPAR_CHARACTERISTICS_TOKEN 20 365 400 #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) 366 401 367 402 /* ··· 371 408 */ 372 409 static void parse_system_parameter_string(struct seq_file *m) 373 410 { 374 - int call_status; 411 + struct papr_sysparm_buf *buf; 375 412 376 - unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL); 377 - if (!local_buffer) { 378 - printk(KERN_ERR "%s %s kmalloc failure at line %d\n", 379 - __FILE__, __func__, __LINE__); 413 + buf = papr_sysparm_buf_alloc(); 414 + if (!buf) 380 415 return; 381 - } 382 416 383 - spin_lock(&rtas_data_buf_lock); 384 - memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH); 385 - call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, 386 - NULL, 387 - SPLPAR_CHARACTERISTICS_TOKEN, 388 - __pa(rtas_data_buf), 389 - RTAS_DATA_BUF_SIZE); 390 - memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH); 391 - local_buffer[SPLPAR_MAXLENGTH - 1] = '\0'; 392 - spin_unlock(&rtas_data_buf_lock); 393 - 394 - if (call_status != 0) { 395 - printk(KERN_INFO 396 - "%s %s Error calling get-system-parameter (0x%x)\n", 397 - __FILE__, __func__, call_status); 417 + if (papr_sysparm_get(PAPR_SYSPARM_SHARED_PROC_LPAR_ATTRS, buf)) { 418 + goto out_free; 398 419 } else { 420 + const char *local_buffer; 399 421 int splpar_strlen; 400 422 int idx, w_idx; 401 423 char *workbuffer = kzalloc(SPLPAR_MAXLENGTH, GFP_KERNEL); 402 - if (!workbuffer) { 403 - printk(KERN_ERR "%s %s kmalloc failure at line %d\n", 404 - __FILE__, __func__, __LINE__); 405 - kfree(local_buffer); 406 - return; 407 - } 408 - #ifdef LPARCFG_DEBUG 409 - printk(KERN_INFO "success calling get-system-parameter\n"); 410 - #endif 411 - splpar_strlen = local_buffer[0] * 256 + local_buffer[1]; 412 - local_buffer += 2; /* step over strlen value */ 424 + 425 + if (!workbuffer) 426 + goto out_free; 427 + 428 + splpar_strlen = be16_to_cpu(buf->len); 429 + local_buffer = buf->val; 413 430 414 431 w_idx = 0; 415 432 idx = 0; ··· 423 480 kfree(workbuffer); 424 481 local_buffer -= 2; /* back up over strlen value */ 425 482 } 426 - kfree(local_buffer); 483 + out_free: 484 + papr_sysparm_buf_free(buf); 427 485 } 428 486 429 487 /* Return the number of processors in the system.
+2 -2
arch/powerpc/platforms/pseries/mobility.c
··· 195 195 u32 nprops; 196 196 u32 vd; 197 197 198 - update_properties_token = rtas_token("ibm,update-properties"); 198 + update_properties_token = rtas_function_token(RTAS_FN_IBM_UPDATE_PROPERTIES); 199 199 if (update_properties_token == RTAS_UNKNOWN_SERVICE) 200 200 return -EINVAL; 201 201 ··· 306 306 int update_nodes_token; 307 307 int rc; 308 308 309 - update_nodes_token = rtas_token("ibm,update-nodes"); 309 + update_nodes_token = rtas_function_token(RTAS_FN_IBM_UPDATE_NODES); 310 310 if (update_nodes_token == RTAS_UNKNOWN_SERVICE) 311 311 return 0; 312 312
+2 -2
arch/powerpc/platforms/pseries/msi.c
··· 679 679 680 680 static int rtas_msi_init(void) 681 681 { 682 - query_token = rtas_token("ibm,query-interrupt-source-number"); 683 - change_token = rtas_token("ibm,change-msi"); 682 + query_token = rtas_function_token(RTAS_FN_IBM_QUERY_INTERRUPT_SOURCE_NUMBER); 683 + change_token = rtas_function_token(RTAS_FN_IBM_CHANGE_MSI); 684 684 685 685 if ((query_token == RTAS_UNKNOWN_SERVICE) || 686 686 (change_token == RTAS_UNKNOWN_SERVICE)) {
+2 -2
arch/powerpc/platforms/pseries/nvram.c
··· 227 227 228 228 nvram_size = be32_to_cpup(nbytes_p); 229 229 230 - nvram_fetch = rtas_token("nvram-fetch"); 231 - nvram_store = rtas_token("nvram-store"); 230 + nvram_fetch = rtas_function_token(RTAS_FN_NVRAM_FETCH); 231 + nvram_store = rtas_function_token(RTAS_FN_NVRAM_STORE); 232 232 printk(KERN_INFO "PPC64 nvram contains %d bytes\n", nvram_size); 233 233 of_node_put(nvram); 234 234
+151
arch/powerpc/platforms/pseries/papr-sysparm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #define pr_fmt(fmt) "papr-sysparm: " fmt 4 + 5 + #include <linux/bug.h> 6 + #include <linux/init.h> 7 + #include <linux/kernel.h> 8 + #include <linux/printk.h> 9 + #include <linux/slab.h> 10 + #include <asm/rtas.h> 11 + #include <asm/papr-sysparm.h> 12 + #include <asm/rtas-work-area.h> 13 + 14 + struct papr_sysparm_buf *papr_sysparm_buf_alloc(void) 15 + { 16 + struct papr_sysparm_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); 17 + 18 + return buf; 19 + } 20 + 21 + void papr_sysparm_buf_free(struct papr_sysparm_buf *buf) 22 + { 23 + kfree(buf); 24 + } 25 + 26 + /** 27 + * papr_sysparm_get() - Retrieve the value of a PAPR system parameter. 28 + * @param: PAPR system parameter token as described in 29 + * 7.3.16 "System Parameters Option". 30 + * @buf: A &struct papr_sysparm_buf as returned from papr_sysparm_buf_alloc(). 31 + * 32 + * Place the result of querying the specified parameter, if available, 33 + * in @buf. The result includes a be16 length header followed by the 34 + * value, which may be a string or binary data. See &struct papr_sysparm_buf. 35 + * 36 + * Since there is at least one parameter (60, OS Service Entitlement 37 + * Status) where the results depend on the incoming contents of the 38 + * work area, the caller-supplied buffer is copied unmodified into the 39 + * work area before calling ibm,get-system-parameter. 40 + * 41 + * A defined parameter may not be implemented on a given system, and 42 + * some implemented parameters may not be available to all partitions 43 + * on a system. A parameter's disposition may change at any time due 44 + * to system configuration changes or partition migration. 45 + * 46 + * Context: This function may sleep. 47 + * 48 + * Return: 0 on success, -errno otherwise. @buf is unmodified on error. 49 + */ 50 + 51 + int papr_sysparm_get(papr_sysparm_t param, struct papr_sysparm_buf *buf) 52 + { 53 + const s32 token = rtas_function_token(RTAS_FN_IBM_GET_SYSTEM_PARAMETER); 54 + struct rtas_work_area *work_area; 55 + s32 fwrc; 56 + int ret; 57 + 58 + might_sleep(); 59 + 60 + if (WARN_ON(!buf)) 61 + return -EFAULT; 62 + 63 + if (token == RTAS_UNKNOWN_SERVICE) 64 + return -ENOENT; 65 + 66 + work_area = rtas_work_area_alloc(sizeof(*buf)); 67 + 68 + memcpy(rtas_work_area_raw_buf(work_area), buf, sizeof(*buf)); 69 + 70 + do { 71 + fwrc = rtas_call(token, 3, 1, NULL, param.token, 72 + rtas_work_area_phys(work_area), 73 + rtas_work_area_size(work_area)); 74 + } while (rtas_busy_delay(fwrc)); 75 + 76 + switch (fwrc) { 77 + case 0: 78 + ret = 0; 79 + memcpy(buf, rtas_work_area_raw_buf(work_area), sizeof(*buf)); 80 + break; 81 + case -3: /* parameter not implemented */ 82 + ret = -EOPNOTSUPP; 83 + break; 84 + case -9002: /* this partition not authorized to retrieve this parameter */ 85 + ret = -EPERM; 86 + break; 87 + case -9999: /* "parameter error" e.g. the buffer is too small */ 88 + ret = -EINVAL; 89 + break; 90 + default: 91 + pr_err("unexpected ibm,get-system-parameter result %d\n", fwrc); 92 + fallthrough; 93 + case -1: /* Hardware/platform error */ 94 + ret = -EIO; 95 + break; 96 + } 97 + 98 + rtas_work_area_free(work_area); 99 + 100 + return ret; 101 + } 102 + 103 + int papr_sysparm_set(papr_sysparm_t param, const struct papr_sysparm_buf *buf) 104 + { 105 + const s32 token = rtas_function_token(RTAS_FN_IBM_SET_SYSTEM_PARAMETER); 106 + struct rtas_work_area *work_area; 107 + s32 fwrc; 108 + int ret; 109 + 110 + might_sleep(); 111 + 112 + if (WARN_ON(!buf)) 113 + return -EFAULT; 114 + 115 + if (token == RTAS_UNKNOWN_SERVICE) 116 + return -ENOENT; 117 + 118 + work_area = rtas_work_area_alloc(sizeof(*buf)); 119 + 120 + memcpy(rtas_work_area_raw_buf(work_area), buf, sizeof(*buf)); 121 + 122 + do { 123 + fwrc = rtas_call(token, 2, 1, NULL, param.token, 124 + rtas_work_area_phys(work_area)); 125 + } while (rtas_busy_delay(fwrc)); 126 + 127 + switch (fwrc) { 128 + case 0: 129 + ret = 0; 130 + break; 131 + case -3: /* parameter not supported */ 132 + ret = -EOPNOTSUPP; 133 + break; 134 + case -9002: /* this partition not authorized to modify this parameter */ 135 + ret = -EPERM; 136 + break; 137 + case -9999: /* "parameter error" e.g. invalid input data */ 138 + ret = -EINVAL; 139 + break; 140 + default: 141 + pr_err("unexpected ibm,set-system-parameter result %d\n", fwrc); 142 + fallthrough; 143 + case -1: /* Hardware/platform error */ 144 + ret = -EIO; 145 + break; 146 + } 147 + 148 + rtas_work_area_free(work_area); 149 + 150 + return ret; 151 + }
+1 -1
arch/powerpc/platforms/pseries/pci.c
··· 60 60 struct pci_dn *pdn; 61 61 int rc; 62 62 unsigned long buid, addr; 63 - int ibm_map_pes = rtas_token("ibm,open-sriov-map-pe-number"); 63 + int ibm_map_pes = rtas_function_token(RTAS_FN_IBM_OPEN_SRIOV_MAP_PE_NUMBER); 64 64 65 65 if (ibm_map_pes == RTAS_UNKNOWN_SERVICE) 66 66 return -EINVAL;
+217
arch/powerpc/platforms/pseries/plpks-secvar.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + // Secure variable implementation using the PowerVM LPAR Platform KeyStore (PLPKS) 4 + // 5 + // Copyright 2022, 2023 IBM Corporation 6 + // Authors: Russell Currey 7 + // Andrew Donnellan 8 + // Nayna Jain 9 + 10 + #define pr_fmt(fmt) "secvar: "fmt 11 + 12 + #include <linux/printk.h> 13 + #include <linux/init.h> 14 + #include <linux/types.h> 15 + #include <linux/slab.h> 16 + #include <linux/string.h> 17 + #include <linux/kobject.h> 18 + #include <linux/nls.h> 19 + #include <asm/machdep.h> 20 + #include <asm/secvar.h> 21 + #include <asm/plpks.h> 22 + 23 + // Config attributes for sysfs 24 + #define PLPKS_CONFIG_ATTR(name, fmt, func) \ 25 + static ssize_t name##_show(struct kobject *kobj, \ 26 + struct kobj_attribute *attr, \ 27 + char *buf) \ 28 + { \ 29 + return sysfs_emit(buf, fmt, func()); \ 30 + } \ 31 + static struct kobj_attribute attr_##name = __ATTR_RO(name) 32 + 33 + PLPKS_CONFIG_ATTR(version, "%u\n", plpks_get_version); 34 + PLPKS_CONFIG_ATTR(max_object_size, "%u\n", plpks_get_maxobjectsize); 35 + PLPKS_CONFIG_ATTR(total_size, "%u\n", plpks_get_totalsize); 36 + PLPKS_CONFIG_ATTR(used_space, "%u\n", plpks_get_usedspace); 37 + PLPKS_CONFIG_ATTR(supported_policies, "%08x\n", plpks_get_supportedpolicies); 38 + PLPKS_CONFIG_ATTR(signed_update_algorithms, "%016llx\n", plpks_get_signedupdatealgorithms); 39 + 40 + static const struct attribute *config_attrs[] = { 41 + &attr_version.attr, 42 + &attr_max_object_size.attr, 43 + &attr_total_size.attr, 44 + &attr_used_space.attr, 45 + &attr_supported_policies.attr, 46 + &attr_signed_update_algorithms.attr, 47 + NULL, 48 + }; 49 + 50 + static u32 get_policy(const char *name) 51 + { 52 + if ((strcmp(name, "db") == 0) || 53 + (strcmp(name, "dbx") == 0) || 54 + (strcmp(name, "grubdb") == 0) || 55 + (strcmp(name, "grubdbx") == 0) || 56 + (strcmp(name, "sbat") == 0)) 57 + return (PLPKS_WORLDREADABLE | PLPKS_SIGNEDUPDATE); 58 + else 59 + return PLPKS_SIGNEDUPDATE; 60 + } 61 + 62 + static const char * const plpks_var_names[] = { 63 + "PK", 64 + "KEK", 65 + "db", 66 + "dbx", 67 + "grubdb", 68 + "grubdbx", 69 + "sbat", 70 + "moduledb", 71 + "trustedcadb", 72 + NULL, 73 + }; 74 + 75 + static int plpks_get_variable(const char *key, u64 key_len, u8 *data, 76 + u64 *data_size) 77 + { 78 + struct plpks_var var = {0}; 79 + int rc = 0; 80 + 81 + // We subtract 1 from key_len because we don't need to include the 82 + // null terminator at the end of the string 83 + var.name = kcalloc(key_len - 1, sizeof(wchar_t), GFP_KERNEL); 84 + if (!var.name) 85 + return -ENOMEM; 86 + rc = utf8s_to_utf16s(key, key_len - 1, UTF16_LITTLE_ENDIAN, (wchar_t *)var.name, 87 + key_len - 1); 88 + if (rc < 0) 89 + goto err; 90 + var.namelen = rc * 2; 91 + 92 + var.os = PLPKS_VAR_LINUX; 93 + if (data) { 94 + var.data = data; 95 + var.datalen = *data_size; 96 + } 97 + rc = plpks_read_os_var(&var); 98 + 99 + if (rc) 100 + goto err; 101 + 102 + *data_size = var.datalen; 103 + 104 + err: 105 + kfree(var.name); 106 + if (rc && rc != -ENOENT) { 107 + pr_err("Failed to read variable '%s': %d\n", key, rc); 108 + // Return -EIO since userspace probably doesn't care about the 109 + // specific error 110 + rc = -EIO; 111 + } 112 + return rc; 113 + } 114 + 115 + static int plpks_set_variable(const char *key, u64 key_len, u8 *data, 116 + u64 data_size) 117 + { 118 + struct plpks_var var = {0}; 119 + int rc = 0; 120 + u64 flags; 121 + 122 + // Secure variables need to be prefixed with 8 bytes of flags. 123 + // We only want to perform the write if we have at least one byte of data. 124 + if (data_size <= sizeof(flags)) 125 + return -EINVAL; 126 + 127 + // We subtract 1 from key_len because we don't need to include the 128 + // null terminator at the end of the string 129 + var.name = kcalloc(key_len - 1, sizeof(wchar_t), GFP_KERNEL); 130 + if (!var.name) 131 + return -ENOMEM; 132 + rc = utf8s_to_utf16s(key, key_len - 1, UTF16_LITTLE_ENDIAN, (wchar_t *)var.name, 133 + key_len - 1); 134 + if (rc < 0) 135 + goto err; 136 + var.namelen = rc * 2; 137 + 138 + // Flags are contained in the first 8 bytes of the buffer, and are always big-endian 139 + flags = be64_to_cpup((__be64 *)data); 140 + 141 + var.datalen = data_size - sizeof(flags); 142 + var.data = data + sizeof(flags); 143 + var.os = PLPKS_VAR_LINUX; 144 + var.policy = get_policy(key); 145 + 146 + // Unlike in the read case, the plpks error code can be useful to 147 + // userspace on write, so we return it rather than just -EIO 148 + rc = plpks_signed_update_var(&var, flags); 149 + 150 + err: 151 + kfree(var.name); 152 + return rc; 153 + } 154 + 155 + // PLPKS dynamic secure boot doesn't give us a format string in the same way OPAL does. 156 + // Instead, report the format using the SB_VERSION variable in the keystore. 157 + // The string is made up by us, and takes the form "ibm,plpks-sb-v<n>" (or "ibm,plpks-sb-unknown" 158 + // if the SB_VERSION variable doesn't exist). Hypervisor defines the SB_VERSION variable as a 159 + // "1 byte unsigned integer value". 160 + static ssize_t plpks_secvar_format(char *buf, size_t bufsize) 161 + { 162 + struct plpks_var var = {0}; 163 + ssize_t ret; 164 + u8 version; 165 + 166 + var.component = NULL; 167 + // Only the signed variables have null bytes in their names, this one doesn't 168 + var.name = "SB_VERSION"; 169 + var.namelen = strlen(var.name); 170 + var.datalen = 1; 171 + var.data = &version; 172 + 173 + // Unlike the other vars, SB_VERSION is owned by firmware instead of the OS 174 + ret = plpks_read_fw_var(&var); 175 + if (ret) { 176 + if (ret == -ENOENT) { 177 + ret = snprintf(buf, bufsize, "ibm,plpks-sb-unknown"); 178 + } else { 179 + pr_err("Error %ld reading SB_VERSION from firmware\n", ret); 180 + ret = -EIO; 181 + } 182 + goto err; 183 + } 184 + 185 + ret = snprintf(buf, bufsize, "ibm,plpks-sb-v%hhu", version); 186 + err: 187 + return ret; 188 + } 189 + 190 + static int plpks_max_size(u64 *max_size) 191 + { 192 + // The max object size reported by the hypervisor is accurate for the 193 + // object itself, but we use the first 8 bytes of data on write as the 194 + // signed update flags, so the max size a user can write is larger. 195 + *max_size = (u64)plpks_get_maxobjectsize() + sizeof(u64); 196 + 197 + return 0; 198 + } 199 + 200 + 201 + static const struct secvar_operations plpks_secvar_ops = { 202 + .get = plpks_get_variable, 203 + .set = plpks_set_variable, 204 + .format = plpks_secvar_format, 205 + .max_size = plpks_max_size, 206 + .config_attrs = config_attrs, 207 + .var_names = plpks_var_names, 208 + }; 209 + 210 + static int plpks_secvar_init(void) 211 + { 212 + if (!plpks_is_available()) 213 + return -ENODEV; 214 + 215 + return set_secvar_ops(&plpks_secvar_ops); 216 + } 217 + machine_device_initcall(pseries, plpks_secvar_init);
+320 -67
arch/powerpc/platforms/pseries/plpks.c
··· 16 16 #include <linux/slab.h> 17 17 #include <linux/string.h> 18 18 #include <linux/types.h> 19 + #include <linux/of_fdt.h> 20 + #include <linux/libfdt.h> 21 + #include <linux/memblock.h> 19 22 #include <asm/hvcall.h> 20 23 #include <asm/machdep.h> 21 - 22 - #include "plpks.h" 23 - 24 - #define PKS_FW_OWNER 0x1 25 - #define PKS_BOOTLOADER_OWNER 0x2 26 - #define PKS_OS_OWNER 0x3 27 - 28 - #define LABEL_VERSION 0 29 - #define MAX_LABEL_ATTR_SIZE 16 30 - #define MAX_NAME_SIZE 239 31 - #define MAX_DATA_SIZE 4000 32 - 33 - #define PKS_FLUSH_MAX_TIMEOUT 5000 //msec 34 - #define PKS_FLUSH_SLEEP 10 //msec 35 - #define PKS_FLUSH_SLEEP_RANGE 400 24 + #include <asm/plpks.h> 25 + #include <asm/firmware.h> 36 26 37 27 static u8 *ospassword; 38 28 static u16 ospasswordlength; 39 29 40 30 // Retrieved with H_PKS_GET_CONFIG 31 + static u8 version; 32 + static u16 objoverhead; 41 33 static u16 maxpwsize; 42 34 static u16 maxobjsize; 35 + static s16 maxobjlabelsize; 36 + static u32 totalsize; 37 + static u32 usedspace; 38 + static u32 supportedpolicies; 39 + static u32 maxlargeobjectsize; 40 + static u64 signedupdatealgorithms; 43 41 44 42 struct plpks_auth { 45 43 u8 version; ··· 58 60 59 61 struct label { 60 62 struct label_attr attr; 61 - u8 name[MAX_NAME_SIZE]; 63 + u8 name[PLPKS_MAX_NAME_SIZE]; 62 64 size_t size; 63 65 }; 64 66 ··· 85 87 err = -ENOENT; 86 88 break; 87 89 case H_BUSY: 90 + case H_LONG_BUSY_ORDER_1_MSEC: 91 + case H_LONG_BUSY_ORDER_10_MSEC: 92 + case H_LONG_BUSY_ORDER_100_MSEC: 93 + case H_LONG_BUSY_ORDER_1_SEC: 94 + case H_LONG_BUSY_ORDER_10_SEC: 95 + case H_LONG_BUSY_ORDER_100_SEC: 88 96 err = -EBUSY; 89 97 break; 90 98 case H_AUTHORITY: ··· 121 117 err = -EINVAL; 122 118 } 123 119 120 + pr_debug("Converted hypervisor code %d to Linux %d\n", rc, err); 121 + 124 122 return err; 125 123 } 126 124 127 125 static int plpks_gen_password(void) 128 126 { 129 127 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 130 - u8 *password, consumer = PKS_OS_OWNER; 128 + u8 *password, consumer = PLPKS_OS_OWNER; 131 129 int rc; 132 130 133 - password = kzalloc(maxpwsize, GFP_KERNEL); 131 + // If we booted from kexec, we could be reusing an existing password already 132 + if (ospassword) { 133 + pr_debug("Password of length %u already in use\n", ospasswordlength); 134 + return 0; 135 + } 136 + 137 + // The password must not cross a page boundary, so we align to the next power of 2 138 + password = kzalloc(roundup_pow_of_two(maxpwsize), GFP_KERNEL); 134 139 if (!password) 135 140 return -ENOMEM; 136 141 ··· 156 143 memcpy(ospassword, password, ospasswordlength); 157 144 } else { 158 145 if (rc == H_IN_USE) { 159 - pr_warn("Password is already set for POWER LPAR Platform KeyStore\n"); 146 + pr_warn("Password already set - authenticated operations will fail\n"); 160 147 rc = 0; 161 148 } else { 162 149 goto out; ··· 172 159 { 173 160 struct plpks_auth *auth; 174 161 175 - if (consumer > PKS_OS_OWNER) 162 + if (consumer > PLPKS_OS_OWNER) 176 163 return ERR_PTR(-EINVAL); 177 164 178 - auth = kzalloc(struct_size(auth, password, maxpwsize), GFP_KERNEL); 165 + // The auth structure must not cross a page boundary and must be 166 + // 16 byte aligned. We align to the next largest power of 2 167 + auth = kzalloc(roundup_pow_of_two(struct_size(auth, password, maxpwsize)), GFP_KERNEL); 179 168 if (!auth) 180 169 return ERR_PTR(-ENOMEM); 181 170 182 171 auth->version = 1; 183 172 auth->consumer = consumer; 184 173 185 - if (consumer == PKS_FW_OWNER || consumer == PKS_BOOTLOADER_OWNER) 174 + if (consumer == PLPKS_FW_OWNER || consumer == PLPKS_BOOTLOADER_OWNER) 186 175 return auth; 187 176 188 177 memcpy(auth->password, ospassword, ospasswordlength); ··· 202 187 u16 namelen) 203 188 { 204 189 struct label *label; 205 - size_t slen; 190 + size_t slen = 0; 206 191 207 - if (!name || namelen > MAX_NAME_SIZE) 192 + if (!name || namelen > PLPKS_MAX_NAME_SIZE) 208 193 return ERR_PTR(-EINVAL); 209 194 210 - slen = strlen(component); 211 - if (component && slen > sizeof(label->attr.prefix)) 212 - return ERR_PTR(-EINVAL); 195 + // Support NULL component for signed updates 196 + if (component) { 197 + slen = strlen(component); 198 + if (slen > sizeof(label->attr.prefix)) 199 + return ERR_PTR(-EINVAL); 200 + } 213 201 214 - label = kzalloc(sizeof(*label), GFP_KERNEL); 202 + // The label structure must not cross a page boundary, so we align to the next power of 2 203 + label = kzalloc(roundup_pow_of_two(sizeof(*label)), GFP_KERNEL); 215 204 if (!label) 216 205 return ERR_PTR(-ENOMEM); 217 206 218 207 if (component) 219 208 memcpy(&label->attr.prefix, component, slen); 220 209 221 - label->attr.version = LABEL_VERSION; 210 + label->attr.version = PLPKS_LABEL_VERSION; 222 211 label->attr.os = varos; 223 - label->attr.length = MAX_LABEL_ATTR_SIZE; 212 + label->attr.length = PLPKS_MAX_LABEL_ATTR_SIZE; 224 213 memcpy(&label->name, name, namelen); 225 214 226 215 label->size = sizeof(struct label_attr) + namelen; ··· 235 216 static int _plpks_get_config(void) 236 217 { 237 218 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 238 - struct { 219 + struct config { 239 220 u8 version; 240 221 u8 flags; 241 - __be32 rsvd0; 222 + __be16 rsvd0; 223 + __be16 objoverhead; 242 224 __be16 maxpwsize; 243 225 __be16 maxobjlabelsize; 244 226 __be16 maxobjsize; 245 227 __be32 totalsize; 246 228 __be32 usedspace; 247 229 __be32 supportedpolicies; 248 - __be64 rsvd1; 249 - } __packed config; 230 + __be32 maxlargeobjectsize; 231 + __be64 signedupdatealgorithms; 232 + u8 rsvd1[476]; 233 + } __packed * config; 250 234 size_t size; 235 + int rc = 0; 236 + 237 + size = sizeof(*config); 238 + 239 + // Config struct must not cross a page boundary. So long as the struct 240 + // size is a power of 2, this should be fine as alignment is guaranteed 241 + config = kzalloc(size, GFP_KERNEL); 242 + if (!config) { 243 + rc = -ENOMEM; 244 + goto err; 245 + } 246 + 247 + rc = plpar_hcall(H_PKS_GET_CONFIG, retbuf, virt_to_phys(config), size); 248 + 249 + if (rc != H_SUCCESS) { 250 + rc = pseries_status_to_err(rc); 251 + goto err; 252 + } 253 + 254 + version = config->version; 255 + objoverhead = be16_to_cpu(config->objoverhead); 256 + maxpwsize = be16_to_cpu(config->maxpwsize); 257 + maxobjsize = be16_to_cpu(config->maxobjsize); 258 + maxobjlabelsize = be16_to_cpu(config->maxobjlabelsize); 259 + totalsize = be32_to_cpu(config->totalsize); 260 + usedspace = be32_to_cpu(config->usedspace); 261 + supportedpolicies = be32_to_cpu(config->supportedpolicies); 262 + maxlargeobjectsize = be32_to_cpu(config->maxlargeobjectsize); 263 + signedupdatealgorithms = be64_to_cpu(config->signedupdatealgorithms); 264 + 265 + // Validate that the numbers we get back match the requirements of the spec 266 + if (maxpwsize < 32) { 267 + pr_err("Invalid Max Password Size received from hypervisor (%d < 32)\n", maxpwsize); 268 + rc = -EIO; 269 + goto err; 270 + } 271 + 272 + if (maxobjlabelsize < 255) { 273 + pr_err("Invalid Max Object Label Size received from hypervisor (%d < 255)\n", 274 + maxobjlabelsize); 275 + rc = -EIO; 276 + goto err; 277 + } 278 + 279 + if (totalsize < 4096) { 280 + pr_err("Invalid Total Size received from hypervisor (%d < 4096)\n", totalsize); 281 + rc = -EIO; 282 + goto err; 283 + } 284 + 285 + if (version >= 3 && maxlargeobjectsize >= 65536 && maxobjsize != 0xFFFF) { 286 + pr_err("Invalid Max Object Size (0x%x != 0xFFFF)\n", maxobjsize); 287 + rc = -EIO; 288 + goto err; 289 + } 290 + 291 + err: 292 + kfree(config); 293 + return rc; 294 + } 295 + 296 + u8 plpks_get_version(void) 297 + { 298 + return version; 299 + } 300 + 301 + u16 plpks_get_objoverhead(void) 302 + { 303 + return objoverhead; 304 + } 305 + 306 + u16 plpks_get_maxpwsize(void) 307 + { 308 + return maxpwsize; 309 + } 310 + 311 + u16 plpks_get_maxobjectsize(void) 312 + { 313 + return maxobjsize; 314 + } 315 + 316 + u16 plpks_get_maxobjectlabelsize(void) 317 + { 318 + return maxobjlabelsize; 319 + } 320 + 321 + u32 plpks_get_totalsize(void) 322 + { 323 + return totalsize; 324 + } 325 + 326 + u32 plpks_get_usedspace(void) 327 + { 328 + // Unlike other config values, usedspace regularly changes as objects 329 + // are updated, so we need to refresh. 330 + int rc = _plpks_get_config(); 331 + if (rc) { 332 + pr_err("Couldn't get config, rc: %d\n", rc); 333 + return 0; 334 + } 335 + return usedspace; 336 + } 337 + 338 + u32 plpks_get_supportedpolicies(void) 339 + { 340 + return supportedpolicies; 341 + } 342 + 343 + u32 plpks_get_maxlargeobjectsize(void) 344 + { 345 + return maxlargeobjectsize; 346 + } 347 + 348 + u64 plpks_get_signedupdatealgorithms(void) 349 + { 350 + return signedupdatealgorithms; 351 + } 352 + 353 + u16 plpks_get_passwordlen(void) 354 + { 355 + return ospasswordlength; 356 + } 357 + 358 + bool plpks_is_available(void) 359 + { 251 360 int rc; 252 361 253 - size = sizeof(config); 362 + if (!firmware_has_feature(FW_FEATURE_LPAR)) 363 + return false; 254 364 255 - rc = plpar_hcall(H_PKS_GET_CONFIG, retbuf, virt_to_phys(&config), size); 365 + rc = _plpks_get_config(); 366 + if (rc) 367 + return false; 256 368 257 - if (rc != H_SUCCESS) 258 - return pseries_status_to_err(rc); 259 - 260 - maxpwsize = be16_to_cpu(config.maxpwsize); 261 - maxobjsize = be16_to_cpu(config.maxobjsize); 262 - 263 - return 0; 369 + return true; 264 370 } 265 371 266 372 static int plpks_confirm_object_flushed(struct label *label, 267 373 struct plpks_auth *auth) 268 374 { 269 375 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 376 + bool timed_out = true; 270 377 u64 timeout = 0; 271 378 u8 status; 272 379 int rc; ··· 404 259 405 260 status = retbuf[0]; 406 261 if (rc) { 262 + timed_out = false; 407 263 if (rc == H_NOT_FOUND && status == 1) 408 264 rc = 0; 409 265 break; 410 266 } 411 267 412 - if (!rc && status == 1) 268 + if (!rc && status == 1) { 269 + timed_out = false; 413 270 break; 271 + } 414 272 415 - usleep_range(PKS_FLUSH_SLEEP, 416 - PKS_FLUSH_SLEEP + PKS_FLUSH_SLEEP_RANGE); 417 - timeout = timeout + PKS_FLUSH_SLEEP; 418 - } while (timeout < PKS_FLUSH_MAX_TIMEOUT); 273 + usleep_range(PLPKS_FLUSH_SLEEP, 274 + PLPKS_FLUSH_SLEEP + PLPKS_FLUSH_SLEEP_RANGE); 275 + timeout = timeout + PLPKS_FLUSH_SLEEP; 276 + } while (timeout < PLPKS_MAX_TIMEOUT); 419 277 420 - rc = pseries_status_to_err(rc); 278 + if (timed_out) 279 + return -ETIMEDOUT; 280 + 281 + return pseries_status_to_err(rc); 282 + } 283 + 284 + int plpks_signed_update_var(struct plpks_var *var, u64 flags) 285 + { 286 + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; 287 + int rc; 288 + struct label *label; 289 + struct plpks_auth *auth; 290 + u64 continuetoken = 0; 291 + u64 timeout = 0; 292 + 293 + if (!var->data || var->datalen <= 0 || var->namelen > PLPKS_MAX_NAME_SIZE) 294 + return -EINVAL; 295 + 296 + if (!(var->policy & PLPKS_SIGNEDUPDATE)) 297 + return -EINVAL; 298 + 299 + // Signed updates need the component to be NULL. 300 + if (var->component) 301 + return -EINVAL; 302 + 303 + auth = construct_auth(PLPKS_OS_OWNER); 304 + if (IS_ERR(auth)) 305 + return PTR_ERR(auth); 306 + 307 + label = construct_label(var->component, var->os, var->name, var->namelen); 308 + if (IS_ERR(label)) { 309 + rc = PTR_ERR(label); 310 + goto out; 311 + } 312 + 313 + do { 314 + rc = plpar_hcall9(H_PKS_SIGNED_UPDATE, retbuf, 315 + virt_to_phys(auth), virt_to_phys(label), 316 + label->size, var->policy, flags, 317 + virt_to_phys(var->data), var->datalen, 318 + continuetoken); 319 + 320 + continuetoken = retbuf[0]; 321 + if (pseries_status_to_err(rc) == -EBUSY) { 322 + int delay_ms = get_longbusy_msecs(rc); 323 + mdelay(delay_ms); 324 + timeout += delay_ms; 325 + } 326 + rc = pseries_status_to_err(rc); 327 + } while (rc == -EBUSY && timeout < PLPKS_MAX_TIMEOUT); 328 + 329 + if (!rc) 330 + rc = plpks_confirm_object_flushed(label, auth); 331 + 332 + kfree(label); 333 + out: 334 + kfree(auth); 421 335 422 336 return rc; 423 337 } ··· 489 285 int rc; 490 286 491 287 if (!var.component || !var.data || var.datalen <= 0 || 492 - var.namelen > MAX_NAME_SIZE || var.datalen > MAX_DATA_SIZE) 288 + var.namelen > PLPKS_MAX_NAME_SIZE || var.datalen > PLPKS_MAX_DATA_SIZE) 493 289 return -EINVAL; 494 290 495 - if (var.policy & SIGNEDUPDATE) 291 + if (var.policy & PLPKS_SIGNEDUPDATE) 496 292 return -EINVAL; 497 293 498 - auth = construct_auth(PKS_OS_OWNER); 294 + auth = construct_auth(PLPKS_OS_OWNER); 499 295 if (IS_ERR(auth)) 500 296 return PTR_ERR(auth); 501 297 ··· 527 323 struct label *label; 528 324 int rc; 529 325 530 - if (!component || vname.namelen > MAX_NAME_SIZE) 326 + if (vname.namelen > PLPKS_MAX_NAME_SIZE) 531 327 return -EINVAL; 532 328 533 - auth = construct_auth(PKS_OS_OWNER); 329 + auth = construct_auth(PLPKS_OS_OWNER); 534 330 if (IS_ERR(auth)) 535 331 return PTR_ERR(auth); 536 332 ··· 562 358 u8 *output; 563 359 int rc; 564 360 565 - if (var->namelen > MAX_NAME_SIZE) 361 + if (var->namelen > PLPKS_MAX_NAME_SIZE) 566 362 return -EINVAL; 567 363 568 364 auth = construct_auth(consumer); 569 365 if (IS_ERR(auth)) 570 366 return PTR_ERR(auth); 571 367 572 - if (consumer == PKS_OS_OWNER) { 368 + if (consumer == PLPKS_OS_OWNER) { 573 369 label = construct_label(var->component, var->os, var->name, 574 370 var->namelen); 575 371 if (IS_ERR(label)) { ··· 584 380 goto out_free_label; 585 381 } 586 382 587 - if (consumer == PKS_OS_OWNER) 383 + if (consumer == PLPKS_OS_OWNER) 588 384 rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth), 589 385 virt_to_phys(label), label->size, virt_to_phys(output), 590 386 maxobjsize); ··· 599 395 goto out_free_output; 600 396 } 601 397 602 - if (var->datalen == 0 || var->datalen > retbuf[0]) 398 + if (!var->data || var->datalen > retbuf[0]) 603 399 var->datalen = retbuf[0]; 604 400 605 - var->data = kzalloc(var->datalen, GFP_KERNEL); 606 - if (!var->data) { 607 - rc = -ENOMEM; 608 - goto out_free_output; 609 - } 610 401 var->policy = retbuf[1]; 611 402 612 - memcpy(var->data, output, var->datalen); 403 + if (var->data) 404 + memcpy(var->data, output, var->datalen); 405 + 613 406 rc = 0; 614 407 615 408 out_free_output: ··· 621 420 622 421 int plpks_read_os_var(struct plpks_var *var) 623 422 { 624 - return plpks_read_var(PKS_OS_OWNER, var); 423 + return plpks_read_var(PLPKS_OS_OWNER, var); 625 424 } 626 425 627 426 int plpks_read_fw_var(struct plpks_var *var) 628 427 { 629 - return plpks_read_var(PKS_FW_OWNER, var); 428 + return plpks_read_var(PLPKS_FW_OWNER, var); 630 429 } 631 430 632 431 int plpks_read_bootloader_var(struct plpks_var *var) 633 432 { 634 - return plpks_read_var(PKS_BOOTLOADER_OWNER, var); 433 + return plpks_read_var(PLPKS_BOOTLOADER_OWNER, var); 434 + } 435 + 436 + int plpks_populate_fdt(void *fdt) 437 + { 438 + int chosen_offset = fdt_path_offset(fdt, "/chosen"); 439 + 440 + if (chosen_offset < 0) { 441 + pr_err("Can't find chosen node: %s\n", 442 + fdt_strerror(chosen_offset)); 443 + return chosen_offset; 444 + } 445 + 446 + return fdt_setprop(fdt, chosen_offset, "ibm,plpks-pw", ospassword, ospasswordlength); 447 + } 448 + 449 + // Once a password is registered with the hypervisor it cannot be cleared without 450 + // rebooting the LPAR, so to keep using the PLPKS across kexec boots we need to 451 + // recover the previous password from the FDT. 452 + // 453 + // There are a few challenges here. We don't want the password to be visible to 454 + // users, so we need to clear it from the FDT. This has to be done in early boot. 455 + // Clearing it from the FDT would make the FDT's checksum invalid, so we have to 456 + // manually cause the checksum to be recalculated. 457 + void __init plpks_early_init_devtree(void) 458 + { 459 + void *fdt = initial_boot_params; 460 + int chosen_node = fdt_path_offset(fdt, "/chosen"); 461 + const u8 *password; 462 + int len; 463 + 464 + if (chosen_node < 0) 465 + return; 466 + 467 + password = fdt_getprop(fdt, chosen_node, "ibm,plpks-pw", &len); 468 + if (len <= 0) { 469 + pr_debug("Couldn't find ibm,plpks-pw node.\n"); 470 + return; 471 + } 472 + 473 + ospassword = memblock_alloc_raw(len, SMP_CACHE_BYTES); 474 + if (!ospassword) { 475 + pr_err("Error allocating memory for password.\n"); 476 + goto out; 477 + } 478 + 479 + memcpy(ospassword, password, len); 480 + ospasswordlength = (u16)len; 481 + 482 + out: 483 + fdt_nop_property(fdt, chosen_node, "ibm,plpks-pw"); 484 + // Since we've cleared the password, we must update the FDT checksum 485 + early_init_dt_verify(fdt); 635 486 } 636 487 637 488 static __init int pseries_plpks_init(void)
-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 0x02 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
+1 -1
arch/powerpc/platforms/pseries/ras.c
··· 155 155 { 156 156 struct device_node *np; 157 157 158 - ras_check_exception_token = rtas_token("check-exception"); 158 + ras_check_exception_token = rtas_function_token(RTAS_FN_CHECK_EXCEPTION); 159 159 160 160 /* Internal Errors */ 161 161 np = of_find_node_by_path("/event-sources/internal-errors");
+209
arch/powerpc/platforms/pseries/rtas-work-area.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #define pr_fmt(fmt) "rtas-work-area: " fmt 4 + 5 + #include <linux/genalloc.h> 6 + #include <linux/log2.h> 7 + #include <linux/kernel.h> 8 + #include <linux/memblock.h> 9 + #include <linux/mempool.h> 10 + #include <linux/minmax.h> 11 + #include <linux/mutex.h> 12 + #include <linux/numa.h> 13 + #include <linux/sizes.h> 14 + #include <linux/wait.h> 15 + 16 + #include <asm/machdep.h> 17 + #include <asm/rtas-work-area.h> 18 + #include <asm/rtas.h> 19 + 20 + enum { 21 + /* 22 + * Ensure the pool is page-aligned. 23 + */ 24 + RTAS_WORK_AREA_ARENA_ALIGN = PAGE_SIZE, 25 + /* 26 + * Don't let a single allocation claim the whole arena. 27 + */ 28 + RTAS_WORK_AREA_ARENA_SZ = RTAS_WORK_AREA_MAX_ALLOC_SZ * 2, 29 + /* 30 + * The smallest known work area size is for ibm,get-vpd's 31 + * location code argument, which is limited to 79 characters 32 + * plus 1 nul terminator. 33 + * 34 + * PAPR+ 7.3.20 ibm,get-vpd RTAS Call 35 + * PAPR+ 12.3.2.4 Converged Location Code Rules - Length Restrictions 36 + */ 37 + RTAS_WORK_AREA_MIN_ALLOC_SZ = roundup_pow_of_two(80), 38 + }; 39 + 40 + static struct { 41 + struct gen_pool *gen_pool; 42 + char *arena; 43 + struct mutex mutex; /* serializes allocations */ 44 + struct wait_queue_head wqh; 45 + mempool_t descriptor_pool; 46 + bool available; 47 + } rwa_state = { 48 + .mutex = __MUTEX_INITIALIZER(rwa_state.mutex), 49 + .wqh = __WAIT_QUEUE_HEAD_INITIALIZER(rwa_state.wqh), 50 + }; 51 + 52 + /* 53 + * A single work area buffer and descriptor to serve requests early in 54 + * boot before the allocator is fully initialized. We know 4KB is the 55 + * most any boot time user needs (they all call ibm,get-system-parameter). 56 + */ 57 + static bool early_work_area_in_use __initdata; 58 + static char early_work_area_buf[SZ_4K] __initdata __aligned(SZ_4K); 59 + static struct rtas_work_area early_work_area __initdata = { 60 + .buf = early_work_area_buf, 61 + .size = sizeof(early_work_area_buf), 62 + }; 63 + 64 + 65 + static struct rtas_work_area * __init rtas_work_area_alloc_early(size_t size) 66 + { 67 + WARN_ON(size > early_work_area.size); 68 + WARN_ON(early_work_area_in_use); 69 + early_work_area_in_use = true; 70 + memset(early_work_area.buf, 0, early_work_area.size); 71 + return &early_work_area; 72 + } 73 + 74 + static void __init rtas_work_area_free_early(struct rtas_work_area *work_area) 75 + { 76 + WARN_ON(work_area != &early_work_area); 77 + WARN_ON(!early_work_area_in_use); 78 + early_work_area_in_use = false; 79 + } 80 + 81 + struct rtas_work_area * __ref __rtas_work_area_alloc(size_t size) 82 + { 83 + struct rtas_work_area *area; 84 + unsigned long addr; 85 + 86 + might_sleep(); 87 + 88 + /* 89 + * The rtas_work_area_alloc() wrapper enforces this at build 90 + * time. Requests that exceed the arena size will block 91 + * indefinitely. 92 + */ 93 + WARN_ON(size > RTAS_WORK_AREA_MAX_ALLOC_SZ); 94 + 95 + if (!rwa_state.available) 96 + return rtas_work_area_alloc_early(size); 97 + /* 98 + * To ensure FCFS behavior and prevent a high rate of smaller 99 + * requests from starving larger ones, use the mutex to queue 100 + * allocations. 101 + */ 102 + mutex_lock(&rwa_state.mutex); 103 + wait_event(rwa_state.wqh, 104 + (addr = gen_pool_alloc(rwa_state.gen_pool, size)) != 0); 105 + mutex_unlock(&rwa_state.mutex); 106 + 107 + area = mempool_alloc(&rwa_state.descriptor_pool, GFP_KERNEL); 108 + area->buf = (char *)addr; 109 + area->size = size; 110 + 111 + return area; 112 + } 113 + 114 + void __ref rtas_work_area_free(struct rtas_work_area *area) 115 + { 116 + if (!rwa_state.available) { 117 + rtas_work_area_free_early(area); 118 + return; 119 + } 120 + 121 + gen_pool_free(rwa_state.gen_pool, (unsigned long)area->buf, area->size); 122 + mempool_free(area, &rwa_state.descriptor_pool); 123 + wake_up(&rwa_state.wqh); 124 + } 125 + 126 + /* 127 + * Initialization of the work area allocator happens in two parts. To 128 + * reliably reserve an arena that satisfies RTAS addressing 129 + * requirements, we must perform a memblock allocation early, 130 + * immmediately after RTAS instantiation. Then we have to wait until 131 + * the slab allocator is up before setting up the descriptor mempool 132 + * and adding the arena to a gen_pool. 133 + */ 134 + static __init int rtas_work_area_allocator_init(void) 135 + { 136 + const unsigned int order = ilog2(RTAS_WORK_AREA_MIN_ALLOC_SZ); 137 + const phys_addr_t pa_start = __pa(rwa_state.arena); 138 + const phys_addr_t pa_end = pa_start + RTAS_WORK_AREA_ARENA_SZ - 1; 139 + struct gen_pool *pool; 140 + const int nid = NUMA_NO_NODE; 141 + int err; 142 + 143 + err = -ENOMEM; 144 + if (!rwa_state.arena) 145 + goto err_out; 146 + 147 + pool = gen_pool_create(order, nid); 148 + if (!pool) 149 + goto err_out; 150 + /* 151 + * All RTAS functions that consume work areas are OK with 152 + * natural alignment, when they have alignment requirements at 153 + * all. 154 + */ 155 + gen_pool_set_algo(pool, gen_pool_first_fit_order_align, NULL); 156 + 157 + err = gen_pool_add(pool, (unsigned long)rwa_state.arena, 158 + RTAS_WORK_AREA_ARENA_SZ, nid); 159 + if (err) 160 + goto err_destroy; 161 + 162 + err = mempool_init_kmalloc_pool(&rwa_state.descriptor_pool, 1, 163 + sizeof(struct rtas_work_area)); 164 + if (err) 165 + goto err_destroy; 166 + 167 + rwa_state.gen_pool = pool; 168 + rwa_state.available = true; 169 + 170 + pr_debug("arena [%pa-%pa] (%uK), min/max alloc sizes %u/%u\n", 171 + &pa_start, &pa_end, 172 + RTAS_WORK_AREA_ARENA_SZ / SZ_1K, 173 + RTAS_WORK_AREA_MIN_ALLOC_SZ, 174 + RTAS_WORK_AREA_MAX_ALLOC_SZ); 175 + 176 + return 0; 177 + 178 + err_destroy: 179 + gen_pool_destroy(pool); 180 + err_out: 181 + return err; 182 + } 183 + machine_arch_initcall(pseries, rtas_work_area_allocator_init); 184 + 185 + /** 186 + * rtas_work_area_reserve_arena() - Reserve memory suitable for RTAS work areas. 187 + */ 188 + void __init rtas_work_area_reserve_arena(const phys_addr_t limit) 189 + { 190 + const phys_addr_t align = RTAS_WORK_AREA_ARENA_ALIGN; 191 + const phys_addr_t size = RTAS_WORK_AREA_ARENA_SZ; 192 + const phys_addr_t min = MEMBLOCK_LOW_LIMIT; 193 + const int nid = NUMA_NO_NODE; 194 + 195 + /* 196 + * Too early for a machine_is(pseries) check. But PAPR 197 + * effectively mandates that ibm,get-system-parameter is 198 + * present: 199 + * 200 + * R1–7.3.16–1. All platforms must support the System 201 + * Parameters option. 202 + * 203 + * So set up the arena if we find that, with a fallback to 204 + * ibm,configure-connector, just in case. 205 + */ 206 + if (rtas_function_implemented(RTAS_FN_IBM_GET_SYSTEM_PARAMETER) || 207 + rtas_function_implemented(RTAS_FN_IBM_CONFIGURE_CONNECTOR)) 208 + rwa_state.arena = memblock_alloc_try_nid(size, align, min, limit, nid); 209 + }
+10 -17
arch/powerpc/platforms/pseries/setup.c
··· 57 57 #include <asm/pmc.h> 58 58 #include <asm/xics.h> 59 59 #include <asm/xive.h> 60 + #include <asm/papr-sysparm.h> 60 61 #include <asm/ppc-pci.h> 61 62 #include <asm/i8259.h> 62 63 #include <asm/udbg.h> ··· 136 135 #endif 137 136 int ibm_nmi_register_token; 138 137 139 - ibm_nmi_register_token = rtas_token("ibm,nmi-register"); 138 + ibm_nmi_register_token = rtas_function_token(RTAS_FN_IBM_NMI_REGISTER); 140 139 if (ibm_nmi_register_token == RTAS_UNKNOWN_SERVICE) 141 140 return; 142 141 143 - ibm_nmi_interlock_token = rtas_token("ibm,nmi-interlock"); 142 + ibm_nmi_interlock_token = rtas_function_token(RTAS_FN_IBM_NMI_INTERLOCK); 144 143 if (WARN_ON(ibm_nmi_interlock_token == RTAS_UNKNOWN_SERVICE)) 145 144 return; 146 145 ··· 942 941 */ 943 942 static void __init pSeries_cmo_feature_init(void) 944 943 { 944 + static struct papr_sysparm_buf buf __initdata; 945 + static_assert(sizeof(buf.val) >= CMO_MAXLENGTH); 945 946 char *ptr, *key, *value, *end; 946 - int call_status; 947 947 int page_order = IOMMU_PAGE_SHIFT_4K; 948 948 949 949 pr_debug(" -> fw_cmo_feature_init()\n"); 950 - spin_lock(&rtas_data_buf_lock); 951 - memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE); 952 - call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, 953 - NULL, 954 - CMO_CHARACTERISTICS_TOKEN, 955 - __pa(rtas_data_buf), 956 - RTAS_DATA_BUF_SIZE); 957 950 958 - if (call_status != 0) { 959 - spin_unlock(&rtas_data_buf_lock); 951 + if (papr_sysparm_get(PAPR_SYSPARM_COOP_MEM_OVERCOMMIT_ATTRS, &buf)) { 960 952 pr_debug("CMO not available\n"); 961 953 pr_debug(" <- fw_cmo_feature_init()\n"); 962 954 return; 963 955 } 964 956 965 - end = rtas_data_buf + CMO_MAXLENGTH - 2; 966 - ptr = rtas_data_buf + 2; /* step over strlen value */ 957 + end = &buf.val[CMO_MAXLENGTH]; 958 + ptr = &buf.val[0]; 967 959 key = value = ptr; 968 960 969 961 while (*ptr && (ptr <= end)) { ··· 1002 1008 } else 1003 1009 pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP, 1004 1010 CMO_SecPSP); 1005 - spin_unlock(&rtas_data_buf_lock); 1006 1011 pr_debug(" <- fw_cmo_feature_init()\n"); 1007 1012 } 1008 1013 ··· 1071 1078 static void pseries_power_off(void) 1072 1079 { 1073 1080 int rc; 1074 - int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups"); 1081 + int rtas_poweroff_ups_token = rtas_function_token(RTAS_FN_IBM_POWER_OFF_UPS); 1075 1082 1076 1083 if (rtas_flash_term_hook) 1077 1084 rtas_flash_term_hook(SYS_POWER_OFF); 1078 1085 1079 1086 if (rtas_poweron_auto == 0 || 1080 1087 rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) { 1081 - rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1); 1088 + rc = rtas_call(rtas_function_token(RTAS_FN_POWER_OFF), 2, 1, NULL, -1, -1); 1082 1089 printk(KERN_INFO "RTAS power-off returned %d\n", rc); 1083 1090 } else { 1084 1091 rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL);
+3 -9
arch/powerpc/platforms/pseries/smp.c
··· 55 55 int smp_query_cpu_stopped(unsigned int pcpu) 56 56 { 57 57 int cpu_status, status; 58 - int qcss_tok = rtas_token("query-cpu-stopped-state"); 58 + int qcss_tok = rtas_function_token(RTAS_FN_QUERY_CPU_STOPPED_STATE); 59 59 60 60 if (qcss_tok == RTAS_UNKNOWN_SERVICE) { 61 61 printk_once(KERN_INFO ··· 108 108 * If the RTAS start-cpu token does not exist then presume the 109 109 * cpu is already spinning. 110 110 */ 111 - start_cpu = rtas_token("start-cpu"); 111 + start_cpu = rtas_function_token(RTAS_FN_START_CPU); 112 112 if (start_cpu == RTAS_UNKNOWN_SERVICE) 113 113 return 1; 114 114 ··· 266 266 * We know prom_init will not have started them if RTAS supports 267 267 * query-cpu-stopped-state. 268 268 */ 269 - if (rtas_token("query-cpu-stopped-state") == RTAS_UNKNOWN_SERVICE) { 269 + if (rtas_function_token(RTAS_FN_QUERY_CPU_STOPPED_STATE) == RTAS_UNKNOWN_SERVICE) { 270 270 if (cpu_has_feature(CPU_FTR_SMT)) { 271 271 for_each_present_cpu(i) { 272 272 if (cpu_thread_in_core(i) == 0) ··· 276 276 cpumask_copy(of_spin_mask, cpu_present_mask); 277 277 278 278 cpumask_clear_cpu(boot_cpuid, of_spin_mask); 279 - } 280 - 281 - /* Non-lpar has additional take/give timebase */ 282 - if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { 283 - smp_ops->give_timebase = rtas_give_timebase; 284 - smp_ops->take_timebase = rtas_take_timebase; 285 279 } 286 280 287 281 pr_debug(" <- smp_init_pSeries()\n");
+1
arch/powerpc/purgatory/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 3 3 KASAN_SANITIZE := n 4 + KCSAN_SANITIZE := n 4 5 5 6 targets += trampoline_$(BITS).o purgatory.ro 6 7
+4 -4
arch/powerpc/sysdev/xics/ics-rtas.c
··· 200 200 201 201 __init int ics_rtas_init(void) 202 202 { 203 - ibm_get_xive = rtas_token("ibm,get-xive"); 204 - ibm_set_xive = rtas_token("ibm,set-xive"); 205 - ibm_int_on = rtas_token("ibm,int-on"); 206 - ibm_int_off = rtas_token("ibm,int-off"); 203 + ibm_get_xive = rtas_function_token(RTAS_FN_IBM_GET_XIVE); 204 + ibm_set_xive = rtas_function_token(RTAS_FN_IBM_SET_XIVE); 205 + ibm_int_on = rtas_function_token(RTAS_FN_IBM_INT_ON); 206 + ibm_int_off = rtas_function_token(RTAS_FN_IBM_INT_OFF); 207 207 208 208 /* We enable the RTAS "ICS" if RTAS is present with the 209 209 * appropriate tokens
+1
arch/powerpc/xmon/Makefile
··· 5 5 KCOV_INSTRUMENT := n 6 6 UBSAN_SANITIZE := n 7 7 KASAN_SANITIZE := n 8 + KCSAN_SANITIZE := n 8 9 9 10 # Disable ftrace for the entire directory 10 11 ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE)
+3 -13
arch/powerpc/xmon/xmon.c
··· 76 76 #define xmon_owner 0 77 77 #endif /* CONFIG_SMP */ 78 78 79 - #ifdef CONFIG_PPC_PSERIES 80 - static int set_indicator_token = RTAS_UNKNOWN_SERVICE; 81 - #endif 82 79 static unsigned long in_xmon __read_mostly = 0; 83 80 static int xmon_on = IS_ENABLED(CONFIG_XMON_DEFAULT); 84 81 static bool xmon_is_ro = IS_ENABLED(CONFIG_XMON_DEFAULT_RO_MODE); ··· 395 398 #ifdef CONFIG_PPC_PSERIES 396 399 /* Since this can't be a module, args should end up below 4GB. */ 397 400 static struct rtas_args args; 401 + const s32 token = rtas_function_token(RTAS_FN_SET_INDICATOR); 398 402 399 403 /* 400 404 * At this point we have got all the cpus we can into ··· 404 406 * If we did try to take rtas.lock there would be a 405 407 * real possibility of deadlock. 406 408 */ 407 - if (set_indicator_token == RTAS_UNKNOWN_SERVICE) 409 + if (token == RTAS_UNKNOWN_SERVICE) 408 410 return; 409 411 410 - rtas_call_unlocked(&args, set_indicator_token, 3, 1, NULL, 412 + rtas_call_unlocked(&args, token, 3, 1, NULL, 411 413 SURVEILLANCE_TOKEN, 0, 0); 412 414 413 415 #endif /* CONFIG_PPC_PSERIES */ ··· 3974 3976 __debugger_iabr_match = xmon_iabr_match; 3975 3977 __debugger_break_match = xmon_break_match; 3976 3978 __debugger_fault_handler = xmon_fault_handler; 3977 - 3978 - #ifdef CONFIG_PPC_PSERIES 3979 - /* 3980 - * Get the token here to avoid trying to get a lock 3981 - * during the crash, causing a deadlock. 3982 - */ 3983 - set_indicator_token = rtas_token("set-indicator"); 3984 - #endif 3985 3979 } else { 3986 3980 __debugger = NULL; 3987 3981 __debugger_ipi = NULL;
+2 -2
drivers/macintosh/windfarm_lm75_sensor.c
··· 33 33 #endif 34 34 35 35 struct wf_lm75_sensor { 36 - int ds1775 : 1; 37 - int inited : 1; 36 + unsigned int ds1775 : 1; 37 + unsigned int inited : 1; 38 38 struct i2c_client *i2c; 39 39 struct wf_sensor sens; 40 40 };
+2 -2
drivers/macintosh/windfarm_smu_sensors.c
··· 274 274 struct list_head link; 275 275 struct wf_sensor *volts; 276 276 struct wf_sensor *amps; 277 - int fake_volts : 1; 278 - int quadratic : 1; 277 + unsigned int fake_volts : 1; 278 + unsigned int quadratic : 1; 279 279 struct wf_sensor sens; 280 280 }; 281 281 #define to_smu_cpu_power(c) container_of(c, struct smu_cpu_power_sensor, sens)
+32 -15
security/integrity/platform_certs/load_powerpc.c
··· 10 10 #include <linux/cred.h> 11 11 #include <linux/err.h> 12 12 #include <linux/slab.h> 13 - #include <linux/of.h> 14 13 #include <asm/secure_boot.h> 15 14 #include <asm/secvar.h> 16 15 #include "keyring_handler.h" 16 + #include "../integrity.h" 17 17 18 18 /* 19 19 * Get a certificate list blob from the named secure variable. 20 + * 21 + * Returns: 22 + * - a pointer to a kmalloc'd buffer containing the cert list on success 23 + * - NULL if the key does not exist 24 + * - an ERR_PTR on error 20 25 */ 21 - static __init void *get_cert_list(u8 *key, unsigned long keylen, uint64_t *size) 26 + static __init void *get_cert_list(u8 *key, unsigned long keylen, u64 *size) 22 27 { 23 28 int rc; 24 29 void *db; 25 30 26 31 rc = secvar_ops->get(key, keylen, NULL, size); 27 32 if (rc) { 28 - pr_err("Couldn't get size: %d\n", rc); 29 - return NULL; 33 + if (rc == -ENOENT) 34 + return NULL; 35 + return ERR_PTR(rc); 30 36 } 31 37 32 38 db = kmalloc(*size, GFP_KERNEL); 33 39 if (!db) 34 - return NULL; 40 + return ERR_PTR(-ENOMEM); 35 41 36 42 rc = secvar_ops->get(key, keylen, db, size); 37 43 if (rc) { 38 44 kfree(db); 39 - pr_err("Error reading %s var: %d\n", key, rc); 40 - return NULL; 45 + return ERR_PTR(rc); 41 46 } 42 47 43 48 return db; ··· 56 51 static int __init load_powerpc_certs(void) 57 52 { 58 53 void *db = NULL, *dbx = NULL; 59 - uint64_t dbsize = 0, dbxsize = 0; 54 + u64 dbsize = 0, dbxsize = 0; 60 55 int rc = 0; 61 - struct device_node *node; 56 + ssize_t len; 57 + char buf[32]; 62 58 63 59 if (!secvar_ops) 64 60 return -ENODEV; 65 61 66 - /* The following only applies for the edk2-compat backend. */ 67 - node = of_find_compatible_node(NULL, NULL, "ibm,edk2-compat-v1"); 68 - if (!node) 62 + len = secvar_ops->format(buf, sizeof(buf)); 63 + if (len <= 0) 69 64 return -ENODEV; 65 + 66 + // Check for known secure boot implementations from OPAL or PLPKS 67 + if (strcmp("ibm,edk2-compat-v1", buf) && strcmp("ibm,plpks-sb-v1", buf)) { 68 + pr_err("Unsupported secvar implementation \"%s\", not loading certs\n", buf); 69 + return -ENODEV; 70 + } 70 71 71 72 /* 72 73 * Get db, and dbx. They might not exist, so it isn't an error if we ··· 80 69 */ 81 70 db = get_cert_list("db", 3, &dbsize); 82 71 if (!db) { 83 - pr_err("Couldn't get db list from firmware\n"); 72 + pr_info("Couldn't get db list from firmware\n"); 73 + } else if (IS_ERR(db)) { 74 + rc = PTR_ERR(db); 75 + pr_err("Error reading db from firmware: %d\n", rc); 76 + return rc; 84 77 } else { 85 78 rc = parse_efi_signature_list("powerpc:db", db, dbsize, 86 79 get_handler_for_db); ··· 96 81 dbx = get_cert_list("dbx", 4, &dbxsize); 97 82 if (!dbx) { 98 83 pr_info("Couldn't get dbx list from firmware\n"); 84 + } else if (IS_ERR(dbx)) { 85 + rc = PTR_ERR(dbx); 86 + pr_err("Error reading dbx from firmware: %d\n", rc); 87 + return rc; 99 88 } else { 100 89 rc = parse_efi_signature_list("powerpc:dbx", dbx, dbxsize, 101 90 get_handler_for_dbx); ··· 107 88 pr_err("Couldn't parse dbx signatures: %d\n", rc); 108 89 kfree(dbx); 109 90 } 110 - 111 - of_node_put(node); 112 91 113 92 return rc; 114 93 }
+6 -28
tools/testing/selftests/powerpc/dscr/dscr.h
··· 64 64 /* Default DSCR access */ 65 65 unsigned long get_default_dscr(void) 66 66 { 67 - int fd = -1, ret; 68 - char buf[16]; 67 + int err; 69 68 unsigned long val; 70 69 71 - if (fd == -1) { 72 - fd = open(DSCR_DEFAULT, O_RDONLY); 73 - if (fd == -1) { 74 - perror("open() failed"); 75 - exit(1); 76 - } 77 - } 78 - memset(buf, 0, sizeof(buf)); 79 - lseek(fd, 0, SEEK_SET); 80 - ret = read(fd, buf, sizeof(buf)); 81 - if (ret == -1) { 70 + err = read_ulong(DSCR_DEFAULT, &val, 16); 71 + if (err) { 82 72 perror("read() failed"); 83 73 exit(1); 84 74 } 85 - sscanf(buf, "%lx", &val); 86 - close(fd); 87 75 return val; 88 76 } 89 77 90 78 void set_default_dscr(unsigned long val) 91 79 { 92 - int fd = -1, ret; 93 - char buf[16]; 80 + int err; 94 81 95 - if (fd == -1) { 96 - fd = open(DSCR_DEFAULT, O_RDWR); 97 - if (fd == -1) { 98 - perror("open() failed"); 99 - exit(1); 100 - } 101 - } 102 - sprintf(buf, "%lx\n", val); 103 - ret = write(fd, buf, strlen(buf)); 104 - if (ret == -1) { 82 + err = write_ulong(DSCR_DEFAULT, val, 16); 83 + if (err) { 105 84 perror("write() failed"); 106 85 exit(1); 107 86 } 108 - close(fd); 109 87 } 110 88 111 89 double uniform_deviate(int seed)
+7 -18
tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
··· 12 12 13 13 static int check_cpu_dscr_default(char *file, unsigned long val) 14 14 { 15 - char buf[10]; 16 - int fd, rc; 15 + unsigned long cpu_dscr; 16 + int err; 17 17 18 - fd = open(file, O_RDWR); 19 - if (fd == -1) { 20 - perror("open() failed"); 21 - return 1; 22 - } 18 + err = read_ulong(file, &cpu_dscr, 16); 19 + if (err) 20 + return err; 23 21 24 - rc = read(fd, buf, sizeof(buf)); 25 - if (rc == -1) { 26 - perror("read() failed"); 27 - close(fd); 28 - return 1; 29 - } 30 - close(fd); 31 - 32 - buf[rc] = '\0'; 33 - if (strtol(buf, NULL, 16) != val) { 22 + if (cpu_dscr != val) { 34 23 printf("DSCR match failed: %ld (system) %ld (cpu)\n", 35 - val, strtol(buf, NULL, 16)); 24 + val, cpu_dscr); 36 25 return 1; 37 26 } 38 27 return 0;
+18 -2
tools/testing/selftests/powerpc/include/utils.h
··· 33 33 34 34 int pick_online_cpu(void); 35 35 36 - int read_debugfs_file(char *debugfs_file, int *result); 37 - int write_debugfs_file(char *debugfs_file, int result); 36 + int parse_intmax(const char *buffer, size_t count, intmax_t *result, int base); 37 + int parse_uintmax(const char *buffer, size_t count, uintmax_t *result, int base); 38 + int parse_int(const char *buffer, size_t count, int *result, int base); 39 + int parse_uint(const char *buffer, size_t count, unsigned int *result, int base); 40 + int parse_long(const char *buffer, size_t count, long *result, int base); 41 + int parse_ulong(const char *buffer, size_t count, unsigned long *result, int base); 42 + 43 + int read_file(const char *path, char *buf, size_t count, size_t *len); 44 + int write_file(const char *path, const char *buf, size_t count); 45 + int read_file_alloc(const char *path, char **buf, size_t *len); 46 + int read_long(const char *path, long *result, int base); 47 + int write_long(const char *path, long result, int base); 48 + int read_ulong(const char *path, unsigned long *result, int base); 49 + int write_ulong(const char *path, unsigned long result, int base); 50 + int read_debugfs_file(const char *debugfs_file, char *buf, size_t count); 51 + int write_debugfs_file(const char *debugfs_file, const char *buf, size_t count); 52 + int read_debugfs_int(const char *debugfs_file, int *result); 53 + int write_debugfs_int(const char *debugfs_file, int result); 38 54 int read_sysfs_file(char *debugfs_file, char *result, size_t result_size); 39 55 int perf_event_open_counter(unsigned int type, 40 56 unsigned long config, int group_fd);
+2 -50
tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
··· 143 143 return i; 144 144 } 145 145 146 - /* Caller must free the allocated buffer return nonzero on error. */ 147 - int read_alloc_input_file(char *fname, char **buf, size_t *bufsize) 148 - { 149 - struct stat statbuf; 150 - FILE *fp; 151 - char *p; 152 - size_t num_bytes; 153 - 154 - if (stat(fname, &statbuf)) { 155 - perror(fname); 156 - return(-1); 157 - } 158 - fp = fopen(fname, "r"); 159 - if (fp == NULL) { 160 - perror(fname); 161 - return(-1); 162 - } 163 - assert(NULL != (p = (char *) malloc(statbuf.st_size))); 164 - num_bytes = fread(p, 1, statbuf.st_size, fp); 165 - if (ferror(fp) || (num_bytes != statbuf.st_size)) { 166 - perror(fname); 167 - return(-1); 168 - } 169 - *buf = p; 170 - *bufsize = num_bytes; 171 - return 0; 172 - } 173 - 174 - /* Returns nonzero on error */ 175 - int write_output_file(char *fname, char *buf, size_t bufsize) 176 - { 177 - FILE *fp; 178 - size_t num_bytes; 179 - 180 - fp = fopen(fname, "w"); 181 - if (fp == NULL) { 182 - perror(fname); 183 - return(-1); 184 - } 185 - num_bytes = fwrite(buf, 1, bufsize, fp); 186 - if (ferror(fp) || (num_bytes != bufsize)) { 187 - perror(fname); 188 - return(-1); 189 - } 190 - fclose(fp); 191 - return 0; 192 - } 193 - 194 146 /* 195 147 * Z_SYNC_FLUSH as described in zlib.h. 196 148 * Returns number of appended bytes ··· 209 257 fprintf(stderr, "usage: %s <fname>\n", argv[0]); 210 258 exit(-1); 211 259 } 212 - if (read_alloc_input_file(argv[1], &inbuf, &inlen)) 260 + if (read_file_alloc(argv[1], &inbuf, &inlen)) 213 261 exit(-1); 214 262 fprintf(stderr, "file %s read, %ld bytes\n", argv[1], inlen); 215 263 ··· 351 399 assert(FNAME_MAX > (strlen(argv[1]) + strlen(FEXT))); 352 400 strcpy(outname, argv[1]); 353 401 strcat(outname, FEXT); 354 - if (write_output_file(outname, outbuf, dsttotlen)) { 402 + if (write_file(outname, outbuf, dsttotlen)) { 355 403 fprintf(stderr, "write error: %s\n", outname); 356 404 exit(-1); 357 405 }
+5 -29
tools/testing/selftests/powerpc/pmu/lib.c
··· 190 190 191 191 bool require_paranoia_below(int level) 192 192 { 193 + int err; 193 194 long current; 194 - char *end, buf[16]; 195 - FILE *f; 196 - bool rc; 197 195 198 - rc = false; 199 - 200 - f = fopen(PARANOID_PATH, "r"); 201 - if (!f) { 202 - perror("fopen"); 203 - goto out; 204 - } 205 - 206 - if (!fgets(buf, sizeof(buf), f)) { 207 - printf("Couldn't read " PARANOID_PATH "?\n"); 208 - goto out_close; 209 - } 210 - 211 - current = strtol(buf, &end, 10); 212 - 213 - if (end == buf) { 196 + err = read_long(PARANOID_PATH, &current, 10); 197 + if (err) { 214 198 printf("Couldn't parse " PARANOID_PATH "?\n"); 215 - goto out_close; 199 + return false; 216 200 } 217 201 218 - if (current >= level) 219 - goto out_close; 220 - 221 - rc = true; 222 - out_close: 223 - fclose(f); 224 - out: 225 - return rc; 202 + return current < level; 226 203 } 227 -
+1 -1
tools/testing/selftests/powerpc/ptrace/Makefile
··· 33 33 $(TESTS_64): CFLAGS += -m64 34 34 $(TM_TESTS): CFLAGS += -I../tm -mhtm 35 35 36 - CFLAGS += -I../../../../../usr/include -fno-pie 36 + CFLAGS += $(KHDR_INCLUDES) -fno-pie 37 37 38 38 $(OUTPUT)/ptrace-gpr: ptrace-gpr.S 39 39 $(OUTPUT)/ptrace-pkey $(OUTPUT)/core-pkey: LDLIBS += -pthread
+8 -20
tools/testing/selftests/powerpc/ptrace/core-pkey.c
··· 348 348 349 349 static int write_core_pattern(const char *core_pattern) 350 350 { 351 - size_t len = strlen(core_pattern), ret; 352 - FILE *f; 351 + int err; 353 352 354 - f = fopen(core_pattern_file, "w"); 355 - SKIP_IF_MSG(!f, "Try with root privileges"); 356 - 357 - ret = fwrite(core_pattern, 1, len, f); 358 - fclose(f); 359 - if (ret != len) { 353 + err = write_file(core_pattern_file, core_pattern, strlen(core_pattern)); 354 + if (err) { 355 + SKIP_IF_MSG(err == -EPERM, "Try with root privileges"); 360 356 perror("Error writing to core_pattern file"); 361 357 return TEST_FAIL; 362 358 } ··· 362 366 363 367 static int setup_core_pattern(char **core_pattern_, bool *changed_) 364 368 { 365 - FILE *f; 366 369 char *core_pattern; 370 + size_t len; 367 371 int ret; 368 372 369 373 core_pattern = malloc(PATH_MAX); ··· 372 376 return TEST_FAIL; 373 377 } 374 378 375 - f = fopen(core_pattern_file, "r"); 376 - if (!f) { 377 - perror("Error opening core_pattern file"); 378 - ret = TEST_FAIL; 379 - goto out; 380 - } 381 - 382 - ret = fread(core_pattern, 1, PATH_MAX - 1, f); 383 - fclose(f); 384 - if (!ret) { 379 + ret = read_file(core_pattern_file, core_pattern, PATH_MAX - 1, &len); 380 + if (ret) { 385 381 perror("Error reading core_pattern file"); 386 382 ret = TEST_FAIL; 387 383 goto out; 388 384 } 389 385 390 - core_pattern[ret] = '\0'; 386 + core_pattern[len] = '\0'; 391 387 392 388 /* Check whether we can predict the name of the core file. */ 393 389 if (!strcmp(core_pattern, "core") || !strcmp(core_pattern, "core.%p"))
+1 -1
tools/testing/selftests/powerpc/security/Makefile
··· 5 5 6 6 top_srcdir = ../../../../.. 7 7 8 - CFLAGS += -I../../../../../usr/include 8 + CFLAGS += $(KHDR_INCLUDES) 9 9 10 10 include ../../lib.mk 11 11
+6 -6
tools/testing/selftests/powerpc/security/entry_flush.c
··· 34 34 // The PMU event we use only works on Power7 or later 35 35 SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06)); 36 36 37 - if (read_debugfs_file("powerpc/rfi_flush", &rfi_flush_orig) < 0) { 37 + if (read_debugfs_int("powerpc/rfi_flush", &rfi_flush_orig) < 0) { 38 38 perror("Unable to read powerpc/rfi_flush debugfs file"); 39 39 SKIP_IF(1); 40 40 } 41 41 42 - if (read_debugfs_file("powerpc/entry_flush", &entry_flush_orig) < 0) { 42 + if (read_debugfs_int("powerpc/entry_flush", &entry_flush_orig) < 0) { 43 43 perror("Unable to read powerpc/entry_flush debugfs file"); 44 44 SKIP_IF(1); 45 45 } 46 46 47 47 if (rfi_flush_orig != 0) { 48 - if (write_debugfs_file("powerpc/rfi_flush", 0) < 0) { 48 + if (write_debugfs_int("powerpc/rfi_flush", 0) < 0) { 49 49 perror("error writing to powerpc/rfi_flush debugfs file"); 50 50 FAIL_IF(1); 51 51 } ··· 105 105 106 106 if (entry_flush == entry_flush_orig) { 107 107 entry_flush = !entry_flush_orig; 108 - if (write_debugfs_file("powerpc/entry_flush", entry_flush) < 0) { 108 + if (write_debugfs_int("powerpc/entry_flush", entry_flush) < 0) { 109 109 perror("error writing to powerpc/entry_flush debugfs file"); 110 110 return 1; 111 111 } ··· 120 120 121 121 set_dscr(0); 122 122 123 - if (write_debugfs_file("powerpc/rfi_flush", rfi_flush_orig) < 0) { 123 + if (write_debugfs_int("powerpc/rfi_flush", rfi_flush_orig) < 0) { 124 124 perror("unable to restore original value of powerpc/rfi_flush debugfs file"); 125 125 return 1; 126 126 } 127 127 128 - if (write_debugfs_file("powerpc/entry_flush", entry_flush_orig) < 0) { 128 + if (write_debugfs_int("powerpc/entry_flush", entry_flush_orig) < 0) { 129 129 perror("unable to restore original value of powerpc/entry_flush debugfs file"); 130 130 return 1; 131 131 }
+6 -6
tools/testing/selftests/powerpc/security/rfi_flush.c
··· 34 34 // The PMU event we use only works on Power7 or later 35 35 SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06)); 36 36 37 - if (read_debugfs_file("powerpc/rfi_flush", &rfi_flush_orig) < 0) { 37 + if (read_debugfs_int("powerpc/rfi_flush", &rfi_flush_orig) < 0) { 38 38 perror("Unable to read powerpc/rfi_flush debugfs file"); 39 39 SKIP_IF(1); 40 40 } 41 41 42 - if (read_debugfs_file("powerpc/entry_flush", &entry_flush_orig) < 0) { 42 + if (read_debugfs_int("powerpc/entry_flush", &entry_flush_orig) < 0) { 43 43 have_entry_flush = 0; 44 44 } else { 45 45 have_entry_flush = 1; 46 46 47 47 if (entry_flush_orig != 0) { 48 - if (write_debugfs_file("powerpc/entry_flush", 0) < 0) { 48 + if (write_debugfs_int("powerpc/entry_flush", 0) < 0) { 49 49 perror("error writing to powerpc/entry_flush debugfs file"); 50 50 return 1; 51 51 } ··· 105 105 106 106 if (rfi_flush == rfi_flush_orig) { 107 107 rfi_flush = !rfi_flush_orig; 108 - if (write_debugfs_file("powerpc/rfi_flush", rfi_flush) < 0) { 108 + if (write_debugfs_int("powerpc/rfi_flush", rfi_flush) < 0) { 109 109 perror("error writing to powerpc/rfi_flush debugfs file"); 110 110 return 1; 111 111 } ··· 120 120 121 121 set_dscr(0); 122 122 123 - if (write_debugfs_file("powerpc/rfi_flush", rfi_flush_orig) < 0) { 123 + if (write_debugfs_int("powerpc/rfi_flush", rfi_flush_orig) < 0) { 124 124 perror("unable to restore original value of powerpc/rfi_flush debugfs file"); 125 125 return 1; 126 126 } 127 127 128 128 if (have_entry_flush) { 129 - if (write_debugfs_file("powerpc/entry_flush", entry_flush_orig) < 0) { 129 + if (write_debugfs_int("powerpc/entry_flush", entry_flush_orig) < 0) { 130 130 perror("unable to restore original value of powerpc/entry_flush " 131 131 "debugfs file"); 132 132 return 1;
+9 -9
tools/testing/selftests/powerpc/security/uaccess_flush.c
··· 36 36 // The PMU event we use only works on Power7 or later 37 37 SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06)); 38 38 39 - if (read_debugfs_file("powerpc/rfi_flush", &rfi_flush_orig) < 0) { 39 + if (read_debugfs_int("powerpc/rfi_flush", &rfi_flush_orig) < 0) { 40 40 perror("Unable to read powerpc/rfi_flush debugfs file"); 41 41 SKIP_IF(1); 42 42 } 43 43 44 - if (read_debugfs_file("powerpc/entry_flush", &entry_flush_orig) < 0) { 44 + if (read_debugfs_int("powerpc/entry_flush", &entry_flush_orig) < 0) { 45 45 perror("Unable to read powerpc/entry_flush debugfs file"); 46 46 SKIP_IF(1); 47 47 } 48 48 49 - if (read_debugfs_file("powerpc/uaccess_flush", &uaccess_flush_orig) < 0) { 49 + if (read_debugfs_int("powerpc/uaccess_flush", &uaccess_flush_orig) < 0) { 50 50 perror("Unable to read powerpc/entry_flush debugfs file"); 51 51 SKIP_IF(1); 52 52 } 53 53 54 54 if (rfi_flush_orig != 0) { 55 - if (write_debugfs_file("powerpc/rfi_flush", 0) < 0) { 55 + if (write_debugfs_int("powerpc/rfi_flush", 0) < 0) { 56 56 perror("error writing to powerpc/rfi_flush debugfs file"); 57 57 FAIL_IF(1); 58 58 } 59 59 } 60 60 61 61 if (entry_flush_orig != 0) { 62 - if (write_debugfs_file("powerpc/entry_flush", 0) < 0) { 62 + if (write_debugfs_int("powerpc/entry_flush", 0) < 0) { 63 63 perror("error writing to powerpc/entry_flush debugfs file"); 64 64 FAIL_IF(1); 65 65 } ··· 119 119 120 120 if (uaccess_flush == uaccess_flush_orig) { 121 121 uaccess_flush = !uaccess_flush_orig; 122 - if (write_debugfs_file("powerpc/uaccess_flush", uaccess_flush) < 0) { 122 + if (write_debugfs_int("powerpc/uaccess_flush", uaccess_flush) < 0) { 123 123 perror("error writing to powerpc/uaccess_flush debugfs file"); 124 124 return 1; 125 125 } ··· 134 134 135 135 set_dscr(0); 136 136 137 - if (write_debugfs_file("powerpc/rfi_flush", rfi_flush_orig) < 0) { 137 + if (write_debugfs_int("powerpc/rfi_flush", rfi_flush_orig) < 0) { 138 138 perror("unable to restore original value of powerpc/rfi_flush debugfs file"); 139 139 return 1; 140 140 } 141 141 142 - if (write_debugfs_file("powerpc/entry_flush", entry_flush_orig) < 0) { 142 + if (write_debugfs_int("powerpc/entry_flush", entry_flush_orig) < 0) { 143 143 perror("unable to restore original value of powerpc/entry_flush debugfs file"); 144 144 return 1; 145 145 } 146 146 147 - if (write_debugfs_file("powerpc/uaccess_flush", uaccess_flush_orig) < 0) { 147 + if (write_debugfs_int("powerpc/uaccess_flush", uaccess_flush_orig) < 0) { 148 148 perror("unable to restore original value of powerpc/uaccess_flush debugfs file"); 149 149 return 1; 150 150 }
+2 -2
tools/testing/selftests/powerpc/syscalls/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 TEST_GEN_PROGS := ipc_unmuxed rtas_filter 3 3 4 - CFLAGS += -I../../../../../usr/include 4 + CFLAGS += $(KHDR_INCLUDES) 5 5 6 6 top_srcdir = ../../../../.. 7 7 include ../../lib.mk 8 8 9 - $(TEST_GEN_PROGS): ../harness.c 9 + $(TEST_GEN_PROGS): ../harness.c ../utils.c
+10 -71
tools/testing/selftests/powerpc/syscalls/rtas_filter.c
··· 8 8 #include <byteswap.h> 9 9 #include <stdint.h> 10 10 #include <inttypes.h> 11 + #include <linux/limits.h> 11 12 #include <stdio.h> 12 13 #include <string.h> 13 14 #include <sys/syscall.h> ··· 51 50 struct region *next; 52 51 }; 53 52 54 - int read_entire_file(int fd, char **buf, size_t *len) 55 - { 56 - size_t buf_size = 0; 57 - size_t off = 0; 58 - int rc; 59 - 60 - *buf = NULL; 61 - do { 62 - buf_size += BLOCK_SIZE; 63 - if (*buf == NULL) 64 - *buf = malloc(buf_size); 65 - else 66 - *buf = realloc(*buf, buf_size); 67 - 68 - if (*buf == NULL) 69 - return -ENOMEM; 70 - 71 - rc = read(fd, *buf + off, BLOCK_SIZE); 72 - if (rc < 0) 73 - return -EIO; 74 - 75 - off += rc; 76 - } while (rc == BLOCK_SIZE); 77 - 78 - if (len) 79 - *len = off; 80 - 81 - return 0; 82 - } 83 - 84 - static int open_prop_file(const char *prop_path, const char *prop_name, int *fd) 85 - { 86 - char *path; 87 - int len; 88 - 89 - /* allocate enough for two string, a slash and trailing NULL */ 90 - len = strlen(prop_path) + strlen(prop_name) + 1 + 1; 91 - path = malloc(len); 92 - if (path == NULL) 93 - return -ENOMEM; 94 - 95 - snprintf(path, len, "%s/%s", prop_path, prop_name); 96 - 97 - *fd = open(path, O_RDONLY); 98 - free(path); 99 - if (*fd < 0) 100 - return -errno; 101 - 102 - return 0; 103 - } 104 - 105 53 static int get_property(const char *prop_path, const char *prop_name, 106 54 char **prop_val, size_t *prop_len) 107 55 { 108 - int rc, fd; 56 + char path[PATH_MAX]; 109 57 110 - rc = open_prop_file(prop_path, prop_name, &fd); 111 - if (rc) 112 - return rc; 58 + int len = snprintf(path, sizeof(path), "%s/%s", prop_path, prop_name); 59 + if (len < 0 || len >= sizeof(path)) 60 + return -ENOMEM; 113 61 114 - rc = read_entire_file(fd, prop_val, prop_len); 115 - close(fd); 116 - 117 - return rc; 62 + return read_file_alloc(path, prop_val, prop_len); 118 63 } 119 64 120 65 int rtas_token(const char *call_name) ··· 85 138 static int read_kregion_bounds(struct region *kregion) 86 139 { 87 140 char *buf; 88 - int fd; 89 - int rc; 141 + int err; 90 142 91 - fd = open("/proc/ppc64/rtas/rmo_buffer", O_RDONLY); 92 - if (fd < 0) { 93 - printf("Could not open rmo_buffer file\n"); 143 + err = read_file_alloc("/proc/ppc64/rtas/rmo_buffer", &buf, NULL); 144 + if (err) { 145 + perror("Could not open rmo_buffer file"); 94 146 return RTAS_IO_ASSERT; 95 - } 96 - 97 - rc = read_entire_file(fd, &buf, NULL); 98 - close(fd); 99 - if (rc) { 100 - free(buf); 101 - return rc; 102 147 } 103 148 104 149 sscanf(buf, "%" SCNx64 " %x", &kregion->addr, &kregion->size);
+1 -1
tools/testing/selftests/powerpc/tm/Makefile
··· 17 17 CFLAGS += -mhtm 18 18 19 19 $(OUTPUT)/tm-syscall: tm-syscall-asm.S 20 - $(OUTPUT)/tm-syscall: CFLAGS += -I../../../../../usr/include 20 + $(OUTPUT)/tm-syscall: CFLAGS += $(KHDR_INCLUDES) 21 21 $(OUTPUT)/tm-tmspr: CFLAGS += -pthread 22 22 $(OUTPUT)/tm-vmx-unavail: CFLAGS += -pthread -m64 23 23 $(OUTPUT)/tm-resched-dscr: ../pmu/lib.c
+355 -61
tools/testing/selftests/powerpc/utils.c
··· 8 8 #include <elf.h> 9 9 #include <errno.h> 10 10 #include <fcntl.h> 11 + #include <inttypes.h> 12 + #include <limits.h> 11 13 #include <link.h> 12 14 #include <sched.h> 13 15 #include <stdio.h> ··· 28 26 29 27 static char auxv[4096]; 30 28 31 - int read_auxv(char *buf, ssize_t buf_size) 29 + int read_file(const char *path, char *buf, size_t count, size_t *len) 32 30 { 33 - ssize_t num; 34 - int rc, fd; 31 + ssize_t rc; 32 + int fd; 33 + int err; 34 + char eof; 35 35 36 - fd = open("/proc/self/auxv", O_RDONLY); 37 - if (fd == -1) { 38 - perror("open"); 36 + fd = open(path, O_RDONLY); 37 + if (fd < 0) 39 38 return -errno; 40 - } 41 39 42 - num = read(fd, buf, buf_size); 43 - if (num < 0) { 44 - perror("read"); 45 - rc = -EIO; 40 + rc = read(fd, buf, count); 41 + if (rc < 0) { 42 + err = -errno; 46 43 goto out; 47 44 } 48 45 49 - if (num > buf_size) { 50 - printf("overflowed auxv buffer\n"); 51 - rc = -EOVERFLOW; 52 - goto out; 46 + if (len) 47 + *len = rc; 48 + 49 + /* Overflow if there are still more bytes after filling the buffer */ 50 + if (rc == count) { 51 + rc = read(fd, &eof, 1); 52 + if (rc != 0) { 53 + err = -EOVERFLOW; 54 + goto out; 55 + } 53 56 } 54 57 55 - rc = 0; 58 + err = 0; 59 + 56 60 out: 57 61 close(fd); 58 - return rc; 62 + errno = -err; 63 + return err; 64 + } 65 + 66 + int read_file_alloc(const char *path, char **buf, size_t *len) 67 + { 68 + size_t read_offset = 0; 69 + size_t buffer_len = 0; 70 + char *buffer = NULL; 71 + int err; 72 + int fd; 73 + 74 + fd = open(path, O_RDONLY); 75 + if (fd < 0) 76 + return -errno; 77 + 78 + /* 79 + * We don't use stat & preallocate st_size because some non-files 80 + * report 0 file size. Instead just dynamically grow the buffer 81 + * as needed. 82 + */ 83 + while (1) { 84 + ssize_t rc; 85 + 86 + if (read_offset >= buffer_len / 2) { 87 + char *next_buffer; 88 + 89 + buffer_len = buffer_len ? buffer_len * 2 : 4096; 90 + next_buffer = realloc(buffer, buffer_len); 91 + if (!next_buffer) { 92 + err = -errno; 93 + goto out; 94 + } 95 + buffer = next_buffer; 96 + } 97 + 98 + rc = read(fd, buffer + read_offset, buffer_len - read_offset); 99 + if (rc < 0) { 100 + err = -errno; 101 + goto out; 102 + } 103 + 104 + if (rc == 0) 105 + break; 106 + 107 + read_offset += rc; 108 + } 109 + 110 + *buf = buffer; 111 + if (len) 112 + *len = read_offset; 113 + 114 + err = 0; 115 + 116 + out: 117 + close(fd); 118 + if (err) 119 + free(buffer); 120 + errno = -err; 121 + return err; 122 + } 123 + 124 + int write_file(const char *path, const char *buf, size_t count) 125 + { 126 + int fd; 127 + int err; 128 + ssize_t rc; 129 + 130 + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); 131 + if (fd < 0) 132 + return -errno; 133 + 134 + rc = write(fd, buf, count); 135 + if (rc < 0) { 136 + err = -errno; 137 + goto out; 138 + } 139 + 140 + if (rc != count) { 141 + err = -EOVERFLOW; 142 + goto out; 143 + } 144 + 145 + err = 0; 146 + 147 + out: 148 + close(fd); 149 + errno = -err; 150 + return err; 151 + } 152 + 153 + int read_auxv(char *buf, ssize_t buf_size) 154 + { 155 + int err; 156 + 157 + err = read_file("/proc/self/auxv", buf, buf_size, NULL); 158 + if (err) { 159 + perror("Error reading /proc/self/auxv"); 160 + return err; 161 + } 162 + 163 + return 0; 164 + } 165 + 166 + int read_debugfs_file(const char *subpath, char *buf, size_t count) 167 + { 168 + char path[PATH_MAX] = "/sys/kernel/debug/"; 169 + 170 + strncat(path, subpath, sizeof(path) - strlen(path) - 1); 171 + 172 + return read_file(path, buf, count, NULL); 173 + } 174 + 175 + int write_debugfs_file(const char *subpath, const char *buf, size_t count) 176 + { 177 + char path[PATH_MAX] = "/sys/kernel/debug/"; 178 + 179 + strncat(path, subpath, sizeof(path) - strlen(path) - 1); 180 + 181 + return write_file(path, buf, count); 182 + } 183 + 184 + static int validate_int_parse(const char *buffer, size_t count, char *end) 185 + { 186 + int err = 0; 187 + 188 + /* Require at least one digit */ 189 + if (end == buffer) { 190 + err = -EINVAL; 191 + goto out; 192 + } 193 + 194 + /* Require all remaining characters be whitespace-ish */ 195 + for (; end < buffer + count; end++) { 196 + if (*end == '\0') 197 + break; 198 + 199 + if (*end != ' ' && *end != '\n') { 200 + err = -EINVAL; 201 + goto out; 202 + } 203 + } 204 + 205 + out: 206 + errno = -err; 207 + return err; 208 + } 209 + 210 + static int parse_bounded_int(const char *buffer, size_t count, intmax_t *result, 211 + int base, intmax_t min, intmax_t max) 212 + { 213 + int err; 214 + char *end; 215 + 216 + errno = 0; 217 + *result = strtoimax(buffer, &end, base); 218 + 219 + if (errno) 220 + return -errno; 221 + 222 + err = validate_int_parse(buffer, count, end); 223 + if (err) 224 + goto out; 225 + 226 + if (*result < min || *result > max) 227 + err = -EOVERFLOW; 228 + 229 + out: 230 + errno = -err; 231 + return err; 232 + } 233 + 234 + static int parse_bounded_uint(const char *buffer, size_t count, uintmax_t *result, 235 + int base, uintmax_t max) 236 + { 237 + int err = 0; 238 + char *end; 239 + 240 + errno = 0; 241 + *result = strtoumax(buffer, &end, base); 242 + 243 + if (errno) 244 + return -errno; 245 + 246 + err = validate_int_parse(buffer, count, end); 247 + if (err) 248 + goto out; 249 + 250 + if (*result > max) 251 + err = -EOVERFLOW; 252 + 253 + out: 254 + errno = -err; 255 + return err; 256 + } 257 + 258 + int parse_intmax(const char *buffer, size_t count, intmax_t *result, int base) 259 + { 260 + return parse_bounded_int(buffer, count, result, base, INTMAX_MIN, INTMAX_MAX); 261 + } 262 + 263 + int parse_uintmax(const char *buffer, size_t count, uintmax_t *result, int base) 264 + { 265 + return parse_bounded_uint(buffer, count, result, base, UINTMAX_MAX); 266 + } 267 + 268 + int parse_int(const char *buffer, size_t count, int *result, int base) 269 + { 270 + intmax_t parsed; 271 + int err = parse_bounded_int(buffer, count, &parsed, base, INT_MIN, INT_MAX); 272 + 273 + *result = parsed; 274 + return err; 275 + } 276 + 277 + int parse_uint(const char *buffer, size_t count, unsigned int *result, int base) 278 + { 279 + uintmax_t parsed; 280 + int err = parse_bounded_uint(buffer, count, &parsed, base, UINT_MAX); 281 + 282 + *result = parsed; 283 + return err; 284 + } 285 + 286 + int parse_long(const char *buffer, size_t count, long *result, int base) 287 + { 288 + intmax_t parsed; 289 + int err = parse_bounded_int(buffer, count, &parsed, base, LONG_MIN, LONG_MAX); 290 + 291 + *result = parsed; 292 + return err; 293 + } 294 + 295 + int parse_ulong(const char *buffer, size_t count, unsigned long *result, int base) 296 + { 297 + uintmax_t parsed; 298 + int err = parse_bounded_uint(buffer, count, &parsed, base, ULONG_MAX); 299 + 300 + *result = parsed; 301 + return err; 302 + } 303 + 304 + int read_long(const char *path, long *result, int base) 305 + { 306 + int err; 307 + char buffer[32] = {0}; 308 + 309 + err = read_file(path, buffer, sizeof(buffer) - 1, NULL); 310 + if (err) 311 + return err; 312 + 313 + return parse_long(buffer, sizeof(buffer), result, base); 314 + } 315 + 316 + int read_ulong(const char *path, unsigned long *result, int base) 317 + { 318 + int err; 319 + char buffer[32] = {0}; 320 + 321 + err = read_file(path, buffer, sizeof(buffer) - 1, NULL); 322 + if (err) 323 + return err; 324 + 325 + return parse_ulong(buffer, sizeof(buffer), result, base); 326 + } 327 + 328 + int write_long(const char *path, long result, int base) 329 + { 330 + int err; 331 + int len; 332 + char buffer[32]; 333 + 334 + /* Decimal only for now: no format specifier for signed hex values */ 335 + if (base != 10) { 336 + err = -EINVAL; 337 + goto out; 338 + } 339 + 340 + len = snprintf(buffer, sizeof(buffer), "%ld", result); 341 + if (len < 0 || len >= sizeof(buffer)) { 342 + err = -EOVERFLOW; 343 + goto out; 344 + } 345 + 346 + err = write_file(path, buffer, len); 347 + 348 + out: 349 + errno = -err; 350 + return err; 351 + } 352 + 353 + int write_ulong(const char *path, unsigned long result, int base) 354 + { 355 + int err; 356 + int len; 357 + char buffer[32]; 358 + char *fmt; 359 + 360 + switch (base) { 361 + case 10: 362 + fmt = "%lu"; 363 + break; 364 + case 16: 365 + fmt = "%lx"; 366 + break; 367 + default: 368 + err = -EINVAL; 369 + goto out; 370 + } 371 + 372 + len = snprintf(buffer, sizeof(buffer), fmt, result); 373 + if (len < 0 || len >= sizeof(buffer)) { 374 + err = -errno; 375 + goto out; 376 + } 377 + 378 + err = write_file(path, buffer, len); 379 + 380 + out: 381 + errno = -err; 382 + return err; 59 383 } 60 384 61 385 void *find_auxv_entry(int type, char *auxv) ··· 470 142 int read_sysfs_file(char *fpath, char *result, size_t result_size) 471 143 { 472 144 char path[PATH_MAX] = "/sys/"; 473 - int rc = -1, fd; 474 145 475 146 strncat(path, fpath, PATH_MAX - strlen(path) - 1); 476 147 477 - if ((fd = open(path, O_RDONLY)) < 0) 478 - return rc; 479 - 480 - rc = read(fd, result, result_size); 481 - 482 - close(fd); 483 - 484 - if (rc < 0) 485 - return rc; 486 - 487 - return 0; 148 + return read_file(path, result, result_size, NULL); 488 149 } 489 150 490 - int read_debugfs_file(char *debugfs_file, int *result) 151 + int read_debugfs_int(const char *debugfs_file, int *result) 491 152 { 492 - int rc = -1, fd; 493 - char path[PATH_MAX]; 494 - char value[16]; 153 + int err; 154 + char value[16] = {0}; 495 155 496 - strcpy(path, "/sys/kernel/debug/"); 497 - strncat(path, debugfs_file, PATH_MAX - strlen(path) - 1); 156 + err = read_debugfs_file(debugfs_file, value, sizeof(value) - 1); 157 + if (err) 158 + return err; 498 159 499 - if ((fd = open(path, O_RDONLY)) < 0) 500 - return rc; 501 - 502 - if ((rc = read(fd, value, sizeof(value))) < 0) 503 - return rc; 504 - 505 - value[15] = 0; 506 - *result = atoi(value); 507 - close(fd); 508 - 509 - return 0; 160 + return parse_int(value, sizeof(value), result, 10); 510 161 } 511 162 512 - int write_debugfs_file(char *debugfs_file, int result) 163 + int write_debugfs_int(const char *debugfs_file, int result) 513 164 { 514 - int rc = -1, fd; 515 - char path[PATH_MAX]; 516 165 char value[16]; 517 - 518 - strcpy(path, "/sys/kernel/debug/"); 519 - strncat(path, debugfs_file, PATH_MAX - strlen(path) - 1); 520 - 521 - if ((fd = open(path, O_WRONLY)) < 0) 522 - return rc; 523 166 524 167 snprintf(value, 16, "%d", result); 525 168 526 - if ((rc = write(fd, value, strlen(value))) < 0) 527 - return rc; 528 - 529 - close(fd); 530 - 531 - return 0; 169 + return write_debugfs_file(debugfs_file, value, strlen(value)); 532 170 } 533 171 534 172 static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,