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 | 49 | Register preservation rules match the ELF ABI calling sequence with the |
| 50 | 50 | following differences: |
| 51 | 51 | |
| 52 | −=========== ============= ======================================== | |
| 53 | 52 | --- For the sc instruction, differences with the ELF ABI --- |
| 53 | +=========== ============= ======================================== | |
| 54 | 54 | r0 Volatile (System call number.) |
| 55 | 55 | r3 Volatile (Parameter 1, and return value.) |
| 56 | 56 | r4-r8 Volatile (Parameters 2-6.) |
| 57 | 57 | cr0 Volatile (cr0.SO is the return error condition.) |
| 58 | 58 | cr1, cr5-7 Nonvolatile |
| 59 | 59 | lr Nonvolatile |
| 60 | +=========== ============= ======================================== | |
| 60 | 61 | |
| 61 | 62 | --- For the scv 0 instruction, differences with the ELF ABI --- |
| 63 | +=========== ============= ======================================== | |
| 62 | 64 | r0 Volatile (System call number.) |
| 63 | 65 | r3 Volatile (Parameter 1, and return value.) |
| 64 | 66 | r4-r8 Volatile (Parameters 2-6.) |
| @@ -860,6 +860,18 @@ config PPC_SUBPAGE_PROT · 859 unmodified lines | ||
| 860 | 860 | |
| 861 | 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 | 875 | config PPC_COPRO_BASE |
| 864 | 876 | bool |
| 865 | 877 | |
| @@ -20,13 +20,9 @@ · 19 unmodified lines | ||
| 20 | 20 | #define _PAGE_RW (_PAGE_READ | _PAGE_WRITE) |
| 21 | 21 | #define _PAGE_RWX (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC) |
| 22 | 22 | #define _PAGE_PRIVILEGED 0x00008 /* kernel access only */ |
| 23 | − | |
| 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 */ | |
| 23 | +#define _PAGE_SAO 0x00010 /* Strong access order */ | |
| 27 | 24 | #define _PAGE_NON_IDEMPOTENT 0x00020 /* non idempotent memory */ |
| 28 | 25 | #define _PAGE_TOLERANT 0x00030 /* tolerant memory, cache inhibited */ |
| 29 | − | |
| 30 | 26 | #define _PAGE_DIRTY 0x00080 /* C: page changed */ |
| 31 | 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 | 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 | 829 | #define pgprot_noncached pgprot_noncached |
| 832 | 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 | 196 | #define CPU_FTR_SPURR LONG_ASM_CONST(0x0000000001000000) |
| 197 | 197 | #define CPU_FTR_DSCR LONG_ASM_CONST(0x0000000002000000) |
| 198 | 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 | 200 | #define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0000000010000000) |
| 201 | 201 | #define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0000000020000000) |
| 202 | 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 | 441 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
| 442 | 442 | CPU_FTR_COHERENT_ICACHE | \ |
| 443 | 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 | 445 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
| 446 | 446 | CPU_FTR_CFAR | CPU_FTR_HVMODE | \ |
| 447 | 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 | 450 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
| 451 | 451 | CPU_FTR_COHERENT_ICACHE | \ |
| 452 | 452 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ |
| 453 | − CPU_FTR_DSCR | \ | |
| 453 | + CPU_FTR_DSCR | CPU_FTR_SAO | \ | |
| 454 | 454 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
| 455 | 455 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ |
| 456 | 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 | 461 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
| 462 | 462 | CPU_FTR_COHERENT_ICACHE | \ |
| 463 | 463 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ |
| 464 | − CPU_FTR_DSCR | \ | |
| 464 | + CPU_FTR_DSCR | CPU_FTR_SAO | \ | |
| 465 | 465 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
| 466 | 466 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ |
| 467 | 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 | 479 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
| 480 | 480 | CPU_FTR_COHERENT_ICACHE | \ |
| 481 | 481 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ |
| 482 | − CPU_FTR_DSCR | \ | |
| 482 | + CPU_FTR_DSCR | CPU_FTR_SAO | \ | |
| 483 | 483 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
| 484 | 484 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ |
| 485 | 485 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \ |
| @@ -13,20 +13,43 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/pkeys.h> |
| 14 | 14 | #include <asm/cpu_has_feature.h> |
| 15 | 15 | |
| 16 | −#ifdef CONFIG_PPC_MEM_KEYS | |
| 17 | 16 | static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, |
| 18 | 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 | 25 | #define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey) |
| 23 | 26 | |
| 24 | 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 | 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 | 54 | #endif /* CONFIG_PPC64 */ |
| 32 | 55 | #endif /* _ASM_POWERPC_MMAN_H */ |
| @@ -82,6 +82,8 @@ · 81 unmodified lines | ||
| 82 | 82 | */ |
| 83 | 83 | #include <asm/nohash/pte-book3e.h> |
| 84 | 84 | |
| 85 | +#define _PAGE_SAO 0 | |
| 86 | + | |
| 85 | 87 | #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) |
| 86 | 88 | |
| 87 | 89 | /* |
| @@ -11,7 +11,7 @@ · 10 unmodified lines | ||
| 11 | 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 | 16 | #define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ |
| 17 | 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 | 653 | {"processor-control-facility-v3", feat_enable_dbell, CPU_FTR_DBELL}, |
| 654 | 654 | {"processor-utilization-of-resources-register", feat_enable_purr, 0}, |
| 655 | 655 | {"no-execute", feat_enable, 0}, |
| 656 | − /* strong-access-ordering is unused */ | |
| 656 | + {"strong-access-ordering", feat_enable, CPU_FTR_SAO}, | |
| 657 | 657 | {"cache-inhibited-large-page", feat_enable_large_ci, 0}, |
| 658 | 658 | {"coprocessor-icswx", feat_enable, 0}, |
| 659 | 659 | {"hypervisor-virtualization-interrupt", feat_enable_hvi, 0}, |
| @@ -113,6 +113,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM) · 112 unmodified lines | ||
| 113 | 113 | ld r11,exception_marker@toc(r2) |
| 114 | 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 | 121 | * RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which |
| 118 | 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 | 548 | * are live for the user thread). |
| 549 | 549 | */ |
| 550 | 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 | 553 | if ((!(msr & MSR_VEC)) && should_restore_altivec()) |
| 554 | 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 | 561 | if (new_msr) { |
| 562 | + unsigned long fpexc_mode = 0; | |
| 563 | + | |
| 562 | 564 | msr_check_and_set(new_msr); |
| 563 | 565 | |
| 564 | − if (new_msr & MSR_FP) | |
| 566 | + if (new_msr & MSR_FP) { | |
| 565 | 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 | 573 | if (new_msr & MSR_VEC) |
| 568 | 574 | do_restore_altivec(); |
| 569 | 575 | |
| @@ -572,7 +578,7 @@ void notrace restore_math(struct pt_regs *regs) · 2 unmodified lines | ||
| 572 | 578 | |
| 573 | 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 | 584 | #endif |
| @@ -232,6 +232,8 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags) · 231 unmodified lines | ||
| 232 | 232 | rflags |= HPTE_R_I; |
| 233 | 233 | else if ((pteflags & _PAGE_CACHE_CTL) == _PAGE_NON_IDEMPOTENT) |
| 234 | 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 | 237 | else |
| 236 | 238 | /* |
| 237 | 239 | * Add memory coherence if cache inhibited is not set |
| @@ -1557,9 +1557,16 @@ nocheck: · 1556 unmodified lines | ||
| 1557 | 1557 | ret = 0; |
| 1558 | 1558 | out: |
| 1559 | 1559 | if (has_branch_stack(event)) { |
| 1560 | − power_pmu_bhrb_enable(event); | |
| 1561 | − cpuhw->bhrb_filter = ppmu->bhrb_filter_map( | |
| 1562 | − event->attr.branch_sample_type); | |
| 1560 | + u64 bhrb_filter = -1; | |
| 1561 | + | |
| 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 | 1572 | perf_pmu_enable(event->pmu); |
| @@ -1881,7 +1888,6 @@ static int power_pmu_event_init(struct perf_event *event) · 315 unmodified lines | ||
| 1881 | 1888 | int n; |
| 1882 | 1889 | int err; |
| 1883 | 1890 | struct cpu_hw_events *cpuhw; |
| 1884 | − u64 bhrb_filter; | |
| 1885 | 1891 | |
| 1886 | 1892 | if (!ppmu) |
| 1887 | 1893 | return -ENOENT; |
| @@ -1987,7 +1993,10 @@ static int power_pmu_event_init(struct perf_event *event) · 99 unmodified lines | ||
| 1987 | 1993 | err = power_check_constraints(cpuhw, events, cflags, n + 1); |
| 1988 | 1994 | |
| 1989 | 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 | 2000 | event->attr.branch_sample_type); |
| 1992 | 2001 | |
| 1993 | 2002 | if (bhrb_filter == -1) { |
| @@ -1289,7 +1289,7 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem, · 1288 unmodified lines | ||
| 1289 | 1289 | header->misc = 0; |
| 1290 | 1290 | |
| 1291 | 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 | 1293 | case 0:/* when MSR HV and PR not set in the trace-record */ |
| 1294 | 1294 | header->misc |= PERF_RECORD_MISC_GUEST_KERNEL; |
| 1295 | 1295 | break; |
| @@ -1297,7 +1297,7 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem, · 1 unmodified line | ||
| 1297 | 1297 | header->misc |= PERF_RECORD_MISC_GUEST_USER; |
| 1298 | 1298 | break; |
| 1299 | 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 | 1301 | break; |
| 1302 | 1302 | case 3: /* MSR HV is 1 and PR is 1 */ |
| 1303 | 1303 | header->misc |= PERF_RECORD_MISC_USER; |
| @@ -36,7 +36,7 @@ config PPC_BOOK3S_6xx · 35 unmodified lines | ||
| 36 | 36 | select PPC_HAVE_PMU_SUPPORT |
| 37 | 37 | select PPC_HAVE_KUEP |
| 38 | 38 | select PPC_HAVE_KUAP |
| 39 | − select HAVE_ARCH_VMAP_STACK | |
| 39 | + select HAVE_ARCH_VMAP_STACK if !ADB_PMU | |
| 40 | 40 | |
| 41 | 41 | config PPC_BOOK3S_601 |
| 42 | 42 | bool "PowerPC 601" |
| @@ -1223,7 +1223,7 @@ static void __init pnv_probe_idle_states(void) · 1222 unmodified lines | ||
| 1223 | 1223 | return; |
| 1224 | 1224 | } |
| 1225 | 1225 | |
| 1226 | − if (pvr_version_is(PVR_POWER9)) | |
| 1226 | + if (cpu_has_feature(CPU_FTR_ARCH_300)) | |
| 1227 | 1227 | pnv_power9_idle_init(); |
| 1228 | 1228 | |
| 1229 | 1229 | for (i = 0; i < nr_pnv_idle_states; i++) |
| @@ -49,6 +49,8 @@ · 48 unmodified lines | ||
| 49 | 49 | #include <linux/cuda.h> |
| 50 | 50 | #ifdef CONFIG_PPC_PMAC |
| 51 | 51 | #include <asm/prom.h> |
| 52 | +#endif | |
| 53 | +#ifdef CONFIG_BOOTX_TEXT | |
| 52 | 54 | #include <asm/btext.h> |
| 53 | 55 | #endif |
| 54 | 56 | |
| @@ -324,6 +324,8 @@ extern unsigned int kobjsize(const void *objp); · 323 unmodified lines | ||
| 324 | 324 | |
| 325 | 325 | #if defined(CONFIG_X86) |
| 326 | 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 | 329 | #elif defined(CONFIG_PARISC) |
| 328 | 330 | # define VM_GROWSUP VM_ARCH_1 |
| 329 | 331 | #elif defined(CONFIG_IA64) |
| @@ -114,6 +114,8 @@ IF_HAVE_PG_IDLE(PG_idle, "idle" ) · 113 unmodified lines | ||
| 114 | 114 | |
| 115 | 115 | #if defined(CONFIG_X86) |
| 116 | 116 | #define __VM_ARCH_SPECIFIC_1 {VM_PAT, "pat" } |
| 117 | +#elif defined(CONFIG_PPC) | |
| 118 | +#define __VM_ARCH_SPECIFIC_1 {VM_SAO, "sao" } | |
| 117 | 119 | #elif defined(CONFIG_PARISC) || defined(CONFIG_IA64) |
| 118 | 120 | #define __VM_ARCH_SPECIFIC_1 {VM_GROWSUP, "growsup" } |
| 119 | 121 | #elif !defined(CONFIG_MMU) |
| @@ -2453,6 +2453,10 @@ int ksm_madvise(struct vm_area_struct *vma, unsigned long start, · 2452 unmodified lines | ||
| 2453 | 2453 | if (vma_is_dax(vma)) |
| 2454 | 2454 | return 0; |
| 2455 | 2455 | |
| 2456 | +#ifdef VM_SAO | |
| 2457 | + if (*vm_flags & VM_SAO) | |
| 2458 | + return 0; | |
| 2459 | +#endif | |
| 2456 | 2460 | #ifdef VM_SPARC_ADI |
| 2457 | 2461 | if (*vm_flags & VM_SPARC_ADI) |
| 2458 | 2462 | return 0; |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | hugetlb_vs_thp_test |
| 3 | 3 | subpage_prot |
| 4 | 4 | tempfile |
| 5 | +prot_sao | |
| 5 | 6 | segv_errors |
| 6 | 7 | wild_bctr |
| 7 | 8 | large_vm_fork_separation |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | noarg: |
| 3 | 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 | 6 | large_vm_fork_separation bad_accesses pkey_exec_prot \ |
| 7 | 7 | pkey_siginfo stack_expansion_signal stack_expansion_ldst |
| 8 | 8 | |
| @@ -14,6 +14,8 @@ include ../../lib.mk · 5 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | $(TEST_GEN_PROGS): ../harness.c ../utils.c |
| 16 | 16 | |
| 17 | +$(OUTPUT)/prot_sao: ../utils.c | |
| 18 | + | |
| 17 | 19 | $(OUTPUT)/wild_bctr: CFLAGS += -m64 |
| 18 | 20 | $(OUTPUT)/large_vm_fork_separation: CFLAGS += -m64 |
| 19 | 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 | +} | |