Skip to content

Commit 6c94f27

Browse files
Ard Biesheuvelctmarinas
authored andcommitted
arm64: switch to relative exception tables
Instead of using absolute addresses for both the exception location and the fixup, use offsets relative to the exception table entry values. Not only does this cut the size of the exception table in half, it is also a prerequisite for KASLR, since absolute exception table entries are subject to dynamic relocation, which is incompatible with the sorting of the exception table that occurs at build time. This patch also introduces the _ASM_EXTABLE preprocessor macro (which exists on x86 as well) and its _asm_extable assembly counterpart, as shorthands to emit exception table entries. Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent a272858 commit 6c94f27

File tree

8 files changed

+43
-51
lines changed

8 files changed

+43
-51
lines changed

arch/arm64/include/asm/alternative.h

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,8 @@ void apply_alternatives(void *start, size_t length);
157157
add \addr, \addr, \post_inc;
158158
alternative_endif
159159

160-
.section __ex_table,"a";
161-
.align 3;
162-
.quad 8888b,\l;
163-
.quad 8889b,\l;
164-
.previous;
160+
_asm_extable 8888b,\l;
161+
_asm_extable 8889b,\l;
165162
.endm
166163

167164
.macro uao_stp l, reg1, reg2, addr, post_inc
@@ -175,11 +172,8 @@ void apply_alternatives(void *start, size_t length);
175172
add \addr, \addr, \post_inc;
176173
alternative_endif
177174

178-
.section __ex_table,"a";
179-
.align 3;
180-
.quad 8888b,\l;
181-
.quad 8889b,\l;
182-
.previous
175+
_asm_extable 8888b,\l;
176+
_asm_extable 8889b,\l;
183177
.endm
184178

185179
.macro uao_user_alternative l, inst, alt_inst, reg, addr, post_inc
@@ -191,10 +185,7 @@ void apply_alternatives(void *start, size_t length);
191185
add \addr, \addr, \post_inc;
192186
alternative_endif
193187

194-
.section __ex_table,"a";
195-
.align 3;
196-
.quad 8888b,\l;
197-
.previous
188+
_asm_extable 8888b,\l;
198189
.endm
199190
#else
200191
.macro uao_ldp l, reg1, reg2, addr, post_inc

arch/arm64/include/asm/assembler.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,19 @@
9494
dmb \opt
9595
.endm
9696

97+
/*
98+
* Emit an entry into the exception table
99+
*/
100+
.macro _asm_extable, from, to
101+
.pushsection __ex_table, "a"
102+
.align 3
103+
.long (\from - .), (\to - .)
104+
.popsection
105+
.endm
106+
97107
#define USER(l, x...) \
98108
9999: x; \
99-
.section __ex_table,"a"; \
100-
.align 3; \
101-
.quad 9999b,l; \
102-
.previous
109+
_asm_extable 9999b, l
103110

