Skip to content

Commit

Permalink
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
Browse files Browse the repository at this point in the history
Pull ARM updates from Russell King:

 - amba bus updates

 - simplify ldr_this_cpu assembler macro for uniprocessor builds

 - avoid explicit assembler literal loads

 - more spectre-bhb improvements

 - add Cortex-A9 Errata 764319 workaround

 - add all unwind tables for modules

* tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm:
  ARM: 9204/2: module: Add all unwind tables when load module
  ARM: 9206/1: A9: Add ARM ERRATA 764319 workaround (Updated)
  ARM: 9201/1: spectre-bhb: rely on linker to emit cross-section literal loads
  ARM: 9200/1: spectre-bhb: avoid cross-subsection jump using a numbered label
  ARM: 9199/1: spectre-bhb: use local DSB and elide ISB in loop8 sequence
  ARM: 9198/1: spectre-bhb: simplify BPIALL vector macro
  ARM: 9195/1: entry: avoid explicit literal loads
  ARM: 9194/1: assembler: simplify ldr_this_cpu for !SMP builds
  ARM: 9192/1: amba: fix memory leak in amba_device_try_add()
  ARM: 9193/1: amba: Add amba_read_periphid() helper
  • Loading branch information
torvalds committed May 24, 2022
2 parents 95fbef1 + b6f21d1 commit d6edf95
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 199 deletions.
11 changes: 11 additions & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,17 @@ config ARM_ERRATA_764369
relevant cache maintenance functions and sets a specific bit
in the diagnostic control register of the SCU.

config ARM_ERRATA_764319
bool "ARM errata: Read to DBGPRSR and DBGOSLSR may generate Undefined instruction"
depends on CPU_V7
help
This option enables the workaround for the 764319 Cortex A-9 erratum.
CP14 read accesses to the DBGPRSR and DBGOSLSR registers generate an
unexpected Undefined Instruction exception when the DBGSWENABLE
external pin is set to 0, even when the CP14 accesses are performed
from a privileged mode. This work around catches the exception in a
way the kernel does not stop execution.

config ARM_ERRATA_775420
bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
depends on CPU_V7
Expand Down
28 changes: 17 additions & 11 deletions arch/arm/include/asm/assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -666,12 +666,11 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
__adldst_l str, \src, \sym, \tmp, \cond
.endm

.macro __ldst_va, op, reg, tmp, sym, cond
.macro __ldst_va, op, reg, tmp, sym, cond, offset
#if __LINUX_ARM_ARCH__ >= 7 || \
!defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
mov_l \tmp, \sym, \cond
\op\cond \reg, [\tmp]
#else
/*
* Avoid a literal load, by emitting a sequence of ADD/LDR instructions
Expand All @@ -683,24 +682,29 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
.reloc .L0_\@, R_ARM_ALU_PC_G0_NC, \sym
.reloc .L1_\@, R_ARM_ALU_PC_G1_NC, \sym
.reloc .L2_\@, R_ARM_LDR_PC_G2, \sym
.L0_\@: sub\cond \tmp, pc, #8
.L1_\@: sub\cond \tmp, \tmp, #4
.L2_\@: \op\cond \reg, [\tmp, #0]
.L0_\@: sub\cond \tmp, pc, #8 - \offset
.L1_\@: sub\cond \tmp, \tmp, #4 - \offset
.L2_\@:
#endif
\op\cond \reg, [\tmp, #\offset]
.endm

/*
* ldr_va - load a 32-bit word from the virtual address of \sym
*/
.macro ldr_va, rd:req, sym:req, cond
__ldst_va ldr, \rd, \rd, \sym, \cond
.macro ldr_va, rd:req, sym:req, cond, tmp, offset=0
.ifnb \tmp
__ldst_va ldr, \rd, \tmp, \sym, \cond, \offset
.else
__ldst_va ldr, \rd, \rd, \sym, \cond, \offset
.endif
.endm

/*
* str_va - store a 32-bit word to the virtual address of \sym
*/
.macro str_va, rn:req, sym:req, tmp:req, cond
__ldst_va str, \rn, \tmp, \sym, \cond
__ldst_va str, \rn, \tmp, \sym, \cond, 0
.endm

/*
Expand All @@ -727,9 +731,11 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
* are permitted to overlap with 'rd' if != sp
*/
.macro ldr_this_cpu, rd:req, sym:req, t1:req, t2:req
#if __LINUX_ARM_ARCH__ >= 7 || \
!defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
#ifndef CONFIG_SMP
ldr_va \rd, \sym, tmp=\t1
#elif __LINUX_ARM_ARCH__ >= 7 || \
!defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
this_cpu_offset \t1
mov_l \t2, \sym
ldr \rd, [\t1, \t2]
Expand Down
17 changes: 4 additions & 13 deletions arch/arm/include/asm/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,10 @@
#define _ASM_ARM_MODULE_H

#include <asm-generic/module.h>

struct unwind_table;
#include <asm/unwind.h>

