Skip to content

Commit 8d56e5c

Browse files
Alexandru Eliseictmarinas
authored andcommitted
arm64: Treat ESR_ELx as a 64-bit register
In the initial release of the ARM Architecture Reference Manual for ARMv8-A, the ESR_ELx registers were defined as 32-bit registers. This changed in 2018 with version D.a (ARM DDI 0487D.a) of the architecture, when they became 64-bit registers, with bits [63:32] defined as RES0. In version G.a, a new field was added to ESR_ELx, ISS2, which covers bits [36:32]. This field is used when the Armv8.7 extension FEAT_LS64 is implemented. As a result of the evolution of the register width, Linux stores it as both a 64-bit value and a 32-bit value, which hasn't affected correctness so far as Linux only uses the lower 32 bits of the register. Make the register type consistent and always treat it as 64-bit wide. The register is redefined as an "unsigned long", which is an unsigned double-word (64-bit quantity) for the LP64 machine (aapcs64 [1], Table 1, page 14). The type was chosen because "unsigned int" is the most frequent type for ESR_ELx and because FAR_ELx, which is used together with ESR_ELx in exception handling, is also declared as "unsigned long". The 64-bit type also makes adding support for architectural features that use fields above bit 31 easier in the future. The KVM hypervisor will receive a similar update in a subsequent patch. [1] https://github.com/ARM-software/abi-aa/releases/download/2021Q3/aapcs64.pdf Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com> Reviewed-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220425114444.368693-4-alexandru.elisei@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent 3fed9e5 commit 8d56e5c

File tree

14 files changed

+116
-116
lines changed

14 files changed

+116
-116
lines changed

arch/arm64/include/asm/debug-monitors.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct task_struct;
6464

6565
struct step_hook {
6666
struct list_head node;
67-
int (*fn)(struct pt_regs *regs, unsigned int esr);
67+
int (*fn)(struct pt_regs *regs, unsigned long esr);
6868
};
6969

7070
void register_user_step_hook(struct step_hook *hook);
@@ -75,7 +75,7 @@ void unregister_kernel_step_hook(struct step_hook *hook);
7575

7676
struct break_hook {
7777
struct list_head node;
78-
int (*fn)(struct pt_regs *regs, unsigned int esr);
78+
int (*fn)(struct pt_regs *regs, unsigned long esr);
7979
u16 imm;
8080
u16 mask; /* These bits are ignored when comparing with imm */
8181
};

arch/arm64/include/asm/esr.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,14 +330,14 @@
330330
#ifndef __ASSEMBLY__
331331
#include <asm/types.h>
332332

333-
static inline bool esr_is_data_abort(u32 esr)
333+
static inline bool esr_is_data_abort(unsigned long esr)
334334
{
335-
const u32 ec = ESR_ELx_EC(esr);
335+
const unsigned long ec = ESR_ELx_EC(esr);
336336

337337
return ec == ESR_ELx_EC_DABT_LOW || ec == ESR_ELx_EC_DABT_CUR;
338338
}
339339

340-
const char *esr_get_class_string(u32 esr);
340+
const char *esr_get_class_string(unsigned long esr);
341341
#endif /* __ASSEMBLY */
342342

343343
#endif /* __ASM_ESR_H */

arch/arm64/include/asm/exception.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
#define __exception_irq_entry __kprobes
2020
#endif
2121

