diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-14 08:48:13 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-14 08:48:13 -0700 |
commit | d785610f052d7456497cdec2a2406f6d4b16569f (patch) | |
tree | d9954bd05a3f1c8204f1aafa994e128e042cc312 /arch | |
parent | aea23e7c464bfdec04b52cf61edb62030e9e0d0a (diff) | |
parent | 83ee9f23763a432a4077bf20624ee35de87bce99 (diff) |
Merge tag 'powerpc-6.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman:
- Ensure we never emit lwarx with EH=1 on 32-bit, because some 32-bit
CPUs trap on it rather than ignoring it as they should.
- Fix ftrace when building with clang, which was broken by some
refactoring.
- A couple of other minor fixes.
Thanks to Christophe Leroy, Naveen N. Rao, Nick Desaulniers, Ondrej
Mosnacek, Pali Rohár, Russell Currey, and Segher Boessenkool.
* tag 'powerpc-6.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
powerpc/kexec: Fix build failure from uninitialised variable
powerpc/ppc-opcode: Fix PPC_RAW_TW()
powerpc64/ftrace: Fix ftrace for clang builds
powerpc: Make eh value more explicit when using lwarx
powerpc: Don't hide eh field of lwarx behind a macro
powerpc: Fix eh field when calling lwarx on PPC32
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/atomic.h | 5 | ||||
-rw-r--r-- | arch/powerpc/include/asm/bitops.h | 4 | ||||
-rw-r--r-- | arch/powerpc/include/asm/ppc-opcode.h | 13 | ||||
-rw-r--r-- | arch/powerpc/include/asm/simple_spinlock.h | 15 | ||||
-rw-r--r-- | arch/powerpc/kernel/trace/ftrace.c | 8 | ||||
-rw-r--r-- | arch/powerpc/kexec/file_load_64.c | 10 |
6 files changed, 25 insertions, 30 deletions
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index 853dc86864f4..486ab7889121 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h @@ -140,9 +140,10 @@ static __always_inline bool arch_atomic_try_cmpxchg_lock(atomic_t *v, int *old, int new) { int r, o = *old; + unsigned int eh = IS_ENABLED(CONFIG_PPC64); __asm__ __volatile__ ( -"1: lwarx %0,0,%2,%5 # atomic_try_cmpxchg_acquire \n" +"1: lwarx %0,0,%2,%[eh] # atomic_try_cmpxchg_acquire \n" " cmpw 0,%0,%3 \n" " bne- 2f \n" " stwcx. %4,0,%2 \n" @@ -150,7 +151,7 @@ arch_atomic_try_cmpxchg_lock(atomic_t *v, int *old, int new) "\t" PPC_ACQUIRE_BARRIER " \n" "2: \n" : "=&r" (r), "+m" (v->counter) - : "r" (&v->counter), "r" (o), "r" (new), "i" (IS_ENABLED(CONFIG_PPC64) ? 1 : 0) + : "r" (&v->counter), "r" (o), "r" (new), [eh] "n" (eh) : "cr0", "memory"); if (unlikely(r != o)) diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index 344fba3b16eb..7e0f0322912b 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h @@ -163,7 +163,7 @@ static inline unsigned long fn( \ "bne- 1b\n" \ postfix \ : "=&r" (old), "=&r" (t) \ - : "rK" (mask), "r" (p), "i" (IS_ENABLED(CONFIG_PPC64) ? eh : 0) \ + : "rK" (mask), "r" (p), "n" (eh) \ : "cc", "memory"); \ return (old & mask); \ } @@ -171,7 +171,7 @@ static inline unsigned long fn( \ DEFINE_TESTOP(test_and_set_bits, or, PPC_ATOMIC_ENTRY_BARRIER, PPC_ATOMIC_EXIT_BARRIER, 0) DEFINE_TESTOP(test_and_set_bits_lock, or, "", - PPC_ACQUIRE_BARRIER, 1) + PPC_ACQUIRE_BARRIER, IS_ENABLED(CONFIG_PPC64)) DEFINE_TESTOP(test_and_change_bits, xor, PPC_ATOMIC_ENTRY_BARRIER, PPC_ATOMIC_EXIT_BARRIER, 0) diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 7b81b37a191e..c6d724104ed1 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -343,6 +343,7 @@ #define __PPC_SPR(r) ((((r) & 0x1f) << 16) | ((((r) >> 5) & 0x1f) << 11)) #define __PPC_RC21 (0x1 << 10) #define __PPC_PRFX_R(r) (((r) & 0x1) << 20) +#define __PPC_EH(eh) (((eh) & 0x1) << 0) /* * Both low and high 16 bits are added as SIGNED additions, so if low 16 bits @@ -359,16 +360,6 @@ #define PPC_LI_MASK 0x03fffffc #define PPC_LI(v) ((v) & PPC_LI_MASK) -/* - * Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a - * larx with EH set as an illegal instruction. - */ -#ifdef CONFIG_PPC64 -#define __PPC_EH(eh) (((eh) & 0x1) << 0) -#else -#define __PPC_EH(eh) 0 -#endif - /* Base instruction encoding */ #define PPC_RAW_CP_ABORT (0x7c00068c) #define PPC_RAW_COPY(a, b) (PPC_INST_COPY | ___PPC_RA(a) | ___PPC_RB(b)) @@ -580,7 +571,7 @@ #define PPC_RAW_BRANCH(offset) (0x48000000 | PPC_LI(offset)) #define PPC_RAW_BL(offset) (0x48000001 | PPC_LI(offset)) -#define PPC_RAW_TW(t0, a, b) (0x7f000008 | ___PPC_RS(t0) | ___PPC_RA(a) | ___PPC_RB(b)) +#define PPC_RAW_TW(t0, a, b) (0x7c000008 | ___PPC_RS(t0) | ___PPC_RA(a) | ___PPC_RB(b)) #define PPC_RAW_TRAP() PPC_RAW_TW(31, 0, 0) #define PPC_RAW_SETB(t, bfa) (0x7c000100 | ___PPC_RT(t) | ___PPC_RA((bfa) << 2)) diff --git a/arch/powerpc/include/asm/simple_spinlock.h b/arch/powerpc/include/asm/simple_spinlock.h index 7ae6aeef8464..9dcc7e9993b9 100644 --- a/arch/powerpc/include/asm/simple_spinlock.h +++ b/arch/powerpc/include/asm/simple_spinlock.h @@ -48,10 +48,11 @@ static inline int arch_spin_is_locked(arch_spinlock_t *lock) static inline unsigned long __arch_spin_trylock(arch_spinlock_t *lock) { unsigned long tmp, token; + unsigned int eh = IS_ENABLED(CONFIG_PPC64); token = LOCK_TOKEN; __asm__ __volatile__( -"1: lwarx %0,0,%2,1\n\ +"1: lwarx %0,0,%2,%[eh]\n\ cmpwi 0,%0,0\n\ bne- 2f\n\ stwcx. %1,0,%2\n\ @@ -59,7 +60,7 @@ static inline unsigned long __arch_spin_trylock(arch_spinlock_t *lock) PPC_ACQUIRE_BARRIER "2:" : "=&r" (tmp) - : "r" (token), "r" (&lock->slock) + : "r" (token), "r" (&lock->slock), [eh] "n" (eh) : "cr0", "memory"); return tmp; @@ -156,9 +157,10 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) static inline long __arch_read_trylock(arch_rwlock_t *rw) { long tmp; + unsigned int eh = IS_ENABLED(CONFIG_PPC64); __asm__ __volatile__( -"1: lwarx %0,0,%1,1\n" +"1: lwarx %0,0,%1,%[eh]\n" __DO_SIGN_EXTEND " addic. %0,%0,1\n\ ble- 2f\n" @@ -166,7 +168,7 @@ static inline long __arch_read_trylock(arch_rwlock_t *rw) bne- 1b\n" PPC_ACQUIRE_BARRIER "2:" : "=&r" (tmp) - : "r" (&rw->lock) + : "r" (&rw->lock), [eh] "n" (eh) : "cr0", "xer", "memory"); return tmp; @@ -179,17 +181,18 @@ static inline long __arch_read_trylock(arch_rwlock_t *rw) static inline long __arch_write_trylock(arch_rwlock_t *rw) { long tmp, token; + unsigned int eh = IS_ENABLED(CONFIG_PPC64); token = WRLOCK_TOKEN; __asm__ __volatile__( -"1: lwarx %0,0,%2,1\n\ +"1: lwarx %0,0,%2,%[eh]\n\ cmpwi 0,%0,0\n\ bne- 2f\n" " stwcx. %1,0,%2\n\ bne- 1b\n" PPC_ACQUIRE_BARRIER "2:" : "=&r" (tmp) - : "r" (token), "r" (&rw->lock) + : "r" (token), "r" (&rw->lock), [eh] "n" (eh) : "cr0", "memory"); return tmp; diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index cb158c32b50b..7b85c3b460a3 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -393,11 +393,11 @@ int ftrace_make_nop(struct module *mod, */ static bool expected_nop_sequence(void *ip, ppc_inst_t op0, ppc_inst_t op1) { - if (IS_ENABLED(CONFIG_PPC64_ELF_ABI_V1)) + if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS)) + return ppc_inst_equal(op0, ppc_inst(PPC_RAW_NOP())); + else return ppc_inst_equal(op0, ppc_inst(PPC_RAW_BRANCH(8))) && ppc_inst_equal(op1, ppc_inst(PPC_INST_LD_TOC)); - else - return ppc_inst_equal(op0, ppc_inst(PPC_RAW_NOP())); } static int @@ -412,7 +412,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) if (copy_inst_from_kernel_nofault(op, ip)) return -EFAULT; - if (IS_ENABLED(CONFIG_PPC64_ELF_ABI_V1) && + if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS) && copy_inst_from_kernel_nofault(op + 1, ip + 4)) return -EFAULT; diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c index 683462e4556b..349a781cea0b 100644 --- a/arch/powerpc/kexec/file_load_64.c +++ b/arch/powerpc/kexec/file_load_64.c @@ -1043,17 +1043,17 @@ static int copy_property(void *fdt, int node_offset, const struct device_node *d const char *propname) { const void *prop, *fdtprop; - int len = 0, fdtlen = 0, ret; + int len = 0, fdtlen = 0; prop = of_get_property(dn, propname, &len); fdtprop = fdt_getprop(fdt, node_offset, propname, &fdtlen); if (fdtprop && !prop) - ret = fdt_delprop(fdt, node_offset, propname); + return fdt_delprop(fdt, node_offset, propname); else if (prop) - ret = fdt_setprop(fdt, node_offset, propname, prop, len); - - return ret; + return fdt_setprop(fdt, node_offset, propname, prop, len); + else + return -FDT_ERR_NOTFOUND; } static int update_pci_dma_nodes(void *fdt, const char *dmapropname) |