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 >