[parisc-linux] a todo entry
John Marvin
jsm@udlkern.fc.hp.com
Fri, 5 Oct 2001 03:03:25 -0600 (MDT)
> This is rather suboptimal. The way it should be done is to always
> access userspace through %sr2 (currently listed as unused). Set sr2
> to the same value as sr3 normally. Set it to 0 when someone does a
> set_fs(KERNEL_DS), and to sr3 when USER_DS. get_fs() should return the
> value of sr2. None of these functions are called frequently, so there's
> no need to cache the values outside the space registers.
>
> This probably isn't a big job, but there's probably some subtlety I've
> overlooked.
The subtlety you overlooked is that although sr2 has no current use
in kernel space, it has to be set to 0 while in user space, because
sr2 is used as a pointer to the linux gateway page for system calls.
Right now we initialize it to zero once for the process and save and
restore it on context switches, i.e. a program will only mess itself
up if it changes the value.
I am almost certain that linux never goes to user space while fs is
set to KERNEL_DS. In general fs is normally set to USER_DS, and
only set to KERNEL_DS for a short period of time, and then restored.
However, I do believe it is possible to sleep while fs is set to
KERNEL_DS.
Anyway, perhaps you were already aware of this. It means that you can't
just set sr2 once from sr3, you need to set it every time sr3 is set,
i.e. upon entry to the kernel, at fork/exec time (add one line to
load_context() in pgalloc.h). It also means that sr2 needs to be set
back to zero when returning to user space (through a variety of paths).
Also, in order for set_fs(old_fs) to work correctly you need to do
either:
1) Set sr2 to 0 when the argument to set_fs is KERNEL_DS, and KERNEL_DS
must be defined as 0 (it is currently). Set sr2 to sr3 when the
argument is any non-zero value. get_fs can then return the value of
sr2.
2) Set sr2 to 0 when the argument to set_fs is KERNEL_DS. Set sr2
to sr3 when the argument is USER_DS. get_fs should return KERNEL_DS
if sr2 is 0. get_fs should return USER_DS otherwise. I prefer this.
John