diff mbox series

[01/18] target/arm: Allow raise_exception to handle finding target EL

Message ID 20220523204742.740932-2-richard.henderson@linaro.org
State New
Headers show
Series target/arm: tidy exception routing | expand

Commit Message

Richard Henderson May 23, 2022, 8:47 p.m. UTC
The work of finding the correct target EL for an exception is
currently split between raise_exception and target_exception_el.
Begin merging these by allowing the input to raise_exception
to be zero and use exception_target_el for that case.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/internals.h | 11 ++++++-----
 target/arm/op_helper.c | 13 +++++++++----
 2 files changed, 15 insertions(+), 9 deletions(-)

Comments

Peter Maydell May 30, 2022, 12:44 p.m. UTC | #1
On Mon, 23 May 2022 at 21:49, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The work of finding the correct target EL for an exception is
> currently split between raise_exception and target_exception_el.
> Begin merging these by allowing the input to raise_exception
> to be zero and use exception_target_el for that case.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/internals.h | 11 ++++++-----
>  target/arm/op_helper.c | 13 +++++++++----
>  2 files changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/target/arm/internals.h b/target/arm/internals.h
> index b654bee468..03363b0f32 100644
> --- a/target/arm/internals.h
> +++ b/target/arm/internals.h
> @@ -111,18 +111,19 @@ FIELD(DBGWCR, SSCE, 29, 1)
>  /**
>   * raise_exception: Raise the specified exception.
>   * Raise a guest exception with the specified value, syndrome register
> - * and target exception level. This should be called from helper functions,
> - * and never returns because we will longjump back up to the CPU main loop.
> + * and the current or target exception level. This should be called from
> + * helper functions, and never returns because we will longjump back up
> + * to the CPU main loop.
>   */
>  G_NORETURN void raise_exception(CPUARMState *env, uint32_t excp,
> -                                uint32_t syndrome, uint32_t target_el);
> +                                uint32_t syndrome, uint32_t cur_or_target_el);

"cur_or_target_el" is odd, because it's mixing what the architecture
sets up as two distinct things: the state the exception is
"taken from", and the state the exception is "taken to". I was
hoping this was just a temporary thing for the purposes of the
refactoring and it would go away near the end of the series, but
it doesn't seem to.

-- PMM
Richard Henderson May 30, 2022, 4:39 p.m. UTC | #2
On 5/30/22 05:44, Peter Maydell wrote:
>>   G_NORETURN void raise_exception(CPUARMState *env, uint32_t excp,
>> -                                uint32_t syndrome, uint32_t target_el);
>> +                                uint32_t syndrome, uint32_t cur_or_target_el);
> 
> "cur_or_target_el" is odd, because it's mixing what the architecture
> sets up as two distinct things: the state the exception is
> "taken from", and the state the exception is "taken to". I was
> hoping this was just a temporary thing for the purposes of the
> refactoring and it would go away near the end of the series, but
> it doesn't seem to.

No, sorry.  Most of the time it's cur_el, except from cpregs, where we get directed to a 
specific higher el.  There may be some way to split the helpers...

I'll have another go at this reorg this week.  If it still doesn't feel cleaner, we can 
drop it, and I'll make some changes to the SME patch set building on this.


r~
Peter Maydell May 30, 2022, 7:01 p.m. UTC | #3
On Mon, 30 May 2022 at 17:39, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 5/30/22 05:44, Peter Maydell wrote:
> >>   G_NORETURN void raise_exception(CPUARMState *env, uint32_t excp,
> >> -                                uint32_t syndrome, uint32_t target_el);
> >> +                                uint32_t syndrome, uint32_t cur_or_target_el);
> >
> > "cur_or_target_el" is odd, because it's mixing what the architecture
> > sets up as two distinct things: the state the exception is
> > "taken from", and the state the exception is "taken to". I was
> > hoping this was just a temporary thing for the purposes of the
> > refactoring and it would go away near the end of the series, but
> > it doesn't seem to.
>
> No, sorry.  Most of the time it's cur_el, except from cpregs, where we get directed to a
> specific higher el.  There may be some way to split the helpers...
>
> I'll have another go at this reorg this week.  If it still doesn't feel cleaner, we can
> drop it, and I'll make some changes to the SME patch set building on this.

I was wondering if it would work better the other way around, so that
raise_exception() doesn't mess with the target_el at all, and all the
"work out which EL to take the exception to" is done in
target_exception_el() and similar ?

-- PMM
Richard Henderson May 30, 2022, 7:51 p.m. UTC | #4
On 5/30/22 12:01, Peter Maydell wrote:
>> I'll have another go at this reorg this week.  If it still doesn't feel cleaner, we can
>> drop it, and I'll make some changes to the SME patch set building on this.
> 
> I was wondering if it would work better the other way around, so that
> raise_exception() doesn't mess with the target_el at all, and all the
> "work out which EL to take the exception to" is done in
> target_exception_el() and similar ?

We need some place to put the EC_ADVSIMDFPACCESSTRAP special case, and it has to be done 
at the same time we're handling HCR_EL2.TGE.  Perhaps that can be separated out to its own 
helper.


r~
diff mbox series

Patch

diff --git a/target/arm/internals.h b/target/arm/internals.h
index b654bee468..03363b0f32 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -111,18 +111,19 @@  FIELD(DBGWCR, SSCE, 29, 1)
 /**
  * raise_exception: Raise the specified exception.
  * Raise a guest exception with the specified value, syndrome register
- * and target exception level. This should be called from helper functions,
- * and never returns because we will longjump back up to the CPU main loop.
+ * and the current or target exception level. This should be called from
+ * helper functions, and never returns because we will longjump back up
+ * to the CPU main loop.
  */
 G_NORETURN void raise_exception(CPUARMState *env, uint32_t excp,
-                                uint32_t syndrome, uint32_t target_el);
+                                uint32_t syndrome, uint32_t cur_or_target_el);
 
 /*
  * Similarly, but also use unwinding to restore cpu state.
  */
 G_NORETURN void raise_exception_ra(CPUARMState *env, uint32_t excp,
-                                      uint32_t syndrome, uint32_t target_el,
-                                      uintptr_t ra);
+                                   uint32_t syndrome,
+                                   uint32_t cur_or_target_el, uintptr_t ra);
 
 /*
  * For AArch64, map a given EL to an index in the banked_spsr array.
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index c4bd668870..6b9141b79a 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -28,10 +28,15 @@ 
 #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)
+void raise_exception(CPUARMState *env, uint32_t excp, uint32_t syndrome,
+                     uint32_t cur_or_target_el)
 {
     CPUState *cs = env_cpu(env);
+    int target_el = cur_or_target_el;
+
+    if (cur_or_target_el == 0) {
+        target_el = exception_target_el(env);
+    }
 
     if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
         /*
@@ -54,7 +59,7 @@  void raise_exception(CPUARMState *env, uint32_t excp,
 }
 
 void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
-                        uint32_t target_el, uintptr_t ra)
+                        uint32_t cur_or_target_el, uintptr_t ra)
 {
     CPUState *cs = env_cpu(env);
 
@@ -64,7 +69,7 @@  void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
      * the caller passed us, and cannot use cpu_loop_exit_restore().
      */
     cpu_restore_state(cs, ra, true);
-    raise_exception(env, excp, syndrome, target_el);
+    raise_exception(env, excp, syndrome, cur_or_target_el);
 }
 
 uint64_t HELPER(neon_tbl)(CPUARMState *env, uint32_t desc,