On Thu, Feb 15, 2024 at 09:34:15PM -0800, Guenter Roeck wrote:
> Unaligned 64-bit accesses were found in Linux to clobber carry bits,
> resulting in bad results if an arithmetic operation involving a
> carry bit was executed after an unaligned 64-bit operation.
> 
> hppa 2.0 defines additional carry bits in PSW register bits 32..39.
> When restoring PSW after executing an unaligned instruction trap,
> those bits were not cleared and ended up to be active all the time.
> Clearing bit 32..39 in psw prior to restoring it solves the problem.
> 
> Fixes: 931adff31478 ("target/hppa: Update cpu_hppa_get/put_psw for hppa64")
> Cc: Richard Henderson <richard.hender...@linaro.org>
> Cc: Charlie Jenkins <char...@rivosinc.com>
> Cc: Helge Deller <del...@gmx.de>
> Signed-off-by: Guenter Roeck <li...@roeck-us.net>
> ---
>  target/hppa/helper.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/target/hppa/helper.c b/target/hppa/helper.c
> index 859644c47a..7b798d1227 100644
> --- a/target/hppa/helper.c
> +++ b/target/hppa/helper.c
> @@ -76,7 +76,12 @@ void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong psw)
>      }
>      psw &= ~reserved;
>  
> -    env->psw = psw & ~(PSW_N | PSW_V | PSW_CB);
> +    if (hppa_is_pa20(env)) {
> +        env->psw = psw & ~(PSW_N | PSW_V | PSW_CB | 0xff00000000ull);

I thought there was something fishy in this function but was slow on the
uptake...

How about defining a new macro (PSW_CB_HIGH) to hold this value?

- Charlie

> +    } else {
> +        env->psw = psw & ~(PSW_N | PSW_V | PSW_CB);
> +    }
> +
>      env->psw_n = (psw / PSW_N) & 1;
>      env->psw_v = -((psw / PSW_V) & 1);
>  
> -- 
> 2.39.2
> 

Reply via email to