Pull powerpc fixes from Michael Ellerman: - Revert our removal of PROT_SAO, at least one user expressed an interest in using it on Power9. Instead don't allow it to be used in guests unless enabled explicitly at compile time. - A fix for a crash introduced by a recent change to FP handling. - Revert a change to our idle code that left Power10 with no idle support. - One minor fix for the new scv system call path to set PPR. - Fix a crash in our "generic" PMU if branch stack events were enabled. - A fix for the IMC PMU, to correctly identify host kernel samples. - The ADB_PMU powermac code was found to be incompatible with VMAP_STACK, so make them incompatible in Kconfig until the code can be fixed. - A build fix in drivers/video/fbdev/controlfb.c, and a documentation fix. Thanks to Alexey Kardashevskiy, Athira Rajeev, Christophe Leroy, Giuseppe Sacco, Madhavan Srinivasan, Milton Miller, Nicholas Piggin, Pratik Rajesh Sampat, Randy Dunlap, Shawn Anastasio, Vaidyanathan Srinivasan. * tag 'powerpc-5.9-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/32s: Disable VMAP stack which CONFIG_ADB_PMU Revert "powerpc/powernv/idle: Replace CPU feature check with PVR check" powerpc/perf: Fix reading of MSR[HV/PR] bits in trace-imc powerpc/perf: Fix crashes with generic_compat_pmu & BHRB powerpc/64s: Fix crash in load_fp_state() due to fpexc_mode powerpc/64s: scv entry should set PPR Documentation/powerpc: fix malformed table in syscall64-abi video: fbdev: controlfb: Fix build for COMPILE_TEST=y && PPC_PMAC=n selftests/powerpc: Update PROT_SAO test to skip ISA 3.1 powerpc/64s: Disallow PROT_SAO in LPARs by default Revert "powerpc/64s: Remove PROT_SAO support"
Unified · Split
| @@ -49,16 +49,18 @@ Register preservation rules · 48 unmodified lines | |||
| 49 | Register preservation rules match the ELF ABI calling sequence with the | 49 | Register preservation rules match the ELF ABI calling sequence with the |
| 50 | following differences: | 50 | following differences: |
| 51 | 51 | ||
| 52 | =========== ============= ======================================== | ||
| 53 | --- For the sc instruction, differences with the ELF ABI --- | 52 | --- For the sc instruction, differences with the ELF ABI --- |
| 53 | =========== ============= ======================================== | ||
| 54 | r0 Volatile (System call number.) | 54 | r0 Volatile (System call number.) |
| 55 | r3 Volatile (Parameter 1, and return value.) | 55 | r3 Volatile (Parameter 1, and return value.) |
| 56 | r4-r8 Volatile (Parameters 2-6.) | 56 | r4-r8 Volatile (Parameters 2-6.) |
| 57 | cr0 Volatile (cr0.SO is the return error condition.) | 57 | cr0 Volatile (cr0.SO is the return error condition.) |
| 58 | cr1, cr5-7 Nonvolatile | 58 | cr1, cr5-7 Nonvolatile |
| 59 | lr Nonvolatile | 59 | lr Nonvolatile |
| 60 | =========== ============= ======================================== | ||
| 60 | 61 | ||
| 61 | --- For the scv 0 instruction, differences with the ELF ABI --- | 62 | --- For the scv 0 instruction, differences with the ELF ABI --- |
| 63 | =========== ============= ======================================== | ||
| 62 | r0 Volatile (System call number.) | 64 | r0 Volatile (System call number.) |
| 63 | r3 Volatile (Parameter 1, and return value.) | 65 | r3 Volatile (Parameter 1, and return value.) |
| 64 | r4-r8 Volatile (Parameters 2-6.) | 66 | r4-r8 Volatile (Parameters 2-6.) |
| @@ -860,6 +860,18 @@ config PPC_SUBPAGE_PROT · 859 unmodified lines | |||
| 860 | 860 | ||
| 861 | If unsure, say N here. | 861 | If unsure, say N here. |
| 862 | 862 | ||
| 863 | config PPC_PROT_SAO_LPAR | ||
| 864 | bool "Support PROT_SAO mappings in LPARs" | ||
| 865 | depends on PPC_BOOK3S_64 | ||
| 866 | help | ||
| 867 | This option adds support for PROT_SAO mappings from userspace | ||
| 868 | inside LPARs on supported CPUs. | ||
| 869 | |||
| 870 | This may cause issues when performing guest migration from | ||
| 871 | a CPU that supports SAO to one that does not. | ||
| 872 | |||
| 873 | If unsure, say N here. | ||
| 874 | |||
| 863 | config PPC_COPRO_BASE | 875 | config PPC_COPRO_BASE |
| 864 | bool | 876 | bool |
| 865 | 877 | ||
| @@ -20,13 +20,9 @@ · 19 unmodified lines | |||
| 20 | #define _PAGE_RW (_PAGE_READ | _PAGE_WRITE) | 20 | #define _PAGE_RW (_PAGE_READ | _PAGE_WRITE) |
| 21 | #define _PAGE_RWX (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC) | 21 | #define _PAGE_RWX (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC) |
| 22 | #define _PAGE_PRIVILEGED 0x00008 /* kernel access only */ | 22 | #define _PAGE_PRIVILEGED 0x00008 /* kernel access only */ |
| 23 | 23 | #define _PAGE_SAO 0x00010 /* Strong access order */ | |
| 24 | #define _PAGE_CACHE_CTL 0x00030 /* Bits for the folowing cache modes */ | ||
| 25 | /* No bits set is normal cacheable memory */ | ||
| 26 | /* 0x00010 unused, is SAO bit on radix POWER9 */ | ||
| 27 | #define _PAGE_NON_IDEMPOTENT 0x00020 /* non idempotent memory */ | 24 | #define _PAGE_NON_IDEMPOTENT 0x00020 /* non idempotent memory */ |
| 28 | #define _PAGE_TOLERANT 0x00030 /* tolerant memory, cache inhibited */ | 25 | #define _PAGE_TOLERANT 0x00030 /* tolerant memory, cache inhibited */ |
| 29 | |||
| 30 | #define _PAGE_DIRTY 0x00080 /* C: page changed */ | 26 | #define _PAGE_DIRTY 0x00080 /* C: page changed */ |
| 31 | #define _PAGE_ACCESSED 0x00100 /* R: page referenced */ | 27 | #define _PAGE_ACCESSED 0x00100 /* R: page referenced */ |
| 32 | /* | 28 | /* |
| @@ -828,6 +824,8 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, · 795 unmodified lines | |||
| 828 | return hash__set_pte_at(mm, addr, ptep, pte, percpu); | 824 | return hash__set_pte_at(mm, addr, ptep, pte, percpu); |
| 829 | } | 825 | } |
| 830 | 826 | ||
| 827 | #define _PAGE_CACHE_CTL (_PAGE_SAO | _PAGE_NON_IDEMPOTENT | _PAGE_TOLERANT) | ||
| 828 | |||
| 831 | #define pgprot_noncached pgprot_noncached | 829 | #define pgprot_noncached pgprot_noncached |
| 832 | static inline pgprot_t pgprot_noncached(pgprot_t prot) | 830 | static inline pgprot_t pgprot_noncached(pgprot_t prot) |
| 833 | { | 831 | { |
| @@ -196,7 +196,7 @@ static inline void cpu_feature_keys_init(void) { } · 195 unmodified lines | |||
| 196 | #define CPU_FTR_SPURR LONG_ASM_CONST(0x0000000001000000) | 196 | #define CPU_FTR_SPURR LONG_ASM_CONST(0x0000000001000000) |
| 197 | #define CPU_FTR_DSCR LONG_ASM_CONST(0x0000000002000000) | 197 | #define CPU_FTR_DSCR LONG_ASM_CONST(0x0000000002000000) |
| 198 | #define CPU_FTR_VSX LONG_ASM_CONST(0x0000000004000000) | 198 | #define CPU_FTR_VSX LONG_ASM_CONST(0x0000000004000000) |
| 199 | // Free LONG_ASM_CONST(0x0000000008000000) | 199 | #define CPU_FTR_SAO LONG_ASM_CONST(0x0000000008000000) |
| 200 | #define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0000000010000000) | 200 | #define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0000000010000000) |
| 201 | #define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0000000020000000) | 201 | #define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0000000020000000) |
| 202 | #define CPU_FTR_ASYM_SMT LONG_ASM_CONST(0x0000000040000000) | 202 | #define CPU_FTR_ASYM_SMT LONG_ASM_CONST(0x0000000040000000) |
| @@ -441,7 +441,7 @@ static inline void cpu_feature_keys_init(void) { } · 238 unmodified lines | |||
| 441 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 441 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
| 442 | CPU_FTR_COHERENT_ICACHE | \ | 442 | CPU_FTR_COHERENT_ICACHE | \ |
| 443 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ | 443 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ |
| 444 | CPU_FTR_DSCR | CPU_FTR_ASYM_SMT | \ | 444 | CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \ |
| 445 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ | 445 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
| 446 | CPU_FTR_CFAR | CPU_FTR_HVMODE | \ | 446 | CPU_FTR_CFAR | CPU_FTR_HVMODE | \ |
| 447 | CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR | CPU_FTR_DABRX ) | 447 | CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR | CPU_FTR_DABRX ) |
| @@ -450,7 +450,7 @@ static inline void cpu_feature_keys_init(void) { } · 2 unmodified lines | |||
| 450 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 450 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
| 451 | CPU_FTR_COHERENT_ICACHE | \ | 451 | CPU_FTR_COHERENT_ICACHE | \ |
| 452 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ | 452 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ |
| 453 | CPU_FTR_DSCR | \ | 453 | CPU_FTR_DSCR | CPU_FTR_SAO | \ |
| 454 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ | 454 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
| 455 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ | 455 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ |
| 456 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ | 456 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ |
| @@ -461,7 +461,7 @@ static inline void cpu_feature_keys_init(void) { } · 4 unmodified lines | |||
| 461 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 461 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
| 462 | CPU_FTR_COHERENT_ICACHE | \ | 462 | CPU_FTR_COHERENT_ICACHE | \ |
| 463 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ | 463 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ |
| 464 | CPU_FTR_DSCR | \ | 464 | CPU_FTR_DSCR | CPU_FTR_SAO | \ |
| 465 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ | 465 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
| 466 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ | 466 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ |
| 467 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \ | 467 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \ |
| @@ -479,7 +479,7 @@ static inline void cpu_feature_keys_init(void) { } · 11 unmodified lines | |||
| 479 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 479 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
| 480 | CPU_FTR_COHERENT_ICACHE | \ | 480 | CPU_FTR_COHERENT_ICACHE | \ |
| 481 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ | 481 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ |
| 482 | CPU_FTR_DSCR | \ | 482 | CPU_FTR_DSCR | CPU_FTR_SAO | \ |
| 483 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ | 483 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
| 484 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ | 484 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ |
| 485 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \ | 485 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \ |
| @@ -13,20 +13,43 @@ · 12 unmodified lines | |||
| 13 | #include <linux/pkeys.h> | 13 | #include <linux/pkeys.h> |
| 14 | #include <asm/cpu_has_feature.h> | 14 | #include <asm/cpu_has_feature.h> |
| 15 | 15 | ||
| 16 | #ifdef CONFIG_PPC_MEM_KEYS | ||
| 17 | static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, | 16 | static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, |
| 18 | unsigned long pkey) | 17 | unsigned long pkey) |
| 19 | { | 18 | { |
| 20 | return pkey_to_vmflag_bits(pkey); | 19 | #ifdef CONFIG_PPC_MEM_KEYS |
| 20 | return (((prot & PROT_SAO) ? VM_SAO : 0) | pkey_to_vmflag_bits(pkey)); | ||
| 21 | #else | ||
| 22 | return ((prot & PROT_SAO) ? VM_SAO : 0); | ||
| 23 | #endif | ||
| 21 | } | 24 | } |
| 22 | #define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey) | 25 | #define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey) |
| 23 | 26 | ||
| 24 | static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) | 27 | static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) |
| 25 | { | 28 | { |
| 26 | return __pgprot(vmflag_to_pte_pkey_bits(vm_flags)); | 29 | #ifdef CONFIG_PPC_MEM_KEYS |
| 30 | return (vm_flags & VM_SAO) ? | ||
| 31 | __pgprot(_PAGE_SAO | vmflag_to_pte_pkey_bits(vm_flags)) : | ||
| 32 | __pgprot(0 | vmflag_to_pte_pkey_bits(vm_flags)); | ||
| 33 | #else | ||
| 34 | return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : __pgprot(0); | ||
| 35 | #endif | ||
| 27 | } | 36 | } |
| 28 | #define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags) | 37 | #define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags) |
| 29 | #endif | 38 | |
| 39 | static inline bool arch_validate_prot(unsigned long prot, unsigned long addr) | ||
| 40 | { | ||
| 41 | if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_SAO)) | ||
| 42 | return false; | ||
| 43 | if (prot & PROT_SAO) { | ||
| 44 | if (!cpu_has_feature(CPU_FTR_SAO)) | ||
| 45 | return false; | ||
| 46 | if (firmware_has_feature(FW_FEATURE_LPAR) && | ||
| 47 | !IS_ENABLED(CONFIG_PPC_PROT_SAO_LPAR)) | ||
| 48 | return false; | ||
| 49 | } | ||
| 50 | return true; | ||
| 51 | } | ||
| 52 | #define arch_validate_prot arch_validate_prot | ||
| 30 | 53 | ||
| 31 | #endif /* CONFIG_PPC64 */ | 54 | #endif /* CONFIG_PPC64 */ |
| 32 | #endif /* _ASM_POWERPC_MMAN_H */ | 55 | #endif /* _ASM_POWERPC_MMAN_H */ |
| @@ -82,6 +82,8 @@ · 81 unmodified lines | |||
| 82 | */ | 82 | */ |
| 83 | #include <asm/nohash/pte-book3e.h> | 83 | #include <asm/nohash/pte-book3e.h> |
| 84 | 84 | ||
| 85 | #define _PAGE_SAO 0 | ||
| 86 | |||
| 85 | #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) | 87 | #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) |
| 86 | 88 | ||
| 87 | /* | 89 | /* |
| @@ -11,7 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <asm-generic/mman-common.h> | 11 | #include <asm-generic/mman-common.h> |
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | #define PROT_SAO 0x10 /* Unsupported since v5.9 */ | 14 | #define PROT_SAO 0x10 /* Strong Access Ordering */ |
| 15 | 15 | ||
| 16 | #define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ | 16 | #define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ |
| 17 | #define MAP_NORESERVE 0x40 /* don't reserve swap pages */ | 17 | #define MAP_NORESERVE 0x40 /* don't reserve swap pages */ |
| @@ -653,7 +653,7 @@ static struct dt_cpu_feature_match __initdata · 652 unmodified lines | |||
| 653 | {"processor-control-facility-v3", feat_enable_dbell, CPU_FTR_DBELL}, | 653 | {"processor-control-facility-v3", feat_enable_dbell, CPU_FTR_DBELL}, |
| 654 | {"processor-utilization-of-resources-register", feat_enable_purr, 0}, | 654 | {"processor-utilization-of-resources-register", feat_enable_purr, 0}, |
| 655 | {"no-execute", feat_enable, 0}, | 655 | {"no-execute", feat_enable, 0}, |
| 656 | /* strong-access-ordering is unused */ | 656 | {"strong-access-ordering", feat_enable, CPU_FTR_SAO}, |
| 657 | {"cache-inhibited-large-page", feat_enable_large_ci, 0}, | 657 | {"cache-inhibited-large-page", feat_enable_large_ci, 0}, |
| 658 | {"coprocessor-icswx", feat_enable, 0}, | 658 | {"coprocessor-icswx", feat_enable, 0}, |
| 659 | {"hypervisor-virtualization-interrupt", feat_enable_hvi, 0}, | 659 | {"hypervisor-virtualization-interrupt", feat_enable_hvi, 0}, |
| @@ -113,6 +113,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM) · 112 unmodified lines | |||
| 113 | ld r11,exception_marker@toc(r2) | 113 | ld r11,exception_marker@toc(r2) |
| 114 | std r11,-16(r10) /* "regshere" marker */ | 114 | std r11,-16(r10) /* "regshere" marker */ |
| 115 | 115 | ||
| 116 | BEGIN_FTR_SECTION | ||
| 117 | HMT_MEDIUM | ||
| 118 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | ||
| 119 | |||
| 116 | /* | 120 | /* |
| 117 | * RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which | 121 | * RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which |
| 118 | * would clobber syscall parameters. Also we always enter with IRQs | 122 | * would clobber syscall parameters. Also we always enter with IRQs |
| @@ -548,7 +548,7 @@ void notrace restore_math(struct pt_regs *regs) · 547 unmodified lines | |||
| 548 | * are live for the user thread). | 548 | * are live for the user thread). |
| 549 | */ | 549 | */ |
| 550 | if ((!(msr & MSR_FP)) && should_restore_fp()) | 550 | if ((!(msr & MSR_FP)) && should_restore_fp()) |
| 551 | new_msr |= MSR_FP | current->thread.fpexc_mode; | 551 | new_msr |= MSR_FP; |
| 552 | 552 | ||
| 553 | if ((!(msr & MSR_VEC)) && should_restore_altivec()) | 553 | if ((!(msr & MSR_VEC)) && should_restore_altivec()) |
| 554 | new_msr |= MSR_VEC; | 554 | new_msr |= MSR_VEC; |
| @@ -559,11 +559,17 @@ void notrace restore_math(struct pt_regs *regs) · 4 unmodified lines | |||
| 559 | } | 559 | } |
| 560 | 560 | ||
| 561 | if (new_msr) { | 561 | if (new_msr) { |
| 562 | unsigned long fpexc_mode = 0; | ||
| 563 | |||
| 562 | msr_check_and_set(new_msr); | 564 | msr_check_and_set(new_msr); |
| 563 | 565 | ||
| 564 | if (new_msr & MSR_FP) | 566 | if (new_msr & MSR_FP) { |
| 565 | do_restore_fp(); | 567 | do_restore_fp(); |
| 566 | 568 | ||
| 569 | // This also covers VSX, because VSX implies FP | ||
| 570 | fpexc_mode = current->thread.fpexc_mode; | ||
| 571 | } | ||
| 572 | |||
| 567 | if (new_msr & MSR_VEC) | 573 | if (new_msr & MSR_VEC) |
| 568 | do_restore_altivec(); | 574 | do_restore_altivec(); |
| 569 | 575 | ||
| @@ -572,7 +578,7 @@ void notrace restore_math(struct pt_regs *regs) · 2 unmodified lines | |||
| 572 | 578 | ||
| 573 | msr_check_and_clear(new_msr); | 579 | msr_check_and_clear(new_msr); |
| 574 | 580 | ||
| 575 | regs->msr |= new_msr; | 581 | regs->msr |= new_msr | fpexc_mode; |
| 576 | } | 582 | } |
| 577 | } | 583 | } |
| 578 | #endif | 584 | #endif |
| @@ -232,6 +232,8 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags) · 231 unmodified lines | |||
| 232 | rflags |= HPTE_R_I; | 232 | rflags |= HPTE_R_I; |
| 233 | else if ((pteflags & _PAGE_CACHE_CTL) == _PAGE_NON_IDEMPOTENT) | 233 | else if ((pteflags & _PAGE_CACHE_CTL) == _PAGE_NON_IDEMPOTENT) |
| 234 | rflags |= (HPTE_R_I | HPTE_R_G); | 234 | rflags |= (HPTE_R_I | HPTE_R_G); |
| 235 | else if ((pteflags & _PAGE_CACHE_CTL) == _PAGE_SAO) | ||
| 236 | rflags |= (HPTE_R_W | HPTE_R_I | HPTE_R_M); | ||
| 235 | else | 237 | else |
| 236 | /* | 238 | /* |
| 237 | * Add memory coherence if cache inhibited is not set | 239 | * Add memory coherence if cache inhibited is not set |
| @@ -1557,9 +1557,16 @@ nocheck: · 1556 unmodified lines | |||
| 1557 | ret = 0; | 1557 | ret = 0; |
| 1558 | out: | 1558 | out: |
| 1559 | if (has_branch_stack(event)) { | 1559 | if (has_branch_stack(event)) { |
| 1560 | power_pmu_bhrb_enable(event); | 1560 | u64 bhrb_filter = -1; |
| 1561 | cpuhw->bhrb_filter = ppmu->bhrb_filter_map( | 1561 | |
| 1562 | event->attr.branch_sample_type); | 1562 | if (ppmu->bhrb_filter_map) |
| 1563 | bhrb_filter = ppmu->bhrb_filter_map( | ||
| 1564 | event->attr.branch_sample_type); | ||
| 1565 | |||
| 1566 | if (bhrb_filter != -1) { | ||
| 1567 | cpuhw->bhrb_filter = bhrb_filter; | ||
| 1568 | power_pmu_bhrb_enable(event); | ||
| 1569 | } | ||
| 1563 | } | 1570 | } |
| 1564 | 1571 | ||
| 1565 | perf_pmu_enable(event->pmu); | 1572 | perf_pmu_enable(event->pmu); |
| @@ -1881,7 +1888,6 @@ static int power_pmu_event_init(struct perf_event *event) · 315 unmodified lines | |||
| 1881 | int n; | 1888 | int n; |
| 1882 | int err; | 1889 | int err; |
| 1883 | struct cpu_hw_events *cpuhw; | 1890 | struct cpu_hw_events *cpuhw; |
| 1884 | u64 bhrb_filter; | ||
| 1885 | 1891 | ||
| 1886 | if (!ppmu) | 1892 | if (!ppmu) |
| 1887 | return -ENOENT; | 1893 | return -ENOENT; |
| @@ -1987,7 +1993,10 @@ static int power_pmu_event_init(struct perf_event *event) · 99 unmodified lines | |||
| 1987 | err = power_check_constraints(cpuhw, events, cflags, n + 1); | 1993 | err = power_check_constraints(cpuhw, events, cflags, n + 1); |
| 1988 | 1994 | ||
| 1989 | if (has_branch_stack(event)) { | 1995 | if (has_branch_stack(event)) { |
| 1990 | bhrb_filter = ppmu->bhrb_filter_map( | 1996 | u64 bhrb_filter = -1; |
| 1997 | |||
| 1998 | if (ppmu->bhrb_filter_map) | ||
| 1999 | bhrb_filter = ppmu->bhrb_filter_map( | ||
| 1991 | event->attr.branch_sample_type); | 2000 | event->attr.branch_sample_type); |
| 1992 | 2001 | ||
| 1993 | if (bhrb_filter == -1) { | 2002 | if (bhrb_filter == -1) { |
| @@ -1289,7 +1289,7 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem, · 1288 unmodified lines | |||
| 1289 | header->misc = 0; | 1289 | header->misc = 0; |
| 1290 | 1290 | ||
| 1291 | if (cpu_has_feature(CPU_FTR_ARCH_31)) { | 1291 | if (cpu_has_feature(CPU_FTR_ARCH_31)) { |
| 1292 | switch (IMC_TRACE_RECORD_VAL_HVPR(mem->val)) { | 1292 | switch (IMC_TRACE_RECORD_VAL_HVPR(be64_to_cpu(READ_ONCE(mem->val)))) { |
| 1293 | case 0:/* when MSR HV and PR not set in the trace-record */ | 1293 | case 0:/* when MSR HV and PR not set in the trace-record */ |
| 1294 | header->misc |= PERF_RECORD_MISC_GUEST_KERNEL; | 1294 | header->misc |= PERF_RECORD_MISC_GUEST_KERNEL; |
| 1295 | break; | 1295 | break; |
| @@ -1297,7 +1297,7 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem, · 1 unmodified line | |||
| 1297 | header->misc |= PERF_RECORD_MISC_GUEST_USER; | 1297 | header->misc |= PERF_RECORD_MISC_GUEST_USER; |
| 1298 | break; | 1298 | break; |
| 1299 | case 2: /* MSR HV is 1 and PR is 0 */ | 1299 | case 2: /* MSR HV is 1 and PR is 0 */ |
| 1300 | header->misc |= PERF_RECORD_MISC_HYPERVISOR; | 1300 | header->misc |= PERF_RECORD_MISC_KERNEL; |
| 1301 | break; | 1301 | break; |
| 1302 | case 3: /* MSR HV is 1 and PR is 1 */ | 1302 | case 3: /* MSR HV is 1 and PR is 1 */ |
| 1303 | header->misc |= PERF_RECORD_MISC_USER; | 1303 | header->misc |= PERF_RECORD_MISC_USER; |
| @@ -36,7 +36,7 @@ config PPC_BOOK3S_6xx · 35 unmodified lines | |||
| 36 | select PPC_HAVE_PMU_SUPPORT | 36 | select PPC_HAVE_PMU_SUPPORT |
| 37 | select PPC_HAVE_KUEP | 37 | select PPC_HAVE_KUEP |
| 38 | select PPC_HAVE_KUAP | 38 | select PPC_HAVE_KUAP |
| 39 | select HAVE_ARCH_VMAP_STACK | 39 | select HAVE_ARCH_VMAP_STACK if !ADB_PMU |
| 40 | 40 | ||
| 41 | config PPC_BOOK3S_601 | 41 | config PPC_BOOK3S_601 |
| 42 | bool "PowerPC 601" | 42 | bool "PowerPC 601" |
| @@ -1223,7 +1223,7 @@ static void __init pnv_probe_idle_states(void) · 1222 unmodified lines | |||
| 1223 | return; | 1223 | return; |
| 1224 | } | 1224 | } |
| 1225 | 1225 | ||
| 1226 | if (pvr_version_is(PVR_POWER9)) | 1226 | if (cpu_has_feature(CPU_FTR_ARCH_300)) |
| 1227 | pnv_power9_idle_init(); | 1227 | pnv_power9_idle_init(); |
| 1228 | 1228 | ||
| 1229 | for (i = 0; i < nr_pnv_idle_states; i++) | 1229 | for (i = 0; i < nr_pnv_idle_states; i++) |
| @@ -49,6 +49,8 @@ · 48 unmodified lines | |||
| 49 | #include <linux/cuda.h> | 49 | #include <linux/cuda.h> |
| 50 | #ifdef CONFIG_PPC_PMAC | 50 | #ifdef CONFIG_PPC_PMAC |
| 51 | #include <asm/prom.h> | 51 | #include <asm/prom.h> |
| 52 | #endif | ||
| 53 | #ifdef CONFIG_BOOTX_TEXT | ||
| 52 | #include <asm/btext.h> | 54 | #include <asm/btext.h> |
| 53 | #endif | 55 | #endif |
| 54 | 56 | ||
| @@ -324,6 +324,8 @@ extern unsigned int kobjsize(const void *objp); · 323 unmodified lines | |||
| 324 | 324 | ||
| 325 | #if defined(CONFIG_X86) | 325 | #if defined(CONFIG_X86) |
| 326 | # define VM_PAT VM_ARCH_1 /* PAT reserves whole VMA at once (x86) */ | 326 | # define VM_PAT VM_ARCH_1 /* PAT reserves whole VMA at once (x86) */ |
| 327 | #elif defined(CONFIG_PPC) | ||
| 328 | # define VM_SAO VM_ARCH_1 /* Strong Access Ordering (powerpc) */ | ||
| 327 | #elif defined(CONFIG_PARISC) | 329 | #elif defined(CONFIG_PARISC) |
| 328 | # define VM_GROWSUP VM_ARCH_1 | 330 | # define VM_GROWSUP VM_ARCH_1 |
| 329 | #elif defined(CONFIG_IA64) | 331 | #elif defined(CONFIG_IA64) |
| @@ -114,6 +114,8 @@ IF_HAVE_PG_IDLE(PG_idle, "idle" ) · 113 unmodified lines | |||
| 114 | 114 | ||
| 115 | #if defined(CONFIG_X86) | 115 | #if defined(CONFIG_X86) |
| 116 | #define __VM_ARCH_SPECIFIC_1 {VM_PAT, "pat" } | 116 | #define __VM_ARCH_SPECIFIC_1 {VM_PAT, "pat" } |
| 117 | #elif defined(CONFIG_PPC) | ||
| 118 | #define __VM_ARCH_SPECIFIC_1 {VM_SAO, "sao" } | ||
| 117 | #elif defined(CONFIG_PARISC) || defined(CONFIG_IA64) | 119 | #elif defined(CONFIG_PARISC) || defined(CONFIG_IA64) |
| 118 | #define __VM_ARCH_SPECIFIC_1 {VM_GROWSUP, "growsup" } | 120 | #define __VM_ARCH_SPECIFIC_1 {VM_GROWSUP, "growsup" } |
| 119 | #elif !defined(CONFIG_MMU) | 121 | #elif !defined(CONFIG_MMU) |
| @@ -2453,6 +2453,10 @@ int ksm_madvise(struct vm_area_struct *vma, unsigned long start, · 2452 unmodified lines | |||
| 2453 | if (vma_is_dax(vma)) | 2453 | if (vma_is_dax(vma)) |
| 2454 | return 0; | 2454 | return 0; |
| 2455 | 2455 | ||
| 2456 | #ifdef VM_SAO | ||
| 2457 | if (*vm_flags & VM_SAO) | ||
| 2458 | return 0; | ||
| 2459 | #endif | ||
| 2456 | #ifdef VM_SPARC_ADI | 2460 | #ifdef VM_SPARC_ADI |
| 2457 | if (*vm_flags & VM_SPARC_ADI) | 2461 | if (*vm_flags & VM_SPARC_ADI) |
| 2458 | return 0; | 2462 | return 0; |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | hugetlb_vs_thp_test | 2 | hugetlb_vs_thp_test |
| 3 | subpage_prot | 3 | subpage_prot |
| 4 | tempfile | 4 | tempfile |
| 5 | prot_sao | ||
| 5 | segv_errors | 6 | segv_errors |
| 6 | wild_bctr | 7 | wild_bctr |
| 7 | large_vm_fork_separation | 8 | large_vm_fork_separation |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | noarg: | 2 | noarg: |
| 3 | $(MAKE) -C ../ | 3 | $(MAKE) -C ../ |
| 4 | 4 | ||
| 5 | TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot segv_errors wild_bctr \ | 5 | TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao segv_errors wild_bctr \ |
| 6 | large_vm_fork_separation bad_accesses pkey_exec_prot \ | 6 | large_vm_fork_separation bad_accesses pkey_exec_prot \ |
| 7 | pkey_siginfo stack_expansion_signal stack_expansion_ldst | 7 | pkey_siginfo stack_expansion_signal stack_expansion_ldst |
| 8 | 8 | ||
| @@ -14,6 +14,8 @@ include ../../lib.mk · 5 unmodified lines | |||
| 14 | 14 | ||
| 15 | $(TEST_GEN_PROGS): ../harness.c ../utils.c | 15 | $(TEST_GEN_PROGS): ../harness.c ../utils.c |
| 16 | 16 | ||
| 17 | $(OUTPUT)/prot_sao: ../utils.c | ||
| 18 | |||
| 17 | $(OUTPUT)/wild_bctr: CFLAGS += -m64 | 19 | $(OUTPUT)/wild_bctr: CFLAGS += -m64 |
| 18 | $(OUTPUT)/large_vm_fork_separation: CFLAGS += -m64 | 20 | $(OUTPUT)/large_vm_fork_separation: CFLAGS += -m64 |
| 19 | $(OUTPUT)/bad_accesses: CFLAGS += -m64 | 21 | $(OUTPUT)/bad_accesses: CFLAGS += -m64 |
| @@ -0,0 +1,43 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright 2016, Michael Ellerman, IBM Corp. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <stdio.h> | ||
| 7 | #include <stdlib.h> | ||
| 8 | #include <string.h> | ||
| 9 | #include <sys/mman.h> | ||
| 10 | |||
| 11 | #include <asm/cputable.h> | ||
| 12 | |||
| 13 | #include "utils.h" | ||
| 14 | |||
| 15 | #define SIZE (64 * 1024) | ||
| 16 | |||
| 17 | int test_prot_sao(void) | ||
| 18 | { | ||
| 19 | char *p; | ||
| 20 | |||
| 21 | /* SAO was introduced in 2.06 and removed in 3.1 */ | ||
| 22 | SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06) || | ||
| 23 | have_hwcap2(PPC_FEATURE2_ARCH_3_1)); | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Ensure we can ask for PROT_SAO. | ||
| 27 | * We can't really verify that it does the right thing, but at least we | ||
| 28 | * confirm the kernel will accept it. | ||
| 29 | */ | ||
| 30 | p = mmap(NULL, SIZE, PROT_READ | PROT_WRITE | PROT_SAO, | ||
| 31 | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | ||
| 32 | FAIL_IF(p == MAP_FAILED); | ||
| 33 | |||
| 34 | /* Write to the mapping, to at least cause a fault */ | ||
| 35 | memset(p, 0xaa, SIZE); | ||
| 36 | |||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | int main(void) | ||
| 41 | { | ||
| 42 | return test_harness(test_prot_sao, "prot-sao"); | ||
| 43 | } | ||