104111
/*
105112
* Register aliases.

arch/arm64/include/asm/futex.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@
4242
"4: mov %w0, %w5\n" \
4343
" b 3b\n" \
4444
" .popsection\n" \
45-
" .pushsection __ex_table,\"a\"\n" \
46-
" .align 3\n" \
47-
" .quad 1b, 4b, 2b, 4b\n" \
48-
" .popsection\n" \
45+
_ASM_EXTABLE(1b, 4b) \
46+
_ASM_EXTABLE(2b, 4b) \
4947
ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \
5048
CONFIG_ARM64_PAN) \
5149
: "=&r" (ret), "=&r" (oldval), "+Q" (*uaddr), "=&r" (tmp) \
@@ -134,10 +132,8 @@ ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
134132
"4: mov %w0, %w6\n"
135133
" b 3b\n"
136134
" .popsection\n"
137-
" .pushsection __ex_table,\"a\"\n"
138-
" .align 3\n"
139-
" .quad 1b, 4b, 2b, 4b\n"
140-
" .popsection\n"
135+
_ASM_EXTABLE(1b, 4b)
136+
_ASM_EXTABLE(2b, 4b)
141137
ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
142138
: "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp)
143139
: "r" (oldval), "r" (newval), "Ir" (-EFAULT)

arch/arm64/include/asm/uaccess.h

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@
3636
#define VERIFY_WRITE 1
3737

3838
/*
39-
* The exception table consists of pairs of addresses: the first is the
40-
* address of an instruction that is allowed to fault, and the second is
41-
* the address at which the program should continue. No registers are
42-
* modified, so it is entirely up to the continuation code to figure out
43-
* what to do.
39+
* The exception table consists of pairs of relative offsets: the first
40+
* is the relative offset to an instruction that is allowed to fault,
41+
* and the second is the relative offset at which the program should
42+
* continue. No registers are modified, so it is entirely up to the
43+
* continuation code to figure out what to do.
4444
*
4545
* All the routines below use bits of fixup code that are out of line
4646
* with the main instruction path. This means when everything is well,
@@ -50,9 +50,11 @@
5050

5151
struct exception_table_entry
5252
{
53-
unsigned long insn, fixup;
53+
int insn, fixup;
5454
};
5555

56+
#define ARCH_HAS_RELATIVE_EXTABLE
57+
5658
extern int fixup_exception(struct pt_regs *regs);
5759

5860
#define KERNEL_DS (-1UL)
@@ -115,6 +117,12 @@ static inline void set_fs(mm_segment_t fs)
115117
#define access_ok(type, addr, size) __range_ok(addr, size)
116118
#define user_addr_max get_fs
117119

120+
#define _ASM_EXTABLE(from, to) \
121+
" .pushsection __ex_table, \"a\"\n" \
122+
" .align 3\n" \
123+
" .long (" #from " - .), (" #to " - .)\n" \
124+
" .popsection\n"
125+
118126
/*
119127
* The "__xxx" versions of the user access functions do not verify the address
120128
* space - it must have been done previously with a separate "access_ok()"
@@ -134,10 +142,7 @@ static inline void set_fs(mm_segment_t fs)
134142
" mov %1, #0\n" \
135143
" b 2b\n" \
136144
" .previous\n" \
137-
" .section __ex_table,\"a\"\n" \
138-
" .align 3\n" \
139-
" .quad 1b, 3b\n" \
140-
" .previous" \
145+
_ASM_EXTABLE(1b, 3b) \
141146
: "+r" (err), "=&r" (x) \
142147
: "r" (addr), "i" (-EFAULT))
143148

@@ -206,10 +211,7 @@ do { \
206211
"3: mov %w0, %3\n" \
207212
" b 2b\n" \
208213
" .previous\n" \
209-
" .section __ex_table,\"a\"\n" \
210-
" .align 3\n" \
211-
" .quad 1b, 3b\n" \
212-
" .previous" \
214+
_ASM_EXTABLE(1b, 3b) \
213215
: "+r" (err) \
214216
: "r" (x), "r" (addr), "i" (-EFAULT))
215217

arch/arm64/include/asm/word-at-a-time.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#ifndef __ASM_WORD_AT_A_TIME_H
1717
#define __ASM_WORD_AT_A_TIME_H
1818

19+
#include <asm/uaccess.h>
20+
1921
#ifndef __AARCH64EB__
2022

2123
#include <linux/kernel.h>
@@ -81,10 +83,7 @@ static inline unsigned long load_unaligned_zeropad(const void *addr)
8183
#endif
8284
" b 2b\n"
8385
" .popsection\n"
84-
" .pushsection __ex_table,\"a\"\n"
85-
" .align 3\n"
86-
" .quad 1b, 3b\n"
87-
" .popsection"
86+
_ASM_EXTABLE(1b, 3b)
8887
: "=&r" (ret), "=&r" (offset)
8988
: "r" (addr), "Q" (*(unsigned long *)addr));
9089

arch/arm64/kernel/armv8_deprecated.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,8 @@ static void __init register_insn_emulation_sysctl(struct ctl_table *table)
297297
"4: mov %w0, %w5\n" \
298298
" b 3b\n" \
299299
" .popsection" \
300-
" .pushsection __ex_table,\"a\"\n" \
301-
" .align 3\n" \
302-
" .quad 0b, 4b\n" \
303-
" .quad 1b, 4b\n" \
304-
" .popsection\n" \
300+
_ASM_EXTABLE(0b, 4b) \
301+
_ASM_EXTABLE(1b, 4b) \
305302
ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \
306303
CONFIG_ARM64_PAN) \
307304
: "=&r" (res), "+r" (data), "=&r" (temp) \

arch/arm64/mm/extable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs)
1111

1212
fixup = search_exception_tables(instruction_pointer(regs));
1313
if (fixup)
14-
regs->pc = fixup->fixup;
14+
regs->pc = (unsigned long)&fixup->fixup + fixup->fixup;
1515

1616
return fixup != NULL;
1717
}

scripts/sortextable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,12 @@ do_file(char const *const fname)
282282
case EM_386:
283283
case EM_X86_64:
284284
case EM_S390:
285+
case EM_AARCH64:
285286
custom_sort = sort_relative_table;
286287
break;
287288
case EM_ARCOMPACT:
288289
case EM_ARCV2:
289290
case EM_ARM:
290-
case EM_AARCH64:
291291
case EM_MICROBLAZE:
292292
case EM_MIPS:
293293
case EM_XTENSA:

0 commit comments

Comments
 (0)