]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
target/ppc: Sign-extend large decrementer to 64-bits
authorNicholas Piggin <npiggin@gmail.com>
Tue, 8 Aug 2023 04:19:50 +0000 (14:19 +1000)
committerMichael Tokarev <mjt@tls.msk.ru>
Mon, 25 Sep 2023 20:43:49 +0000 (23:43 +0300)
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>
[ clg: removed extra cpu and pcc variables shadowing local variables ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit c8fbc6b9f2f3c732ee3307093c1c5c367eaa64ae)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
hw/ppc/ppc.c

index 9961abc50534d949ec0f93097f28127a2ed62b2a..5573ab467c41ed6417023a58043cd00c2d5a1d4e 100644 (file)
@@ -746,7 +746,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;
 }
@@ -765,7 +767,7 @@ 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;
+        return sextract64(hdecr, 0, pcc->lrg_decr_bits);
     }
     return (uint32_t) hdecr;
 }