diff mbox series

target/sparc: Clear may_lookup for npc == DYNAMIC_PC

Message ID 20231015232454.391788-1-richard.henderson@linaro.org
State Superseded
Headers show
Series target/sparc: Clear may_lookup for npc == DYNAMIC_PC | expand

Commit Message

Richard Henderson Oct. 15, 2023, 11:24 p.m. UTC
With pairs of jmp+rett, pc == DYNAMIC_PC_LOOKUP and
npc == DYNAMIC_PC.  Make sure that we exit for interrupts.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---

Mark, I wonder if this will cure some of your lost interrupt issues.
Spotted while looking at issues from the JMPL+RETT+RETURN patch.

r~
---
 target/sparc/translate.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

Comments

Mark Cave-Ayland Oct. 16, 2023, 7:17 p.m. UTC | #1
On 16/10/2023 00:24, Richard Henderson wrote:

> With pairs of jmp+rett, pc == DYNAMIC_PC_LOOKUP and
> npc == DYNAMIC_PC.  Make sure that we exit for interrupts.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> 
> Mark, I wonder if this will cure some of your lost interrupt issues.
> Spotted while looking at issues from the JMPL+RETT+RETURN patch.
> 
> r~

Yes, I believe it does! I've just tried this on my Solaris 8 image and I no longer 
see any lockups when wiggling the mouse :)  Presumably this needs a CC: qemu-stable 
and a Fixes: tag along with:

Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

> ---
>   target/sparc/translate.c | 20 +++++++++++++++++---
>   1 file changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/target/sparc/translate.c b/target/sparc/translate.c
> index f92ff80ac8..8fabed28fd 100644
> --- a/target/sparc/translate.c
> +++ b/target/sparc/translate.c
> @@ -5654,10 +5654,10 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
>               break;
>           }
>   
> +        may_lookup = true;
>           if (dc->pc & 3) {
>               switch (dc->pc) {
>               case DYNAMIC_PC_LOOKUP:
> -                may_lookup = true;
>                   break;
>               case DYNAMIC_PC:
>                   may_lookup = false;
> @@ -5667,10 +5667,24 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
>               }
>           } else {
>               tcg_gen_movi_tl(cpu_pc, dc->pc);
> -            may_lookup = true;
>           }
>   
> -        save_npc(dc);
> +        if (dc->npc & 3) {
> +            switch (dc->npc) {
> +            case JUMP_PC:
> +                gen_generic_branch(dc);
> +                break;
> +            case DYNAMIC_PC:
> +                may_lookup = false;
> +                break;
> +            case DYNAMIC_PC_LOOKUP:
> +                break;
> +            default:
> +                g_assert_not_reached();
> +            }
> +        } else {
> +            tcg_gen_movi_tl(cpu_npc, dc->npc);
> +        }
>           if (may_lookup) {
>               tcg_gen_lookup_and_goto_ptr();
>           } else {


ATB,

Mark.
diff mbox series

Patch

diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index f92ff80ac8..8fabed28fd 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -5654,10 +5654,10 @@  static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
             break;
         }
 
+        may_lookup = true;
         if (dc->pc & 3) {
             switch (dc->pc) {
             case DYNAMIC_PC_LOOKUP:
-                may_lookup = true;
                 break;
             case DYNAMIC_PC:
                 may_lookup = false;
@@ -5667,10 +5667,24 @@  static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
             }
         } else {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
-            may_lookup = true;
         }
 
-        save_npc(dc);
+        if (dc->npc & 3) {
+            switch (dc->npc) {
+            case JUMP_PC:
+                gen_generic_branch(dc);
+                break;
+            case DYNAMIC_PC:
+                may_lookup = false;
+                break;
+            case DYNAMIC_PC_LOOKUP:
+                break;
+            default:
+                g_assert_not_reached();
+            }
+        } else {
+            tcg_gen_movi_tl(cpu_npc, dc->npc);
+        }
         if (may_lookup) {
             tcg_gen_lookup_and_goto_ptr();
         } else {