diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-04-08 14:06:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-04-08 14:06:12 -0400 |
commit | 894ca30cf6ddf891aa17c39a4b8d511c0a8cf2e9 (patch) | |
tree | 677edeb5c76f9570252bac09e2885b3abf572f33 | |
parent | cf01fb9985e8deb25ccf0ea54d916b8871ae0e62 (diff) | |
parent | 4749228f022893faf54a3dbc70796f78b7d4f342 (diff) |
Merge tag 'powerpc-4.11-7' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman:
"Some more powerpc fixes for 4.11:
Headed to stable:
- disable HFSCR[TM] if TM is not supported, fixes a potential host
kernel crash triggered by a hostile guest, but only in
configurations that no one uses
- don't try to fix up misaligned load-with-reservation instructions
- fix flush_(d|i)cache_range() called from modules on little endian
kernels
- add missing global TLB invalidate if cxl is active
- fix missing preempt_disable() in crc32c-vpmsum
And a fix for selftests build changes that went in this release:
- selftests/powerpc: Fix standalone powerpc build
Thanks to: Benjamin Herrenschmidt, Frederic Barrat, Oliver O'Halloran,
Paul Mackerras"
* tag 'powerpc-4.11-7' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
powerpc/crypto/crc32c-vpmsum: Fix missing preempt_disable()
powerpc/mm: Add missing global TLB invalidate if cxl is active
powerpc/64: Fix flush_(d|i)cache_range() called from modules
powerpc: Don't try to fix up misaligned load-with-reservation instructions
powerpc: Disable HFSCR[TM] if TM is not supported
selftests/powerpc: Fix standalone powerpc build
-rw-r--r-- | arch/powerpc/crypto/crc32c-vpmsum_glue.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/align.c | 27 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_64.S | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 9 | ||||
-rw-r--r-- | arch/powerpc/mm/hash_native_64.c | 7 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/Makefile | 10 |
6 files changed, 43 insertions, 17 deletions
diff --git a/arch/powerpc/crypto/crc32c-vpmsum_glue.c b/arch/powerpc/crypto/crc32c-vpmsum_glue.c index 411994551afc..f058e0c3e4d4 100644 --- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c +++ b/arch/powerpc/crypto/crc32c-vpmsum_glue.c | |||
@@ -33,10 +33,13 @@ static u32 crc32c_vpmsum(u32 crc, unsigned char const *p, size_t len) | |||
33 | } | 33 | } |
34 | 34 | ||
35 | if (len & ~VMX_ALIGN_MASK) { | 35 | if (len & ~VMX_ALIGN_MASK) { |
36 | preempt_disable(); | ||
36 | pagefault_disable(); | 37 | pagefault_disable(); |
37 | enable_kernel_altivec(); | 38 | enable_kernel_altivec(); |
38 | crc = __crc32c_vpmsum(crc, p, len & ~VMX_ALIGN_MASK); | 39 | crc = __crc32c_vpmsum(crc, p, len & ~VMX_ALIGN_MASK); |
40 | disable_kernel_altivec(); | ||
39 | pagefault_enable(); | 41 | pagefault_enable(); |
42 | preempt_enable(); | ||
40 | } | 43 | } |
41 | 44 | ||
42 | tail = len & VMX_ALIGN_MASK; | 45 | tail = len & VMX_ALIGN_MASK; |
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index cbc7c42cdb74..ec7a8b099dd9 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c | |||
@@ -807,14 +807,25 @@ int fix_alignment(struct pt_regs *regs) | |||
807 | nb = aligninfo[instr].len; | 807 | nb = aligninfo[instr].len; |
808 | flags = aligninfo[instr].flags; | 808 | flags = aligninfo[instr].flags; |
809 | 809 | ||
810 | /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */ | 810 | /* |
811 | if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) { | 811 | * Handle some cases which give overlaps in the DSISR values. |
812 | nb = 8; | 812 | */ |
813 | flags = LD+SW; | 813 | if (IS_XFORM(instruction)) { |
814 | } else if (IS_XFORM(instruction) && | 814 | switch (get_xop(instruction)) { |
815 | ((instruction >> 1) & 0x3ff) == 660) { | 815 | case 532: /* ldbrx */ |
816 | nb = 8; | 816 | nb = 8; |
817 | flags = ST+SW; | 817 | flags = LD+SW; |
818 | break; | ||
819 | case 660: /* stdbrx */ | ||
820 | nb = 8; | ||
821 | flags = ST+SW; | ||
822 | break; | ||
823 | case 20: /* lwarx */ | ||
824 | case 84: /* ldarx */ | ||
825 | case 116: /* lharx */ | ||
826 | case 276: /* lqarx */ | ||
827 | return 0; /* not emulated ever */ | ||
828 | } | ||
818 | } | 829 | } |
819 | 830 | ||
820 | /* Byteswap little endian loads and stores */ | 831 | /* Byteswap little endian loads and stores */ |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index ae179cb1bb3c..c119044cad0d 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -67,7 +67,7 @@ PPC64_CACHES: | |||
67 | * flush all bytes from start through stop-1 inclusive | 67 | * flush all bytes from start through stop-1 inclusive |
68 | */ | 68 | */ |
69 | 69 | ||
70 | _GLOBAL(flush_icache_range) | 70 | _GLOBAL_TOC(flush_icache_range) |
71 | BEGIN_FTR_SECTION | 71 | BEGIN_FTR_SECTION |
72 | PURGE_PREFETCHED_INS | 72 | PURGE_PREFETCHED_INS |
73 | blr | 73 | blr |
@@ -120,7 +120,7 @@ EXPORT_SYMBOL(flush_icache_range) | |||
120 | * | 120 | * |
121 | * flush all bytes from start to stop-1 inclusive | 121 | * flush all bytes from start to stop-1 inclusive |
122 | */ | 122 | */ |
123 | _GLOBAL(flush_dcache_range) | 123 | _GLOBAL_TOC(flush_dcache_range) |
124 | 124 | ||
125 | /* | 125 | /* |
126 | * Flush the data cache to memory | 126 | * Flush the data cache to memory |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 9cfaa8b69b5f..f997154dfc41 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -236,6 +236,15 @@ static void cpu_ready_for_interrupts(void) | |||
236 | mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); | 236 | mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); |
237 | } | 237 | } |
238 | 238 | ||
239 | /* | ||
240 | * Fixup HFSCR:TM based on CPU features. The bit is set by our | ||
241 | * early asm init because at that point we haven't updated our | ||
242 | * CPU features from firmware and device-tree. Here we have, | ||
243 | * so let's do it. | ||
244 | */ | ||
245 | if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP)) | ||
246 | mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM); | ||
247 | |||
239 | /* Set IR and DR in PACA MSR */ | 248 | /* Set IR and DR in PACA MSR */ |
240 | get_paca()->kernel_msr = MSR_KERNEL; | 249 | get_paca()->kernel_msr = MSR_KERNEL; |
241 | } | 250 | } |
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index cc332608e656..65bb8f33b399 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -638,6 +638,10 @@ static void native_flush_hash_range(unsigned long number, int local) | |||
638 | unsigned long psize = batch->psize; | 638 | unsigned long psize = batch->psize; |
639 | int ssize = batch->ssize; | 639 | int ssize = batch->ssize; |
640 | int i; | 640 | int i; |
641 | unsigned int use_local; | ||
642 | |||
643 | use_local = local && mmu_has_feature(MMU_FTR_TLBIEL) && | ||
644 | mmu_psize_defs[psize].tlbiel && !cxl_ctx_in_use(); | ||
641 | 645 | ||
642 | local_irq_save(flags); | 646 | local_irq_save(flags); |
643 | 647 | ||
@@ -667,8 +671,7 @@ static void native_flush_hash_range(unsigned long number, int local) | |||
667 | } pte_iterate_hashed_end(); | 671 | } pte_iterate_hashed_end(); |
668 | } | 672 | } |
669 | 673 | ||
670 | if (mmu_has_feature(MMU_FTR_TLBIEL) && | 674 | if (use_local) { |
671 | mmu_psize_defs[psize].tlbiel && local) { | ||
672 | asm volatile("ptesync":::"memory"); | 675 | asm volatile("ptesync":::"memory"); |
673 | for (i = 0; i < number; i++) { | 676 | for (i = 0; i < number; i++) { |
674 | vpn = batch->vpn[i]; | 677 | vpn = batch->vpn[i]; |
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 1c5d0575802e..bf13fc2297aa 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile | |||
@@ -34,34 +34,34 @@ endif | |||
34 | all: $(SUB_DIRS) | 34 | all: $(SUB_DIRS) |
35 | 35 | ||
36 | $(SUB_DIRS): | 36 | $(SUB_DIRS): |
37 | BUILD_TARGET=$$OUTPUT/$@; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $@ all | 37 | BUILD_TARGET=$(OUTPUT)/$@; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $@ all |
38 | 38 | ||
39 | include ../lib.mk | 39 | include ../lib.mk |
40 | 40 | ||
41 | override define RUN_TESTS | 41 | override define RUN_TESTS |
42 | @for TARGET in $(SUB_DIRS); do \ | 42 | @for TARGET in $(SUB_DIRS); do \ |
43 | BUILD_TARGET=$$OUTPUT/$$TARGET; \ | 43 | BUILD_TARGET=$(OUTPUT)/$$TARGET; \ |
44 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ | 44 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ |
45 | done; | 45 | done; |
46 | endef | 46 | endef |
47 | 47 | ||
48 | override define INSTALL_RULE | 48 | override define INSTALL_RULE |
49 | @for TARGET in $(SUB_DIRS); do \ | 49 | @for TARGET in $(SUB_DIRS); do \ |
50 | BUILD_TARGET=$$OUTPUT/$$TARGET; \ | 50 | BUILD_TARGET=$(OUTPUT)/$$TARGET; \ |
51 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install;\ | 51 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install;\ |
52 | done; | 52 | done; |
53 | endef | 53 | endef |
54 | 54 | ||
55 | override define EMIT_TESTS | 55 | override define EMIT_TESTS |
56 | @for TARGET in $(SUB_DIRS); do \ | 56 | @for TARGET in $(SUB_DIRS); do \ |
57 | BUILD_TARGET=$$OUTPUT/$$TARGET; \ | 57 | BUILD_TARGET=$(OUTPUT)/$$TARGET; \ |
58 | $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\ | 58 | $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\ |
59 | done; | 59 | done; |
60 | endef | 60 | endef |
61 | 61 | ||
62 | clean: | 62 | clean: |
63 | @for TARGET in $(SUB_DIRS); do \ | 63 | @for TARGET in $(SUB_DIRS); do \ |
64 | BUILD_TARGET=$$OUTPUT/$$TARGET; \ | 64 | BUILD_TARGET=$(OUTPUT)/$$TARGET; \ |
65 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean; \ | 65 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean; \ |
66 | done; | 66 | done; |
67 | rm -f tags | 67 | rm -f tags |