Commit 9cbbef4e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:
 "The main things are getting kgdb up and running with upstream GDB
  after a protocol change was reverted and fixing our spin_unlock_wait
  and spin_is_locked implementations after doing some similar work with
  PeterZ on the qspinlock code last week.  Whilst we haven't seen any
  failures in practice, it's still worth getting this fixed.

  Summary:

   - Plug the ongoing spin_unlock_wait/spin_is_locked mess
   - KGDB protocol fix to sync w/ GDB
   - Fix MIDR-based PMU probing for old 32-bit SMP systems
     (OMAP4/Realview)
   - Minor tweaks to the fault handling path"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64: kgdb: Match pstate size with gdbserver protocol
  arm64: spinlock: Ensure forward-progress in spin_unlock_wait
  arm64: spinlock: fix spin_unlock_wait for LSE atomics
  arm64: spinlock: order spin_{is_locked,unlock_wait} against local locks
  arm: pmu: Fix non-devicetree probing
  arm64: mm: mark fault_info table const
  arm64: fix dump_instr when PAN and UAO are in use
parents 8c256155 0d15ef67
...@@ -38,25 +38,54 @@ extern int kgdb_fault_expected; ...@@ -38,25 +38,54 @@ extern int kgdb_fault_expected;
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
/* /*
* gdb is expecting the following registers layout. * gdb remote procotol (well most versions of it) expects the following
* register layout.
* *
* General purpose regs: * General purpose regs:
* r0-r30: 64 bit * r0-r30: 64 bit
* sp,pc : 64 bit * sp,pc : 64 bit
* pstate : 64 bit * pstate : 32 bit
* Total: 34 * Total: 33 + 1
* FPU regs: * FPU regs:
* f0-f31: 128 bit * f0-f31: 128 bit
* Total: 32
* Extra regs
* fpsr & fpcr: 32 bit * fpsr & fpcr: 32 bit
* Total: 2 * Total: 32 + 2
* *
* To expand a little on the "most versions of it"... when the gdb remote
* protocol for AArch64 was developed it depended on a statement in the
* Architecture Reference Manual that claimed "SPSR_ELx is a 32-bit register".
* and, as a result, allocated only 32-bits for the PSTATE in the remote
* protocol. In fact this statement is still present in ARM DDI 0487A.i.
*
* Unfortunately "is a 32-bit register" has a very special meaning for
* system registers. It means that "the upper bits, bits[63:32], are
* RES0.". RES0 is heavily used in the ARM architecture documents as a
* way to leave space for future architecture changes. So to translate a
* little for people who don't spend their spare time reading ARM architecture
* manuals, what "is a 32-bit register" actually means in this context is
* "is a 64-bit register but one with no meaning allocated to any of the
* upper 32-bits... *yet*".
*
* Perhaps then we should not be surprised that this has led to some
* confusion. Specifically a patch, influenced by the above translation,
* that extended PSTATE to 64-bit was accepted into gdb-7.7 but the patch
* was reverted in gdb-7.8.1 and all later releases, when this was
* discovered to be an undocumented protocol change.
*
* So... it is *not* wrong for us to only allocate 32-bits to PSTATE
* here even though the kernel itself allocates 64-bits for the same
* state. That is because this bit of code tells the kernel how the gdb
* remote protocol (well most versions of it) describes the register state.
*
* Note that if you are using one of the versions of gdb that supports
* the gdb-7.7 version of the protocol you cannot use kgdb directly
* without providing a custom register description (gdb can load new
* protocol descriptions at runtime).
*/ */
#define _GP_REGS 34 #define _GP_REGS 33
#define _FP_REGS 32 #define _FP_REGS 32
#define _EXTRA_REGS 2 #define _EXTRA_REGS 3
/* /*
* general purpose registers size in bytes. * general purpose registers size in bytes.
* pstate is only 4 bytes. subtract 4 bytes * pstate is only 4 bytes. subtract 4 bytes
......
...@@ -30,22 +30,53 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) ...@@ -30,22 +30,53 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
{ {
unsigned int tmp; unsigned int tmp;
arch_spinlock_t lockval; arch_spinlock_t lockval;
u32 owner;
/*
* Ensure prior spin_lock operations to other locks have completed
* on this CPU before we test whether "lock" is locked.
*/
smp_mb();
owner = READ_ONCE(lock->owner) << 16;
asm volatile( asm volatile(
" sevl\n" " sevl\n"
"1: wfe\n" "1: wfe\n"
"2: ldaxr %w0, %2\n" "2: ldaxr %w0, %2\n"
/* Is the lock free? */
" eor %w1, %w0, %w0, ror #16\n" " eor %w1, %w0, %w0, ror #16\n"
" cbnz %w1, 1b\n" " cbz %w1, 3f\n"
/* Lock taken -- has there been a subsequent unlock->lock transition? */
" eor %w1, %w3, %w0, lsl #16\n"
" cbz %w1, 1b\n"
/*
* The owner has been updated, so there was an unlock->lock
* transition that we missed. That means we can rely on the
* store-release of the unlock operation paired with the
* load-acquire of the lock operation to publish any of our
* previous stores to the new lock owner and therefore don't
* need to bother with the writeback below.
*/
" b 4f\n"
"3:\n"
/*
* Serialise against any concurrent lockers by writing back the
* unlocked lock value
*/
ARM64_LSE_ATOMIC_INSN( ARM64_LSE_ATOMIC_INSN(
/* LL/SC */ /* LL/SC */
" stxr %w1, %w0, %2\n" " stxr %w1, %w0, %2\n"
" cbnz %w1, 2b\n", /* Serialise against any concurrent lockers */
/* LSE atomics */
" nop\n" " nop\n"
" nop\n") " nop\n",
/* LSE atomics */
" mov %w1, %w0\n"
" cas %w0, %w0, %2\n"
" eor %w1, %w1, %w0\n")
/* Somebody else wrote to the lock, GOTO 10 and reload the value */
" cbnz %w1, 2b\n"
"4:"
: "=&r" (lockval), "=&r" (tmp), "+Q" (*lock) : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock)
: : "r" (owner)
: "memory"); : "memory");
} }
...@@ -148,6 +179,7 @@ static inline int arch_spin_value_unlocked(arch_spinlock_t lock) ...@@ -148,6 +179,7 @@ static inline int arch_spin_value_unlocked(arch_spinlock_t lock)
static inline int arch_spin_is_locked(arch_spinlock_t *lock) static inline int arch_spin_is_locked(arch_spinlock_t *lock)
{ {
smp_mb(); /* See arch_spin_unlock_wait */
return !arch_spin_value_unlocked(READ_ONCE(*lock)); return !arch_spin_value_unlocked(READ_ONCE(*lock));
} }
......
...@@ -58,7 +58,17 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { ...@@ -58,7 +58,17 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
{ "x30", 8, offsetof(struct pt_regs, regs[30])}, { "x30", 8, offsetof(struct pt_regs, regs[30])},
{ "sp", 8, offsetof(struct pt_regs, sp)}, { "sp", 8, offsetof(struct pt_regs, sp)},
{ "pc", 8, offsetof(struct pt_regs, pc)}, { "pc", 8, offsetof(struct pt_regs, pc)},
{ "pstate", 8, offsetof(struct pt_regs, pstate)}, /*
* struct pt_regs thinks PSTATE is 64-bits wide but gdb remote
* protocol disagrees. Therefore we must extract only the lower
* 32-bits. Look for the big comment in asm/kgdb.h for more
* detail.
*/
{ "pstate", 4, offsetof(struct pt_regs, pstate)
#ifdef CONFIG_CPU_BIG_ENDIAN
+ 4
#endif
},
{ "v0", 16, -1 }, { "v0", 16, -1 },
{ "v1", 16, -1 }, { "v1", 16, -1 },
{ "v2", 16, -1 }, { "v2", 16, -1 },
...@@ -128,6 +138,8 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) ...@@ -128,6 +138,8 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
memset((char *)gdb_regs, 0, NUMREGBYTES); memset((char *)gdb_regs, 0, NUMREGBYTES);
thread_regs = task_pt_regs(task); thread_regs = task_pt_regs(task);
memcpy((void *)gdb_regs, (void *)thread_regs->regs, GP_REG_BYTES); memcpy((void *)gdb_regs, (void *)thread_regs->regs, GP_REG_BYTES);
/* Special case for PSTATE (check comments in asm/kgdb.h for details) */
dbg_get_reg(33, gdb_regs + GP_REG_BYTES, thread_regs);
} }
void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
......
...@@ -64,8 +64,7 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, ...@@ -64,8 +64,7 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
/* /*
* We need to switch to kernel mode so that we can use __get_user * We need to switch to kernel mode so that we can use __get_user
* to safely read from kernel space. Note that we now dump the * to safely read from kernel space.
* code first, just in case the backtrace kills us.
*/ */
fs = get_fs(); fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
...@@ -111,21 +110,12 @@ static void dump_backtrace_entry(unsigned long where) ...@@ -111,21 +110,12 @@ static void dump_backtrace_entry(unsigned long where)
print_ip_sym(where); print_ip_sym(where);
} }
static void dump_instr(const char *lvl, struct pt_regs *regs) static void __dump_instr(const char *lvl, struct pt_regs *regs)
{ {
unsigned long addr = instruction_pointer(regs); unsigned long addr = instruction_pointer(regs);
mm_segment_t fs;
char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
int i; int i;
/*
* We need to switch to kernel mode so that we can use __get_user
* to safely read from kernel space. Note that we now dump the
* code first, just in case the backtrace kills us.
*/
fs = get_fs();
set_fs(KERNEL_DS);
for (i = -4; i < 1; i++) { for (i = -4; i < 1; i++) {
unsigned int val, bad; unsigned int val, bad;
...@@ -139,8 +129,18 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) ...@@ -139,8 +129,18 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
} }
} }
printk("%sCode: %s\n", lvl, str); printk("%sCode: %s\n", lvl, str);
}
static void dump_instr(const char *lvl, struct pt_regs *regs)
{
if (!user_mode(regs)) {
mm_segment_t fs = get_fs();
set_fs(KERNEL_DS);
__dump_instr(lvl, regs);
set_fs(fs); set_fs(fs);
} else {
__dump_instr(lvl, regs);
}
} }
static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
......
...@@ -441,7 +441,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs) ...@@ -441,7 +441,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
return 1; return 1;
} }
static struct fault_info { static const struct fault_info {
int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs); int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs);
int sig; int sig;
int code; int code;
......
...@@ -1010,8 +1010,8 @@ int arm_pmu_device_probe(struct platform_device *pdev, ...@@ -1010,8 +1010,8 @@ int arm_pmu_device_probe(struct platform_device *pdev,
if (!ret) if (!ret)
ret = init_fn(pmu); ret = init_fn(pmu);
} else { } else {
ret = probe_current_pmu(pmu, probe_table);
cpumask_setall(&pmu->supported_cpus); cpumask_setall(&pmu->supported_cpus);
ret = probe_current_pmu(pmu, probe_table);
} }
if (ret) { if (ret) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment