Re: alpha: potential race around hae_cache in RESTORE_ALL

From: Al Viro
Date: Sat Sep 25 2010 - 15:19:17 EST


On Sat, Sep 25, 2010 at 11:42:41AM -0700, Linus Torvalds wrote:
> Ok, so it's been absolutely ages since I touched the HAE stuff, but I
> think the logic was that interrupts will always restore HAE to the
> pre-interrupt state on exit, so reading it was always supposedly
> race-free and didn't need any protection from normal code.
>
> But yes, any actual _changes_ to HAE had better protect against
> interrupts, so that they don't see the half-done state.
>
> So yes, I think you found a bug.
>
> I also don't see why that crazy RESTORE_ALL code does that reload of
> $0 and $1 when it updates HAE. Is that just legacy from it having
> _used_ to do the swipl PAL-call and that trashed those registers?

Looks like... swpipl takes argument in $16 and returns value in $0;
trashes $1, $16, $22--$25. Out of those, RESTORE_ALL deals with $22--$25
later in the sequence and $16 it handled by rti.

> Anyway, I think the fix should be that we really always do have
> interrupts disabled in RESTORE_ALL, rather than re-introduce the swipl
> into the RESTORE_ALL sequence. A lot of the critical sequences already
> do that - notably the normal return-to-user space code sequence that
> is the really critical one.

Agreed. There are only two places that need change (return to kernel path
in ret_from_syscall and kernel_thread essentially jumping to the same path),
so I'll just add
ret_to_kernel:
lda $16, 7
call_pal PAL_swpipl
br restore_all
and make these two places go to ret_to_kernel instead of restore_all.

BTW, another bug on alpha: coredump puts rdusp() result into regsets for
_all_ threads. Should be ti->pcb.usp for everything except current, a-la
KSTK_ESP logics...

I'll send fixes shortly
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/