#ifdef CONFIG_ARM_UNWIND
enum {
ARM_SEC_INIT,
ARM_SEC_DEVINIT,
ARM_SEC_CORE,
ARM_SEC_EXIT,
ARM_SEC_DEVEXIT,
ARM_SEC_HOT,
ARM_SEC_UNLIKELY,
ARM_SEC_MAX,
};
#define ELF_SECTION_UNWIND 0x70000001
#endif

#define PLT_ENT_STRIDE L1_CACHE_BYTES
Expand All @@ -36,7 +26,8 @@ struct mod_plt_sec {

struct mod_arch_specific {
#ifdef CONFIG_ARM_UNWIND
struct unwind_table *unwind[ARM_SEC_MAX];
struct list_head unwind_list;
struct unwind_table *init_table;
#endif
#ifdef CONFIG_ARM_MODULE_PLTS
struct mod_plt_sec core;
Expand Down
1 change: 1 addition & 0 deletions arch/arm/include/asm/unwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct unwind_idx {

struct unwind_table {
struct list_head list;
struct list_head mod_list;
const struct unwind_idx *start;
const struct unwind_idx *origin;
const struct unwind_idx *stop;
Expand Down
88 changes: 33 additions & 55 deletions arch/arm/kernel/entry-armv.S
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@
.macro pabt_helper
@ PABORT handler takes pt_regs in r2, fault address in r4 and psr in r5
#ifdef MULTI_PABORT
ldr ip, .LCprocfns
mov lr, pc
ldr pc, [ip, #PROCESSOR_PABT_FUNC]
ldr_va ip, processor, offset=PROCESSOR_PABT_FUNC
bl_r ip
#else
bl CPU_PABORT_HANDLER
#endif
Expand All @@ -82,9 +81,8 @@
@ the fault status register in r1. r9 must be preserved.
@
#ifdef MULTI_DABORT
ldr ip, .LCprocfns
mov lr, pc
ldr pc, [ip, #PROCESSOR_DABT_FUNC]
ldr_va ip, processor, offset=PROCESSOR_DABT_FUNC
bl_r ip
#else
bl CPU_DABORT_HANDLER
#endif
Expand Down Expand Up @@ -302,16 +300,6 @@ __fiq_svc:
UNWIND(.fnend )
ENDPROC(__fiq_svc)

.align 5
.LCcralign:
.word cr_alignment
#ifdef MULTI_DABORT
.LCprocfns:
.word processor
#endif
.LCfp:
.word fp_enter

/*
* Abort mode handlers
*/
Expand Down Expand Up @@ -370,7 +358,7 @@ ENDPROC(__fiq_abt)
THUMB( stmia sp, {r0 - r12} )

ATRAP( mrc p15, 0, r7, c1, c0, 0)
ATRAP( ldr r8, .LCcralign)
ATRAP( ldr_va r8, cr_alignment)

ldmia r0, {r3 - r5}
add r0, sp, #S_PC @ here for interlock avoidance
Expand All @@ -379,8 +367,6 @@ ENDPROC(__fiq_abt)
str r3, [sp] @ save the "real" r0 copied
@ from the exception stack

ATRAP( ldr r8, [r8, #0])

@
@ We are now ready to fill in the remaining blanks on the stack:
@
Expand Down Expand Up @@ -505,9 +491,7 @@ __und_usr_thumb:
*/
#if __LINUX_ARM_ARCH__ < 7
/* If the target CPU may not be Thumb-2-capable, a run-time check is needed: */
#define NEED_CPU_ARCHITECTURE
ldr r5, .LCcpu_architecture
ldr r5, [r5]
ldr_va r5, cpu_architecture
cmp r5, #CPU_ARCH_ARMv7
blo __und_usr_fault_16 @ 16bit undefined instruction
/*
Expand Down Expand Up @@ -654,12 +638,6 @@ call_fpe:
ret.w lr @ CP#14 (Debug)
ret.w lr @ CP#15 (Control)

#ifdef NEED_CPU_ARCHITECTURE
.align 2
.LCcpu_architecture:
.word __cpu_architecture
#endif

#ifdef CONFIG_NEON
.align 6

Expand All @@ -685,9 +663,8 @@ call_fpe:
#endif

do_fpe:
ldr r4, .LCfp
add r10, r10, #TI_FPSTATE @ r10 = workspace
ldr pc, [r4] @ Call FP module USR entry point
ldr_va pc, fp_enter, tmp=r4 @ Call FP module USR entry point

/*
* The FP module is called with these registers set:
Expand Down Expand Up @@ -1101,6 +1078,12 @@ __kuser_helper_end:
*/
.macro vector_stub, name, mode, correction=0
.align 5
#ifdef CONFIG_HARDEN_BRANCH_HISTORY
vector_bhb_bpiall_\name:
mcr p15, 0, r0, c7, c5, 6 @ BPIALL
@ isb not needed due to "movs pc, lr" in the vector stub
@ which gives a "context synchronisation".
#endif

vector_\name:
.if \correction
Expand All @@ -1111,7 +1094,8 @@ vector_\name:
stmia sp, {r0, lr} @ save r0, lr

@ Save spsr_<exception> (parent CPSR)
2: mrs lr, spsr
.Lvec_\name:
mrs lr, spsr
str lr, [sp, #8] @ save spsr

@
Expand Down Expand Up @@ -1148,25 +1132,11 @@ vector_bhb_loop8_\name:
3: W(b) . + 4
subs r0, r0, #1
bne 3b
dsb
isb
b 2b
ENDPROC(vector_bhb_loop8_\name)

vector_bhb_bpiall_\name:
.if \correction
sub lr, lr, #\correction
.endif

@ Save r0, lr_<exception> (parent PC)
stmia sp, {r0, lr}

@ bhb workaround
mcr p15, 0, r0, c7, c5, 6 @ BPIALL
dsb nsh
@ isb not needed due to "movs pc, lr" in the vector stub
@ which gives a "context synchronisation".
b 2b
ENDPROC(vector_bhb_bpiall_\name)
b .Lvec_\name
ENDPROC(vector_bhb_loop8_\name)
.previous
#endif

Expand All @@ -1176,10 +1146,15 @@ ENDPROC(vector_bhb_bpiall_\name)
.endm

.section .stubs, "ax", %progbits
@ This must be the first word
@ These need to remain at the start of the section so that
@ they are in range of the 'SWI' entries in the vector tables
@ located 4k down.
.L__vector_swi:
.word vector_swi
#ifdef CONFIG_HARDEN_BRANCH_HISTORY
.L__vector_bhb_loop8_swi:
.word vector_bhb_loop8_swi
.L__vector_bhb_bpiall_swi:
.word vector_bhb_bpiall_swi
#endif

Expand Down Expand Up @@ -1322,10 +1297,11 @@ vector_addrexcptn:
.globl vector_fiq

.section .vectors, "ax", %progbits
.L__vectors_start:
W(b) vector_rst
W(b) vector_und
W(ldr) pc, .L__vectors_start + 0x1000
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_swi )
THUMB( .reloc ., R_ARM_THM_PC12, .L__vector_swi )
W(ldr) pc, .
W(b) vector_pabt
W(b) vector_dabt
W(b) vector_addrexcptn
Expand All @@ -1334,21 +1310,23 @@ vector_addrexcptn:

#ifdef CONFIG_HARDEN_BRANCH_HISTORY
.section .vectors.bhb.loop8, "ax", %progbits
.L__vectors_bhb_loop8_start:
W(b) vector_rst
W(b) vector_bhb_loop8_und
W(ldr) pc, .L__vectors_bhb_loop8_start + 0x1004
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_bhb_loop8_swi )
THUMB( .reloc ., R_ARM_THM_PC12, .L__vector_bhb_loop8_swi )
W(ldr) pc, .
W(b) vector_bhb_loop8_pabt
W(b) vector_bhb_loop8_dabt
W(b) vector_addrexcptn
W(b) vector_bhb_loop8_irq
W(b) vector_bhb_loop8_fiq

.section .vectors.bhb.bpiall, "ax", %progbits
.L__vectors_bhb_bpiall_start:
W(b) vector_rst
W(b) vector_bhb_bpiall_und
W(ldr) pc, .L__vectors_bhb_bpiall_start + 0x1008
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_bhb_bpiall_swi )
THUMB( .reloc ., R_ARM_THM_PC12, .L__vector_bhb_bpiall_swi )
W(ldr) pc, .
W(b) vector_bhb_bpiall_pabt
W(b) vector_bhb_bpiall_dabt
W(b) vector_addrexcptn
Expand Down
12 changes: 2 additions & 10 deletions arch/arm/kernel/entry-common.S
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ ENTRY(vector_bhb_loop8_swi)
1: b 2f
2: subs r8, r8, #1
bne 1b
dsb
dsb nsh
isb
b 3f
ENDPROC(vector_bhb_loop8_swi)
Expand Down Expand Up @@ -198,7 +198,7 @@ ENTRY(vector_swi)
#endif
reload_current r10, ip
zero_fp
alignment_trap r10, ip, __cr_alignment
alignment_trap r10, ip, cr_alignment
asm_trace_hardirqs_on save=0
enable_irq_notrace
ct_user_exit save=0
Expand Down Expand Up @@ -328,14 +328,6 @@ __sys_trace_return:
bl syscall_trace_exit
b ret_slow_syscall

.align 5
#ifdef CONFIG_ALIGNMENT_TRAP
.type __cr_alignment, #object
__cr_alignment:
.word cr_alignment
#endif
.ltorg

.macro syscall_table_start, sym
.equ __sys_nr, 0
.type \sym, #object
Expand Down
3 changes: 1 addition & 2 deletions arch/arm/kernel/entry-header.S
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@
.macro alignment_trap, rtmp1, rtmp2, label
#ifdef CONFIG_ALIGNMENT_TRAP
mrc p15, 0, \rtmp2, c1, c0, 0
ldr \rtmp1, \label
ldr \rtmp1, [\rtmp1]
ldr_va \rtmp1, \label
teq \rtmp1, \rtmp2
mcrne p15, 0, \rtmp1, c1, c0, 0
#endif
Expand Down
Loading

0 comments on commit d6edf95

Please sign in to comment.