From: Helge Deller <[email protected]> While adding hppa64 support, the psw_v variable got extended from 32 to 64 bits. So, when packaging the PSW-V bit from the psw_v variable for interrupt processing, check bit 31 instead the 63th (sign) bit.
This fixes a hard to find Linux kernel boot issue where the loss of the PSW-V bit due to an ITLB interruption in the middle of a series of ds/addc instructions (from the divU milicode library) generated the wrong division result and thus triggered a Linux kernel crash. Link: https://lore.kernel.org/lkml/[email protected]/ Reported-by: Guenter Roeck <[email protected]> Signed-off-by: Helge Deller <[email protected]> Reviewed-by: Richard Henderson <[email protected]> Tested-by: Guenter Roeck <[email protected]> Fixes: 931adff31478 ("target/hppa: Update cpu_hppa_get/put_psw for hppa64") Cc: [email protected] # v8.2+ --- target/hppa/cpu.h | 2 +- target/hppa/helper.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 2bcb3b602b..5478b183dc 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -211,7 +211,7 @@ typedef struct CPUArchState { uint32_t psw; /* All psw bits except the following: */ uint32_t psw_xb; /* X and B, in their normal positions */ target_ulong psw_n; /* boolean */ - target_long psw_v; /* in most significant bit */ + target_long psw_v; /* in bit 31 */ /* Splitting the carry-borrow field into the MSB and "the rest", allows * for "the rest" to be deleted when it is unused, but the MSB is in use. diff --git a/target/hppa/helper.c b/target/hppa/helper.c index b79ddd8184..d4b1a3cd5a 100644 --- a/target/hppa/helper.c +++ b/target/hppa/helper.c @@ -53,7 +53,7 @@ target_ulong cpu_hppa_get_psw(CPUHPPAState *env) } psw |= env->psw_n * PSW_N; - psw |= (env->psw_v < 0) * PSW_V; + psw |= ((env->psw_v >> 31) & 1) * PSW_V; psw |= env->psw | env->psw_xb; return psw; -- 2.46.0
