[PATCH v2 08/19] target/ppc: Sign-extend large decrementer to 64-bits

Nicholas Piggin posted 19 patches 1 year, 3 months ago
[PATCH v2 08/19] target/ppc: Sign-extend large decrementer to 64-bits
Posted by Nicholas Piggin 1 year, 3 months ago
When storing a large decrementer value with the most significant
implemented bit set, it is to be treated as a negative and sign
extended.

This isn't hit for book3s DEC because of another bug, fixing it
in the next patch exposes this one and can cause additional
problems, so fix this first. It can be hit with HDECR and other
edge triggered types.

Fixes: a8dafa52518 ("target/ppc: Implement large decrementer support for TCG")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 hw/ppc/ppc.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index a397820d9c..fb4784793c 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -743,7 +743,9 @@ target_ulong cpu_ppc_load_decr(CPUPPCState *env)
      * to 64 bits, otherwise it is a 32 bit value.
      */
     if (env->spr[SPR_LPCR] & LPCR_LD) {
-        return decr;
+        PowerPCCPU *cpu = env_archcpu(env);
+        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+        return sextract64(decr, 0, pcc->lrg_decr_bits);
     }
     return (uint32_t) decr;
 }
@@ -762,7 +764,9 @@ target_ulong cpu_ppc_load_hdecr(CPUPPCState *env)
      * extended to 64 bits, otherwise it is 32 bits.
      */
     if (pcc->lrg_decr_bits > 32) {
-        return hdecr;
+        PowerPCCPU *cpu = env_archcpu(env);
+        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+        return sextract64(hdecr, 0, pcc->lrg_decr_bits);
     }
     return (uint32_t) hdecr;
 }
-- 
2.40.1
Re: [PATCH v2 08/19] target/ppc: Sign-extend large decrementer to 64-bits
Posted by Cédric Le Goater 1 year, 2 months ago
Nick,

On 8/8/23 06:19, Nicholas Piggin wrote:
> When storing a large decrementer value with the most significant
> implemented bit set, it is to be treated as a negative and sign
> extended.
> 
> This isn't hit for book3s DEC because of another bug, fixing it
> in the next patch exposes this one and can cause additional
> problems, so fix this first. It can be hit with HDECR and other
> edge triggered types.
> 
> Fixes: a8dafa52518 ("target/ppc: Implement large decrementer support for TCG")
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
>   hw/ppc/ppc.c | 8 ++++++--
>   1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
> index a397820d9c..fb4784793c 100644
> --- a/hw/ppc/ppc.c
> +++ b/hw/ppc/ppc.c
> @@ -743,7 +743,9 @@ target_ulong cpu_ppc_load_decr(CPUPPCState *env)
>        * to 64 bits, otherwise it is a 32 bit value.
>        */
>       if (env->spr[SPR_LPCR] & LPCR_LD) {
> -        return decr;
> +        PowerPCCPU *cpu = env_archcpu(env);
> +        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
> +        return sextract64(decr, 0, pcc->lrg_decr_bits);
>       }
>       return (uint32_t) decr;
>   }
> @@ -762,7 +764,9 @@ target_ulong cpu_ppc_load_hdecr(CPUPPCState *env)
>        * extended to 64 bits, otherwise it is 32 bits.
>        */
>       if (pcc->lrg_decr_bits > 32) {
> -        return hdecr;
> +        PowerPCCPU *cpu = env_archcpu(env);
> +        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);

Why are 'cpu' and 'ppc' duplicated ?

Thanks,

C.


> +        return sextract64(hdecr, 0, pcc->lrg_decr_bits);
>       }
>       return (uint32_t) hdecr;
>   }
Re: [PATCH v2 08/19] target/ppc: Sign-extend large decrementer to 64-bits
Posted by Nicholas Piggin 1 year, 2 months ago
On Fri Sep 1, 2023 at 10:25 PM AEST, Cédric Le Goater wrote:
> Nick,
>
> On 8/8/23 06:19, Nicholas Piggin wrote:
> > When storing a large decrementer value with the most significant
> > implemented bit set, it is to be treated as a negative and sign
> > extended.
> > 
> > This isn't hit for book3s DEC because of another bug, fixing it
> > in the next patch exposes this one and can cause additional
> > problems, so fix this first. It can be hit with HDECR and other
> > edge triggered types.
> > 
> > Fixes: a8dafa52518 ("target/ppc: Implement large decrementer support for TCG")
> > Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> > ---
> >   hw/ppc/ppc.c | 8 ++++++--
> >   1 file changed, 6 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
> > index a397820d9c..fb4784793c 100644
> > --- a/hw/ppc/ppc.c
> > +++ b/hw/ppc/ppc.c
> > @@ -743,7 +743,9 @@ target_ulong cpu_ppc_load_decr(CPUPPCState *env)
> >        * to 64 bits, otherwise it is a 32 bit value.
> >        */
> >       if (env->spr[SPR_LPCR] & LPCR_LD) {
> > -        return decr;
> > +        PowerPCCPU *cpu = env_archcpu(env);
> > +        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
> > +        return sextract64(decr, 0, pcc->lrg_decr_bits);
> >       }
> >       return (uint32_t) decr;
> >   }
> > @@ -762,7 +764,9 @@ target_ulong cpu_ppc_load_hdecr(CPUPPCState *env)
> >        * extended to 64 bits, otherwise it is 32 bits.
> >        */
> >       if (pcc->lrg_decr_bits > 32) {
> > -        return hdecr;
> > +        PowerPCCPU *cpu = env_archcpu(env);
> > +        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>
> Why are 'cpu' and 'ppc' duplicated ?

Hmm.. cut and paste bug maybe, good catch.

I'll send an increment to tidy it if needed.

Thanks,
Nick