diff mbox series

[v1,2/2] target/microblaze: Improve transaction failure handling

Message ID 20200828113931.3252489-3-edgar.iglesias@gmail.com (mailing list archive)
State New, archived
Headers show
Series target/microblaze: Improve bus fault handling | expand

Commit Message

Edgar E. Iglesias Aug. 28, 2020, 11:39 a.m. UTC
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

When the CPU has exceptions disabled, avoid unwinding CPU
state and clobbering registers if we're not going to raise
any exception.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 target/microblaze/op_helper.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

Comments

Luc Michel Aug. 28, 2020, 1:04 p.m. UTC | #1
On 8/28/20 1:39 PM, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
> 
> When the CPU has exceptions disabled, avoid unwinding CPU
> state and clobbering registers if we're not going to raise
> any exception.
> 
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>

Reviewed-by: Luc Michel <luc.michel@greensocs.com>

> ---
>   target/microblaze/op_helper.c | 19 +++++++------------
>   1 file changed, 7 insertions(+), 12 deletions(-)
> 
> diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
> index 13ac476199..190cd96c6a 100644
> --- a/target/microblaze/op_helper.c
> +++ b/target/microblaze/op_helper.c
> @@ -483,22 +483,17 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
>       cpu = MICROBLAZE_CPU(cs);
>       env = &cpu->env;
>   
> -    cpu_restore_state(cs, retaddr, true);
>       if (!(env->sregs[SR_MSR] & MSR_EE)) {
>           return;
>       }
>   
> -    env->sregs[SR_EAR] = addr;
> -    if (access_type == MMU_INST_FETCH) {
> -        if (cpu->cfg.iopb_bus_exception) {
> -            env->sregs[SR_ESR] = ESR_EC_INSN_BUS;
> -            helper_raise_exception(env, EXCP_HW_EXCP);
> -        }
> -    } else {
> -        if (cpu->cfg.dopb_bus_exception) {
> -            env->sregs[SR_ESR] = ESR_EC_DATA_BUS;
> -            helper_raise_exception(env, EXCP_HW_EXCP);
> -        }
> +    if ((access_type == MMU_INST_FETCH && cpu->cfg.iopb_bus_exception) ||
> +        (access_type != MMU_INST_FETCH && cpu->cfg.dopb_bus_exception)) {
> +        cpu_restore_state(cs, retaddr, true);
> +        env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ?
> +                             ESR_EC_INSN_BUS : ESR_EC_DATA_BUS;
> +        env->sregs[SR_EAR] = addr;
> +        helper_raise_exception(env, EXCP_HW_EXCP);
>       }
>   }
>   #endif
>
Alistair Francis Aug. 28, 2020, 6:46 p.m. UTC | #2
On Fri, Aug 28, 2020 at 4:41 AM Edgar E. Iglesias
<edgar.iglesias@gmail.com> wrote:
>
> From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
>
> When the CPU has exceptions disabled, avoid unwinding CPU
> state and clobbering registers if we're not going to raise
> any exception.
>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/microblaze/op_helper.c | 19 +++++++------------
>  1 file changed, 7 insertions(+), 12 deletions(-)
>
> diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
> index 13ac476199..190cd96c6a 100644
> --- a/target/microblaze/op_helper.c
> +++ b/target/microblaze/op_helper.c
> @@ -483,22 +483,17 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
>      cpu = MICROBLAZE_CPU(cs);
>      env = &cpu->env;
>
> -    cpu_restore_state(cs, retaddr, true);
>      if (!(env->sregs[SR_MSR] & MSR_EE)) {
>          return;
>      }
>
> -    env->sregs[SR_EAR] = addr;
> -    if (access_type == MMU_INST_FETCH) {
> -        if (cpu->cfg.iopb_bus_exception) {
> -            env->sregs[SR_ESR] = ESR_EC_INSN_BUS;
> -            helper_raise_exception(env, EXCP_HW_EXCP);
> -        }
> -    } else {
> -        if (cpu->cfg.dopb_bus_exception) {
> -            env->sregs[SR_ESR] = ESR_EC_DATA_BUS;
> -            helper_raise_exception(env, EXCP_HW_EXCP);
> -        }
> +    if ((access_type == MMU_INST_FETCH && cpu->cfg.iopb_bus_exception) ||
> +        (access_type != MMU_INST_FETCH && cpu->cfg.dopb_bus_exception)) {
> +        cpu_restore_state(cs, retaddr, true);
> +        env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ?
> +                             ESR_EC_INSN_BUS : ESR_EC_DATA_BUS;
> +        env->sregs[SR_EAR] = addr;
> +        helper_raise_exception(env, EXCP_HW_EXCP);
>      }
>  }
>  #endif
> --
> 2.25.1
>
>
Richard Henderson Aug. 28, 2020, 8:34 p.m. UTC | #3
On 8/28/20 4:39 AM, Edgar E. Iglesias wrote:
> +    if ((access_type == MMU_INST_FETCH && cpu->cfg.iopb_bus_exception) ||
> +        (access_type != MMU_INST_FETCH && cpu->cfg.dopb_bus_exception)) {
> +        cpu_restore_state(cs, retaddr, true);
> +        env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ?
> +                             ESR_EC_INSN_BUS : ESR_EC_DATA_BUS;
> +        env->sregs[SR_EAR] = addr;
> +        helper_raise_exception(env, EXCP_HW_EXCP);

I think it's better to use cpu_loop_exit_restore, adding the one line for
cs->exception_index from helper_raise_exception.


r~
Edgar E. Iglesias Aug. 31, 2020, 12:41 p.m. UTC | #4
On Fri, Aug 28, 2020 at 01:34:08PM -0700, Richard Henderson wrote:
> On 8/28/20 4:39 AM, Edgar E. Iglesias wrote:
> > +    if ((access_type == MMU_INST_FETCH && cpu->cfg.iopb_bus_exception) ||
> > +        (access_type != MMU_INST_FETCH && cpu->cfg.dopb_bus_exception)) {
> > +        cpu_restore_state(cs, retaddr, true);
> > +        env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ?
> > +                             ESR_EC_INSN_BUS : ESR_EC_DATA_BUS;
> > +        env->sregs[SR_EAR] = addr;
> > +        helper_raise_exception(env, EXCP_HW_EXCP);
> 
> I think it's better to use cpu_loop_exit_restore, adding the one line for
> cs->exception_index from helper_raise_exception.
> 

OK, let's use the patch you posted:

https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg07630.html

Thanks,
Edgar
diff mbox series

Patch

diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index 13ac476199..190cd96c6a 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -483,22 +483,17 @@  void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
     cpu = MICROBLAZE_CPU(cs);
     env = &cpu->env;
 
-    cpu_restore_state(cs, retaddr, true);
     if (!(env->sregs[SR_MSR] & MSR_EE)) {
         return;
     }
 
-    env->sregs[SR_EAR] = addr;
-    if (access_type == MMU_INST_FETCH) {
-        if (cpu->cfg.iopb_bus_exception) {
-            env->sregs[SR_ESR] = ESR_EC_INSN_BUS;
-            helper_raise_exception(env, EXCP_HW_EXCP);
-        }
-    } else {
-        if (cpu->cfg.dopb_bus_exception) {
-            env->sregs[SR_ESR] = ESR_EC_DATA_BUS;
-            helper_raise_exception(env, EXCP_HW_EXCP);
-        }
+    if ((access_type == MMU_INST_FETCH && cpu->cfg.iopb_bus_exception) ||
+        (access_type != MMU_INST_FETCH && cpu->cfg.dopb_bus_exception)) {
+        cpu_restore_state(cs, retaddr, true);
+        env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ?
+                             ESR_EC_INSN_BUS : ESR_EC_DATA_BUS;
+        env->sregs[SR_EAR] = addr;
+        helper_raise_exception(env, EXCP_HW_EXCP);
     }
 }
 #endif