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
This commit is contained in:
@@ -140,9 +140,10 @@ static __always_inline bool
|
|||||||
arch_atomic_try_cmpxchg_lock(atomic_t *v, int *old, int new)
|
arch_atomic_try_cmpxchg_lock(atomic_t *v, int *old, int new)
|
||||||
{
|
{
|
||||||
int r, o = *old;
|
int r, o = *old;
|
||||||
|
unsigned int eh = IS_ENABLED(CONFIG_PPC64);
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
__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"
|
" cmpw 0,%0,%3 \n"
|
||||||
" bne- 2f \n"
|
" bne- 2f \n"
|
||||||
" stwcx. %4,0,%2 \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"
|
"\t" PPC_ACQUIRE_BARRIER " \n"
|
||||||
"2: \n"
|
"2: \n"
|
||||||
: "=&r" (r), "+m" (v->counter)
|
: "=&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");
|
: "cr0", "memory");
|
||||||
|
|
||||||
if (unlikely(r != o))
|
if (unlikely(r != o))
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ static inline unsigned long fn( \
|
|||||||
"bne- 1b\n" \
|
"bne- 1b\n" \
|
||||||
postfix \
|
postfix \
|
||||||
: "=&r" (old), "=&r" (t) \
|
: "=&r" (old), "=&r" (t) \
|
||||||
: "rK" (mask), "r" (p), "i" (IS_ENABLED(CONFIG_PPC64) ? eh : 0) \
|
: "rK" (mask), "r" (p), "n" (eh) \
|
||||||
: "cc", "memory"); \
|
: "cc", "memory"); \
|
||||||
return (old & mask); \
|
return (old & mask); \
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ static inline unsigned long fn( \
|
|||||||
DEFINE_TESTOP(test_and_set_bits, or, PPC_ATOMIC_ENTRY_BARRIER,
|
DEFINE_TESTOP(test_and_set_bits, or, PPC_ATOMIC_ENTRY_BARRIER,
|
||||||
PPC_ATOMIC_EXIT_BARRIER, 0)
|
PPC_ATOMIC_EXIT_BARRIER, 0)
|
||||||
DEFINE_TESTOP(test_and_set_bits_lock, or, "",
|
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,
|
DEFINE_TESTOP(test_and_change_bits, xor, PPC_ATOMIC_ENTRY_BARRIER,
|
||||||
PPC_ATOMIC_EXIT_BARRIER, 0)
|
PPC_ATOMIC_EXIT_BARRIER, 0)
|
||||||
|
|
||||||
|
|||||||
@@ -343,6 +343,7 @@
|
|||||||
#define __PPC_SPR(r) ((((r) & 0x1f) << 16) | ((((r) >> 5) & 0x1f) << 11))
|
#define __PPC_SPR(r) ((((r) & 0x1f) << 16) | ((((r) >> 5) & 0x1f) << 11))
|
||||||
#define __PPC_RC21 (0x1 << 10)
|
#define __PPC_RC21 (0x1 << 10)
|
||||||
#define __PPC_PRFX_R(r) (((r) & 0x1) << 20)
|
#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
|
* 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_MASK 0x03fffffc
|
||||||
#define PPC_LI(v) ((v) & PPC_LI_MASK)
|
#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 */
|
/* Base instruction encoding */
|
||||||
#define PPC_RAW_CP_ABORT (0x7c00068c)
|
#define PPC_RAW_CP_ABORT (0x7c00068c)
|
||||||
#define PPC_RAW_COPY(a, b) (PPC_INST_COPY | ___PPC_RA(a) | ___PPC_RB(b))
|
#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_BRANCH(offset) (0x48000000 | PPC_LI(offset))
|
||||||
#define PPC_RAW_BL(offset) (0x48000001 | 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_TRAP() PPC_RAW_TW(31, 0, 0)
|
||||||
#define PPC_RAW_SETB(t, bfa) (0x7c000100 | ___PPC_RT(t) | ___PPC_RA((bfa) << 2))
|
#define PPC_RAW_SETB(t, bfa) (0x7c000100 | ___PPC_RT(t) | ___PPC_RA((bfa) << 2))
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
static inline unsigned long __arch_spin_trylock(arch_spinlock_t *lock)
|
||||||
{
|
{
|
||||||
unsigned long tmp, token;
|
unsigned long tmp, token;
|
||||||
|
unsigned int eh = IS_ENABLED(CONFIG_PPC64);
|
||||||
|
|
||||||
token = LOCK_TOKEN;
|
token = LOCK_TOKEN;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"1: lwarx %0,0,%2,1\n\
|
"1: lwarx %0,0,%2,%[eh]\n\
|
||||||
cmpwi 0,%0,0\n\
|
cmpwi 0,%0,0\n\
|
||||||
bne- 2f\n\
|
bne- 2f\n\
|
||||||
stwcx. %1,0,%2\n\
|
stwcx. %1,0,%2\n\
|
||||||
@@ -59,7 +60,7 @@ static inline unsigned long __arch_spin_trylock(arch_spinlock_t *lock)
|
|||||||
PPC_ACQUIRE_BARRIER
|
PPC_ACQUIRE_BARRIER
|
||||||
"2:"
|
"2:"
|
||||||
: "=&r" (tmp)
|
: "=&r" (tmp)
|
||||||
: "r" (token), "r" (&lock->slock)
|
: "r" (token), "r" (&lock->slock), [eh] "n" (eh)
|
||||||
: "cr0", "memory");
|
: "cr0", "memory");
|
||||||
|
|
||||||
return tmp;
|
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)
|
static inline long __arch_read_trylock(arch_rwlock_t *rw)
|
||||||
{
|
{
|
||||||
long tmp;
|
long tmp;
|
||||||
|
unsigned int eh = IS_ENABLED(CONFIG_PPC64);
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"1: lwarx %0,0,%1,1\n"
|
"1: lwarx %0,0,%1,%[eh]\n"
|
||||||
__DO_SIGN_EXTEND
|
__DO_SIGN_EXTEND
|
||||||
" addic. %0,%0,1\n\
|
" addic. %0,%0,1\n\
|
||||||
ble- 2f\n"
|
ble- 2f\n"
|
||||||
@@ -166,7 +168,7 @@ static inline long __arch_read_trylock(arch_rwlock_t *rw)
|
|||||||
bne- 1b\n"
|
bne- 1b\n"
|
||||||
PPC_ACQUIRE_BARRIER
|
PPC_ACQUIRE_BARRIER
|
||||||
"2:" : "=&r" (tmp)
|
"2:" : "=&r" (tmp)
|
||||||
: "r" (&rw->lock)
|
: "r" (&rw->lock), [eh] "n" (eh)
|
||||||
: "cr0", "xer", "memory");
|
: "cr0", "xer", "memory");
|
||||||
|
|
||||||
return tmp;
|
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)
|
static inline long __arch_write_trylock(arch_rwlock_t *rw)
|
||||||
{
|
{
|
||||||
long tmp, token;
|
long tmp, token;
|
||||||
|
unsigned int eh = IS_ENABLED(CONFIG_PPC64);
|
||||||
|
|
||||||
token = WRLOCK_TOKEN;
|
token = WRLOCK_TOKEN;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"1: lwarx %0,0,%2,1\n\
|
"1: lwarx %0,0,%2,%[eh]\n\
|
||||||
cmpwi 0,%0,0\n\
|
cmpwi 0,%0,0\n\
|
||||||
bne- 2f\n"
|
bne- 2f\n"
|
||||||
" stwcx. %1,0,%2\n\
|
" stwcx. %1,0,%2\n\
|
||||||
bne- 1b\n"
|
bne- 1b\n"
|
||||||
PPC_ACQUIRE_BARRIER
|
PPC_ACQUIRE_BARRIER
|
||||||
"2:" : "=&r" (tmp)
|
"2:" : "=&r" (tmp)
|
||||||
: "r" (token), "r" (&rw->lock)
|
: "r" (token), "r" (&rw->lock), [eh] "n" (eh)
|
||||||
: "cr0", "memory");
|
: "cr0", "memory");
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|||||||
@@ -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)
|
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))) &&
|
return ppc_inst_equal(op0, ppc_inst(PPC_RAW_BRANCH(8))) &&
|
||||||
ppc_inst_equal(op1, ppc_inst(PPC_INST_LD_TOC));
|
ppc_inst_equal(op1, ppc_inst(PPC_INST_LD_TOC));
|
||||||
else
|
|
||||||
return ppc_inst_equal(op0, ppc_inst(PPC_RAW_NOP()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -412,7 +412,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
|||||||
if (copy_inst_from_kernel_nofault(op, ip))
|
if (copy_inst_from_kernel_nofault(op, ip))
|
||||||
return -EFAULT;
|
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))
|
copy_inst_from_kernel_nofault(op + 1, ip + 4))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
|||||||
@@ -1043,17 +1043,17 @@ static int copy_property(void *fdt, int node_offset, const struct device_node *d
|
|||||||
const char *propname)
|
const char *propname)
|
||||||
{
|
{
|
||||||
const void *prop, *fdtprop;
|
const void *prop, *fdtprop;
|
||||||
int len = 0, fdtlen = 0, ret;
|
int len = 0, fdtlen = 0;
|
||||||
|
|
||||||
prop = of_get_property(dn, propname, &len);
|
prop = of_get_property(dn, propname, &len);
|
||||||
fdtprop = fdt_getprop(fdt, node_offset, propname, &fdtlen);
|
fdtprop = fdt_getprop(fdt, node_offset, propname, &fdtlen);
|
||||||
|
|
||||||
if (fdtprop && !prop)
|
if (fdtprop && !prop)
|
||||||
ret = fdt_delprop(fdt, node_offset, propname);
|
return fdt_delprop(fdt, node_offset, propname);
|
||||||
else if (prop)
|
else if (prop)
|
||||||
ret = fdt_setprop(fdt, node_offset, propname, prop, len);
|
return fdt_setprop(fdt, node_offset, propname, prop, len);
|
||||||
|
else
|
||||||
return ret;
|
return -FDT_ERR_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int update_pci_dma_nodes(void *fdt, const char *dmapropname)
|
static int update_pci_dma_nodes(void *fdt, const char *dmapropname)
|
||||||
|
|||||||
Reference in New Issue
Block a user