diff --git a/include/arch/aarch64/setjmp.h b/include/arch/aarch64/setjmp.h index bbfe1df..f7991fd 100644 --- a/include/arch/aarch64/setjmp.h +++ b/include/arch/aarch64/setjmp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,46 +14,20 @@ #define JMP_CTX_X27 0x40 #define JMP_CTX_X29 0x50 #define JMP_CTX_SP 0x60 -#define JMP_CTX_END 0x70 +#define JMP_CTX_END 0x70 /* Aligned to 16 bytes */ #define JMP_SIZE (JMP_CTX_END >> 3) #ifndef __ASSEMBLY__ +#include #include /* Jump buffer hosting x18 - x30 and sp_el0 registers */ -struct jmpbuf { - uint64_t buf[JMP_SIZE]; -} __aligned(16); +typedef uint64_t jmp_buf[JMP_SIZE] __aligned(16); - -/* - * Set a jump point, and populate the jump buffer with context information so - * that longjmp() can jump later. The caller must adhere to the following - * conditions: - * - * - After calling this function, the stack must not be shrunk. The contents of - * the stack must not be changed either. - * - * - If the caller were to 'return', the buffer must be considered invalid, and - * must not be used with longjmp(). - * - * The caller will observe this function returning at two distinct - * circumstances, each with different return values: - * - * - Zero, when the buffer is setup; - * - * - Non-zero, when a call to longjmp() is made (presumably by one of the - * callee functions) with the same jump buffer. - */ -int setjmp(struct jmpbuf *buf); - -/* - * Reset execution to a jump point, and restore context information according to - * the jump buffer populated by setjmp(). - */ -void longjmp(struct jmpbuf *buf); +int setjmp(jmp_buf env); +__dead2 void longjmp(jmp_buf env, int val); #endif /* __ASSEMBLY__ */ #endif /* SETJMP_H */ diff --git a/lib/aarch64/setjmp.S b/lib/aarch64/setjmp.S index 9060cb7..9d9eb49 100644 --- a/lib/aarch64/setjmp.S +++ b/lib/aarch64/setjmp.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,10 +12,7 @@ .globl longjmp /* - * int setjmp(struct jmpbuf *buf); - * - * Sets a jump point in the buffer specified in x0. Returns 0 to the caller when - * when setting up the jump, and 1 when returning from the jump. + * int setjmp(jmp_buf env); */ func setjmp mov x7, sp @@ -34,9 +31,7 @@ /* - * void longjmp(struct jmpbuf *buf); - * - * Return to a jump point setup by setjmp() + * void longjmp(jmp_buf env, int val); */ func longjmp ldp x7, xzr, [x0, #JMP_CTX_SP] @@ -60,6 +55,7 @@ mov sp, x7 - mov x0, #1 + ands x0, x1, x1 /* Move val to x0 and set flags */ + cinc x0, x0, eq /* If val is 0, return 1 */ ret endfunc longjmp diff --git a/services/std_svc/sdei/sdei_dispatch.S b/services/std_svc/sdei/sdei_dispatch.S index a7a4a40..8449e4b 100644 --- a/services/std_svc/sdei/sdei_dispatch.S +++ b/services/std_svc/sdei/sdei_dispatch.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,7 @@ .globl begin_sdei_synchronous_dispatch /* - * void begin_sdei_synchronous_dispatch(struct jmpbuf *buffer); + * void begin_sdei_synchronous_dispatch(jmp_buf *buffer); * * Begin SDEI dispatch synchronously by setting up a jump point, and exiting * EL3. This jump point is jumped to by the dispatcher after the event is diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c index b8799cd..fa1d3d2 100644 --- a/services/std_svc/sdei/sdei_intr_mgmt.c +++ b/services/std_svc/sdei/sdei_intr_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -31,7 +31,7 @@ typedef struct sdei_dispatch_context { sdei_ev_map_t *map; uint64_t x[SDEI_SAVED_GPREGS]; - struct jmpbuf *dispatch_jmp; + jmp_buf *dispatch_jmp; /* Exception state registers */ uint64_t elr_el3; @@ -236,7 +236,7 @@ * SDEI client. */ static void setup_ns_dispatch(sdei_ev_map_t *map, sdei_entry_t *se, - cpu_context_t *ctx, struct jmpbuf *dispatch_jmp) + cpu_context_t *ctx, jmp_buf *dispatch_jmp) { sdei_dispatch_context_t *disp_ctx; @@ -347,7 +347,7 @@ unsigned int sec_state; sdei_cpu_state_t *state; uint32_t intr; - struct jmpbuf dispatch_jmp; + jmp_buf dispatch_jmp; const uint64_t mpidr = read_mpidr_el1(); /* @@ -529,7 +529,7 @@ cpu_context_t *ns_ctx; sdei_dispatch_context_t *disp_ctx; sdei_cpu_state_t *state; - struct jmpbuf dispatch_jmp; + jmp_buf dispatch_jmp; /* Can't dispatch if events are masked on this PE */ state = sdei_get_this_pe_state(); @@ -595,9 +595,9 @@ return 0; } -static void end_sdei_synchronous_dispatch(struct jmpbuf *buffer) +static void end_sdei_synchronous_dispatch(jmp_buf *buffer) { - longjmp(buffer); + longjmp(*buffer, 1); } int sdei_event_complete(bool resume, uint64_t pc) diff --git a/services/std_svc/sdei/sdei_private.h b/services/std_svc/sdei/sdei_private.h index 1486431..8cc66e7 100644 --- a/services/std_svc/sdei/sdei_private.h +++ b/services/std_svc/sdei/sdei_private.h @@ -243,6 +243,6 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle, void *cookie); bool can_sdei_state_trans(sdei_entry_t *se, sdei_action_t act); -void begin_sdei_synchronous_dispatch(struct jmpbuf *buffer); +void begin_sdei_synchronous_dispatch(jmp_buf *buffer); #endif /* SDEI_PRIVATE_H */