From 1f7d228c8ad8c2d60b83dbe7f015e3697fabf247 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 22 Jan 2019 15:18:47 -0500 Subject: [PATCH] target/arm: Introduce raise_exception_ra This path uses cpu_loop_exit_restore to unwind current processor state. Backports commit 7469f6c696d74ad3b22b67c08e1e8f79e2b5d3d6 from qemu --- qemu/aarch64.h | 1 + qemu/aarch64eb.h | 1 + qemu/arm.h | 1 + qemu/armeb.h | 1 + qemu/header_gen.py | 2 ++ qemu/target/arm/internals.h | 7 +++++++ qemu/target/arm/op_helper.c | 19 +++++++++++++++++-- 7 files changed, 30 insertions(+), 2 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index a7c32cea..add16191 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -4268,6 +4268,7 @@ #define new_tmp_a64_zero new_tmp_a64_zero_aarch64 #define pred_esz_masks pred_esz_masks_aarch64 #define raise_exception raise_exception_aarch64 +#define raise_exception_ra raise_exception_ra_aarch64 #define read_cpu_reg read_cpu_reg_aarch64 #define read_cpu_reg_sp read_cpu_reg_sp_aarch64 #define sli_op sli_op_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index eb34d13f..d25d946d 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -4268,6 +4268,7 @@ #define new_tmp_a64_zero new_tmp_a64_zero_aarch64eb #define pred_esz_masks pred_esz_masks_aarch64eb #define raise_exception raise_exception_aarch64eb +#define raise_exception_ra raise_exception_ra_aarch64eb #define read_cpu_reg read_cpu_reg_aarch64eb #define read_cpu_reg_sp read_cpu_reg_sp_aarch64eb #define sli_op sli_op_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 5e300615..6d347e0e 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -3286,6 +3286,7 @@ #define mla_op mla_op_arm #define mls_op mls_op_arm #define raise_exception raise_exception_arm +#define raise_exception_ra raise_exception_ra_arm #define sli_op sli_op_arm #define ssra_op ssra_op_arm #define sri_op sri_op_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 1bcd685d..58f4113e 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -3286,6 +3286,7 @@ #define mla_op mla_op_armeb #define mls_op mls_op_armeb #define raise_exception raise_exception_armeb +#define raise_exception_ra raise_exception_ra_armeb #define sli_op sli_op_armeb #define ssra_op ssra_op_armeb #define sri_op sri_op_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 6c27dba2..fd0e012f 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -3295,6 +3295,7 @@ arm_symbols = ( 'mla_op', 'mls_op', 'raise_exception', + 'raise_exception_ra', 'sli_op', 'ssra_op', 'sri_op', @@ -4302,6 +4303,7 @@ aarch64_symbols = ( 'new_tmp_a64_zero', 'pred_esz_masks', 'raise_exception', + 'raise_exception_ra', 'read_cpu_reg', 'read_cpu_reg_sp', 'sli_op', diff --git a/qemu/target/arm/internals.h b/qemu/target/arm/internals.h index f9c9d0b0..731a63a1 100644 --- a/qemu/target/arm/internals.h +++ b/qemu/target/arm/internals.h @@ -103,6 +103,13 @@ FIELD(V7M_EXCRET, RES1, 7, 25) /* including the must-be-1 prefix */ void QEMU_NORETURN raise_exception(CPUARMState *env, uint32_t excp, uint32_t syndrome, uint32_t target_el); +/* + * Similarly, but also use unwinding to restore cpu state. + */ +void QEMU_NORETURN raise_exception_ra(CPUARMState *env, uint32_t excp, + uint32_t syndrome, uint32_t target_el, + uintptr_t ra); + /* * For AArch64, map a given EL to an index in the banked_spsr array. * Note that this mapping and the AArch32 mapping defined in bank_number() diff --git a/qemu/target/arm/op_helper.c b/qemu/target/arm/op_helper.c index 9b655e14..f22336f5 100644 --- a/qemu/target/arm/op_helper.c +++ b/qemu/target/arm/op_helper.c @@ -27,8 +27,8 @@ #define SIGNBIT (uint32_t)0x80000000 #define SIGNBIT64 ((uint64_t)1 << 63) -void raise_exception(CPUARMState *env, uint32_t excp, - uint32_t syndrome, uint32_t target_el) +static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp, + uint32_t syndrome, uint32_t target_el) { CPUState *cs = CPU(arm_env_get_cpu(env)); @@ -49,9 +49,24 @@ void raise_exception(CPUARMState *env, uint32_t excp, cs->exception_index = excp; env->exception.syndrome = syndrome; env->exception.target_el = target_el; + + return cs; +} + +void raise_exception(CPUARMState *env, uint32_t excp, + uint32_t syndrome, uint32_t target_el) +{ + CPUState *cs = do_raise_exception(env, excp, syndrome, target_el); cpu_loop_exit(cs); } +void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome, + uint32_t target_el, uintptr_t ra) +{ + CPUState *cs = do_raise_exception(env, excp, syndrome, target_el); + cpu_loop_exit_restore(cs, ra); +} + static int exception_target_el(CPUARMState *env) { int target_el = MAX(1, arm_current_el(env));