On 11/18/21 18:03, John David Anglin wrote: > The extru instruction leaves the most significant 32 bits of the target register in an undefined > state on PA 2.0 systems. If any of these bits are nonzero, this will break the calculation of the > lock pointer. > > Fix by using extrd,u instruction on 64-bit kernels. Good catch!! Did you checked if it actually happened that the most significant 32 bits were non-zero? If so, could this be one of the reasons we saw strange issues or even memory corruption? Sadly I sent a pull request to Linus a few hours ago, otherwise I would have added this patch... Helge > Signed-off-by: John David Anglin <dave.anglin@xxxxxxxx> > --- > diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S > index 3f24a0af1e04..3f70528622eb 100644 > --- a/arch/parisc/kernel/syscall.S > +++ b/arch/parisc/kernel/syscall.S > @@ -572,7 +572,11 @@ lws_compare_and_swap: > ldo R%lws_lock_start(%r20), %r28 > > /* Extract eight bits from r26 and hash lock (Bits 3-11) */ > +#ifdef CONFIG_64BIT > + extrd,u %r26, 60, 8, %r20 > +#else > extru %r26, 28, 8, %r20 > +#endif > > /* Find lock to use, the hash is either one of 0 to > 15, multiplied by 16 (keep it 16-byte aligned) > @@ -762,7 +761,11 @@ cas2_lock_start: > ldo R%lws_lock_start(%r20), %r28 > > /* Extract eight bits from r26 and hash lock (Bits 3-11) */ > +#ifdef CONFIG_64BIT > + extrd,u %r26, 60, 8, %r20 > +#else > extru %r26, 28, 8, %r20 > +#endif > > /* Find lock to use, the hash is either one of 0 to > 15, multiplied by 16 (keep it 16-byte aligned)