22-
static inline u32 disr_to_esr(u64 disr)
22+
static inline unsigned long disr_to_esr(u64 disr)
2323
{
24-
unsigned int esr = ESR_ELx_EC_SERROR << ESR_ELx_EC_SHIFT;
24+
unsigned long esr = ESR_ELx_EC_SERROR << ESR_ELx_EC_SHIFT;
2525

2626
if ((disr & DISR_EL1_IDS) == 0)
2727
esr |= (disr & DISR_EL1_ESR_MASK);
@@ -57,23 +57,23 @@ asmlinkage void call_on_irq_stack(struct pt_regs *regs,
5757
void (*func)(struct pt_regs *));
5858
asmlinkage void asm_exit_to_user_mode(struct pt_regs *regs);
5959

60-
void do_mem_abort(unsigned long far, unsigned int esr, struct pt_regs *regs);
60+
void do_mem_abort(unsigned long far, unsigned long esr, struct pt_regs *regs);
6161
void do_undefinstr(struct pt_regs *regs);
6262
void do_bti(struct pt_regs *regs);
63-
void do_debug_exception(unsigned long addr_if_watchpoint, unsigned int esr,
63+
void do_debug_exception(unsigned long addr_if_watchpoint, unsigned long esr,
6464
struct pt_regs *regs);
65-
void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs);
66-
void do_sve_acc(unsigned int esr, struct pt_regs *regs);
67-
void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs);
68-
void do_sysinstr(unsigned int esr, struct pt_regs *regs);
69-
void do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs);
70-
void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr);
71-
void do_cp15instr(unsigned int esr, struct pt_regs *regs);
65+
void do_fpsimd_acc(unsigned long esr, struct pt_regs *regs);
66+
void do_sve_acc(unsigned long esr, struct pt_regs *regs);
67+
void do_fpsimd_exc(unsigned long esr, struct pt_regs *regs);
68+
void do_sysinstr(unsigned long esr, struct pt_regs *regs);
69+
void do_sp_pc_abort(unsigned long addr, unsigned long esr, struct pt_regs *regs);
70+
void bad_el0_sync(struct pt_regs *regs, int reason, unsigned long esr);
71+
void do_cp15instr(unsigned long esr, struct pt_regs *regs);
7272
void do_el0_svc(struct pt_regs *regs);
7373
void do_el0_svc_compat(struct pt_regs *regs);
74-
void do_ptrauth_fault(struct pt_regs *regs, unsigned int esr);
75-
void do_serror(struct pt_regs *regs, unsigned int esr);
74+
void do_ptrauth_fault(struct pt_regs *regs, unsigned long esr);
75+
void do_serror(struct pt_regs *regs, unsigned long esr);
7676
void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags);
7777

78-
void panic_bad_stack(struct pt_regs *regs, unsigned int esr, unsigned long far);
78+
void panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far);
7979
#endif /* __ASM_EXCEPTION_H */

arch/arm64/include/asm/system_misc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ void die(const char *msg, struct pt_regs *regs, int err);
2323
struct siginfo;
2424
void arm64_notify_die(const char *str, struct pt_regs *regs,
2525
int signo, int sicode, unsigned long far,
26-
int err);
26+
unsigned long err);
2727

28-
void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
28+
void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned long,
2929
struct pt_regs *),
3030
int sig, int code, const char *name);
3131

arch/arm64/include/asm/traps.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct undef_hook {
2424

2525
void register_undef_hook(struct undef_hook *hook);
2626
void unregister_undef_hook(struct undef_hook *hook);
27-
void force_signal_inject(int signal, int code, unsigned long address, unsigned int err);
27+
void force_signal_inject(int signal, int code, unsigned long address, unsigned long err);
2828
void arm64_notify_segfault(unsigned long addr);
2929
void arm64_force_sig_fault(int signo, int code, unsigned long far, const char *str);
3030
void arm64_force_sig_mceerr(int code, unsigned long far, short lsb, const char *str);
@@ -57,7 +57,7 @@ static inline int in_entry_text(unsigned long ptr)
5757
* errors share the same encoding as an all-zeros encoding from a CPU that
5858
* doesn't support RAS.
5959
*/
60-
static inline bool arm64_is_ras_serror(u32 esr)
60+
static inline bool arm64_is_ras_serror(unsigned long esr)
6161
{
6262
WARN_ON(preemptible());
6363

@@ -77,9 +77,9 @@ static inline bool arm64_is_ras_serror(u32 esr)
7777
* We treat them as Uncontainable.
7878
* Non-RAS SError's are reported as Uncontained/Uncategorized.
7979
*/
80-
static inline u32 arm64_ras_serror_get_severity(u32 esr)
80+
static inline unsigned long arm64_ras_serror_get_severity(unsigned long esr)
8181
{
82-
u32 aet = esr & ESR_ELx_AET;
82+
unsigned long aet = esr & ESR_ELx_AET;
8383

8484
if (!arm64_is_ras_serror(esr)) {
8585
/* Not a RAS error, we can't interpret the ESR. */
@@ -98,6 +98,6 @@ static inline u32 arm64_ras_serror_get_severity(u32 esr)
9898
return aet;
9999
}
100100

101-
bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned int esr);
102-
void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr);
101+
bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned long esr);
102+
void __noreturn arm64_serror_panic(struct pt_regs *regs, unsigned long esr);
103103
#endif

