Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+102 -29
+37 -8
arch/arm64/include/asm/kgdb.h
··· 38 38 #endif /* !__ASSEMBLY__ */ 39 39 40 40 /* 41 - * gdb is expecting the following registers layout. 41 + * gdb remote procotol (well most versions of it) expects the following 42 + * register layout. 42 43 * 43 44 * General purpose regs: 44 45 * r0-r30: 64 bit 45 46 * sp,pc : 64 bit 46 - * pstate : 64 bit 47 - * Total: 34 47 + * pstate : 32 bit 48 + * Total: 33 + 1 48 49 * FPU regs: 49 50 * f0-f31: 128 bit 50 - * Total: 32 51 - * Extra regs 52 51 * fpsr & fpcr: 32 bit 53 - * Total: 2 52 + * Total: 32 + 2 54 53 * 54 + * To expand a little on the "most versions of it"... when the gdb remote 55 + * protocol for AArch64 was developed it depended on a statement in the 56 + * Architecture Reference Manual that claimed "SPSR_ELx is a 32-bit register". 57 + * and, as a result, allocated only 32-bits for the PSTATE in the remote 58 + * protocol. In fact this statement is still present in ARM DDI 0487A.i. 59 + * 60 + * Unfortunately "is a 32-bit register" has a very special meaning for 61 + * system registers. It means that "the upper bits, bits[63:32], are 62 + * RES0.". RES0 is heavily used in the ARM architecture documents as a 63 + * way to leave space for future architecture changes. So to translate a 64 + * little for people who don't spend their spare time reading ARM architecture 65 + * manuals, what "is a 32-bit register" actually means in this context is 66 + * "is a 64-bit register but one with no meaning allocated to any of the 67 + * upper 32-bits... *yet*". 68 + * 69 + * Perhaps then we should not be surprised that this has led to some 70 + * confusion. Specifically a patch, influenced by the above translation, 71 + * that extended PSTATE to 64-bit was accepted into gdb-7.7 but the patch 72 + * was reverted in gdb-7.8.1 and all later releases, when this was 73 + * discovered to be an undocumented protocol change. 74 + * 75 + * So... it is *not* wrong for us to only allocate 32-bits to PSTATE 76 + * here even though the kernel itself allocates 64-bits for the same 77 + * state. That is because this bit of code tells the kernel how the gdb 78 + * remote protocol (well most versions of it) describes the register state. 79 + * 80 + * Note that if you are using one of the versions of gdb that supports 81 + * the gdb-7.7 version of the protocol you cannot use kgdb directly 82 + * without providing a custom register description (gdb can load new 83 + * protocol descriptions at runtime). 55 84 */ 56 85 57 - #define _GP_REGS 34 86 + #define _GP_REGS 33 58 87 #define _FP_REGS 32 59 - #define _EXTRA_REGS 2 88 + #define _EXTRA_REGS 3 60 89 /* 61 90 * general purpose registers size in bytes. 62 91 * pstate is only 4 bytes. subtract 4 bytes
+37 -5
arch/arm64/include/asm/spinlock.h
··· 30 30 { 31 31 unsigned int tmp; 32 32 arch_spinlock_t lockval; 33 + u32 owner; 34 + 35 + /* 36 + * Ensure prior spin_lock operations to other locks have completed 37 + * on this CPU before we test whether "lock" is locked. 38 + */ 39 + smp_mb(); 40 + owner = READ_ONCE(lock->owner) << 16; 33 41 34 42 asm volatile( 35 43 " sevl\n" 36 44 "1: wfe\n" 37 45 "2: ldaxr %w0, %2\n" 46 + /* Is the lock free? */ 38 47 " eor %w1, %w0, %w0, ror #16\n" 39 - " cbnz %w1, 1b\n" 48 + " cbz %w1, 3f\n" 49 + /* Lock taken -- has there been a subsequent unlock->lock transition? */ 50 + " eor %w1, %w3, %w0, lsl #16\n" 51 + " cbz %w1, 1b\n" 52 + /* 53 + * The owner has been updated, so there was an unlock->lock 54 + * transition that we missed. That means we can rely on the 55 + * store-release of the unlock operation paired with the 56 + * load-acquire of the lock operation to publish any of our 57 + * previous stores to the new lock owner and therefore don't 58 + * need to bother with the writeback below. 59 + */ 60 + " b 4f\n" 61 + "3:\n" 62 + /* 63 + * Serialise against any concurrent lockers by writing back the 64 + * unlocked lock value 65 + */ 40 66 ARM64_LSE_ATOMIC_INSN( 41 67 /* LL/SC */ 42 68 " stxr %w1, %w0, %2\n" 43 - " cbnz %w1, 2b\n", /* Serialise against any concurrent lockers */ 44 - /* LSE atomics */ 45 69 " nop\n" 46 - " nop\n") 70 + " nop\n", 71 + /* LSE atomics */ 72 + " mov %w1, %w0\n" 73 + " cas %w0, %w0, %2\n" 74 + " eor %w1, %w1, %w0\n") 75 + /* Somebody else wrote to the lock, GOTO 10 and reload the value */ 76 + " cbnz %w1, 2b\n" 77 + "4:" 47 78 : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock) 48 - : 79 + : "r" (owner) 49 80 : "memory"); 50 81 } 51 82 ··· 179 148 180 149 static inline int arch_spin_is_locked(arch_spinlock_t *lock) 181 150 { 151 + smp_mb(); /* See arch_spin_unlock_wait */ 182 152 return !arch_spin_value_unlocked(READ_ONCE(*lock)); 183 153 } 184 154
+13 -1
arch/arm64/kernel/kgdb.c
··· 58 58 { "x30", 8, offsetof(struct pt_regs, regs[30])}, 59 59 { "sp", 8, offsetof(struct pt_regs, sp)}, 60 60 { "pc", 8, offsetof(struct pt_regs, pc)}, 61 - { "pstate", 8, offsetof(struct pt_regs, pstate)}, 61 + /* 62 + * struct pt_regs thinks PSTATE is 64-bits wide but gdb remote 63 + * protocol disagrees. Therefore we must extract only the lower 64 + * 32-bits. Look for the big comment in asm/kgdb.h for more 65 + * detail. 66 + */ 67 + { "pstate", 4, offsetof(struct pt_regs, pstate) 68 + #ifdef CONFIG_CPU_BIG_ENDIAN 69 + + 4 70 + #endif 71 + }, 62 72 { "v0", 16, -1 }, 63 73 { "v1", 16, -1 }, 64 74 { "v2", 16, -1 }, ··· 138 128 memset((char *)gdb_regs, 0, NUMREGBYTES); 139 129 thread_regs = task_pt_regs(task); 140 130 memcpy((void *)gdb_regs, (void *)thread_regs->regs, GP_REG_BYTES); 131 + /* Special case for PSTATE (check comments in asm/kgdb.h for details) */ 132 + dbg_get_reg(33, gdb_regs + GP_REG_BYTES, thread_regs); 141 133 } 142 134 143 135 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+13 -13
arch/arm64/kernel/traps.c
··· 64 64 65 65 /* 66 66 * We need to switch to kernel mode so that we can use __get_user 67 - * to safely read from kernel space. Note that we now dump the 68 - * code first, just in case the backtrace kills us. 67 + * to safely read from kernel space. 69 68 */ 70 69 fs = get_fs(); 71 70 set_fs(KERNEL_DS); ··· 110 111 print_ip_sym(where); 111 112 } 112 113 113 - static void dump_instr(const char *lvl, struct pt_regs *regs) 114 + static void __dump_instr(const char *lvl, struct pt_regs *regs) 114 115 { 115 116 unsigned long addr = instruction_pointer(regs); 116 - mm_segment_t fs; 117 117 char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; 118 118 int i; 119 - 120 - /* 121 - * We need to switch to kernel mode so that we can use __get_user 122 - * to safely read from kernel space. Note that we now dump the 123 - * code first, just in case the backtrace kills us. 124 - */ 125 - fs = get_fs(); 126 - set_fs(KERNEL_DS); 127 119 128 120 for (i = -4; i < 1; i++) { 129 121 unsigned int val, bad; ··· 129 139 } 130 140 } 131 141 printk("%sCode: %s\n", lvl, str); 142 + } 132 143 133 - set_fs(fs); 144 + static void dump_instr(const char *lvl, struct pt_regs *regs) 145 + { 146 + if (!user_mode(regs)) { 147 + mm_segment_t fs = get_fs(); 148 + set_fs(KERNEL_DS); 149 + __dump_instr(lvl, regs); 150 + set_fs(fs); 151 + } else { 152 + __dump_instr(lvl, regs); 153 + } 134 154 } 135 155 136 156 static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+1 -1
arch/arm64/mm/fault.c
··· 441 441 return 1; 442 442 } 443 443 444 - static struct fault_info { 444 + static const struct fault_info { 445 445 int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs); 446 446 int sig; 447 447 int code;
+1 -1
drivers/perf/arm_pmu.c
··· 1010 1010 if (!ret) 1011 1011 ret = init_fn(pmu); 1012 1012 } else { 1013 - ret = probe_current_pmu(pmu, probe_table); 1014 1013 cpumask_setall(&pmu->supported_cpus); 1014 + ret = probe_current_pmu(pmu, probe_table); 1015 1015 } 1016 1016 1017 1017 if (ret) {