arch/arm64/kernel/debug-monitors.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ void unregister_kernel_step_hook(struct step_hook *hook)
202202
* So we call all the registered handlers, until the right handler is
203203
* found which returns zero.
204204
*/
205-
static int call_step_hook(struct pt_regs *regs, unsigned int esr)
205+
static int call_step_hook(struct pt_regs *regs, unsigned long esr)
206206
{
207207
struct step_hook *hook;
208208
struct list_head *list;
@@ -238,7 +238,7 @@ static void send_user_sigtrap(int si_code)
238238
"User debug trap");
239239
}
240240

241-
static int single_step_handler(unsigned long unused, unsigned int esr,
241+
static int single_step_handler(unsigned long unused, unsigned long esr,
242242
struct pt_regs *regs)
243243
{
244244
bool handler_found = false;
@@ -299,11 +299,11 @@ void unregister_kernel_break_hook(struct break_hook *hook)
299299
unregister_debug_hook(&hook->node);
300300
}
301301

302-
static int call_break_hook(struct pt_regs *regs, unsigned int esr)
302+
static int call_break_hook(struct pt_regs *regs, unsigned long esr)
303303
{
304304
struct break_hook *hook;
305305
struct list_head *list;
306-
int (*fn)(struct pt_regs *regs, unsigned int esr) = NULL;
306+
int (*fn)(struct pt_regs *regs, unsigned long esr) = NULL;
307307

308308
list = user_mode(regs) ? &user_break_hook : &kernel_break_hook;
309309

@@ -312,7 +312,7 @@ static int call_break_hook(struct pt_regs *regs, unsigned int esr)
312312
* entirely not preemptible, and we can use rcu list safely here.
313313
*/
314314
list_for_each_entry_rcu(hook, list, node) {
315-
unsigned int comment = esr & ESR_ELx_BRK64_ISS_COMMENT_MASK;
315+
unsigned long comment = esr & ESR_ELx_BRK64_ISS_COMMENT_MASK;
316316

317317
if ((comment & ~hook->mask) == hook->imm)
318318
fn = hook->fn;
@@ -322,7 +322,7 @@ static int call_break_hook(struct pt_regs *regs, unsigned int esr)
322322
}
323323
NOKPROBE_SYMBOL(call_break_hook);
324324

325-
static int brk_handler(unsigned long unused, unsigned int esr,
325+
static int brk_handler(unsigned long unused, unsigned long esr,
326326
struct pt_regs *regs)
327327
{
328328
if (call_break_hook(regs, esr) == DBG_HOOK_HANDLED)

arch/arm64/kernel/entry-common.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,13 @@ extern void (*handle_arch_irq)(struct pt_regs *);
282282
extern void (*handle_arch_fiq)(struct pt_regs *);
283283

284284
static void noinstr __panic_unhandled(struct pt_regs *regs, const char *vector,
285-
unsigned int esr)
285+
unsigned long esr)
286286
{
287287
arm64_enter_nmi(regs);
288288

289289
console_verbose();
290290

291-
pr_crit("Unhandled %s exception on CPU%d, ESR 0x%08x -- %s\n",
291+
pr_crit("Unhandled %s exception on CPU%d, ESR 0x%016lx -- %s\n",
292292
vector, smp_processor_id(), esr,
293293
esr_get_class_string(esr));
294294

@@ -818,7 +818,7 @@ UNHANDLED(el0t, 32, error)
818818
#ifdef CONFIG_VMAP_STACK
819819
asmlinkage void noinstr handle_bad_stack(struct pt_regs *regs)
820820
{
821-
unsigned int esr = read_sysreg(esr_el1);
821+
unsigned long esr = read_sysreg(esr_el1);
822822
unsigned long far = read_sysreg(far_el1);
823823

824824
arm64_enter_nmi(regs);

arch/arm64/kernel/fpsimd.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ void fpsimd_release_task(struct task_struct *dead_task)
10041004
* would have disabled the SVE access trap for userspace during
10051005
* ret_to_user, making an SVE access trap impossible in that case.
10061006
*/
1007-
void do_sve_acc(unsigned int esr, struct pt_regs *regs)
1007+
void do_sve_acc(unsigned long esr, struct pt_regs *regs)
10081008
{
10091009
/* Even if we chose not to use SVE, the hardware could still trap: */
10101010
if (unlikely(!system_supports_sve()) || WARN_ON(is_compat_task())) {
@@ -1046,7 +1046,7 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs)
10461046
/*
10471047
* Trapped FP/ASIMD access.
10481048
*/
1049-
void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs)
1049+
void do_fpsimd_acc(unsigned long esr, struct pt_regs *regs)
10501050
{
10511051
/* TODO: implement lazy context saving/restoring */
10521052
WARN_ON(1);
@@ -1055,7 +1055,7 @@ void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs)
10551055
/*
10561056
* Raise a SIGFPE for the current process.
10571057
*/
1058-
void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs)
1058+
void do_fpsimd_exc(unsigned long esr, struct pt_regs *regs)
10591059
{
10601060
unsigned int si_code = FPE_FLTUNK;
10611061

arch/arm64/kernel/hw_breakpoint.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ NOKPROBE_SYMBOL(toggle_bp_registers);
617617
/*
618618
* Debug exception handlers.
619619
*/
620-
static int breakpoint_handler(unsigned long unused, unsigned int esr,
620+
static int breakpoint_handler(unsigned long unused, unsigned long esr,
621621
struct pt_regs *regs)
622622
{
623623
int i, step = 0, *kernel_step;
@@ -751,7 +751,7 @@ static int watchpoint_report(struct perf_event *wp, unsigned long addr,
751751
return step;
752752
}
753753

754-
static int watchpoint_handler(unsigned long addr, unsigned int esr,
754+
static int watchpoint_handler(unsigned long addr, unsigned long esr,
755755
struct pt_regs *regs)
756756
{
757757
int i, step = 0, *kernel_step, access, closest_match = 0;

arch/arm64/kernel/kgdb.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,14 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
232232
return err;
233233
}
234234

235-
static int kgdb_brk_fn(struct pt_regs *regs, unsigned int esr)
235+
static int kgdb_brk_fn(struct pt_regs *regs, unsigned long esr)
236236
{
237237
kgdb_handle_exception(1, SIGTRAP, 0, regs);
238238
return DBG_HOOK_HANDLED;
239239
}
240240
NOKPROBE_SYMBOL(kgdb_brk_fn)
241241

242-
static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
242+
static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned long esr)
243243
{
244244
compiled_break = 1;
245245
kgdb_handle_exception(1, SIGTRAP, 0, regs);
@@ -248,7 +248,7 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
248248
}
249249
NOKPROBE_SYMBOL(kgdb_compiled_brk_fn);
250250

251-
static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
251+
static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned long esr)
252252
{
253253
if (!kgdb_single_step)
254254
return DBG_HOOK_ERROR;

0 commit comments

Comments
 (0)