the segment registers are just indices to the kernels descriptor tables.
setting the segment registers can be done with assembly instructions from 
userspace. but what you need is being able to modify the descriptors in
a save way from userspace!

i needed this for linuxemu to implement set_thread_area syscalls
under plan9 so i made the modifications to the kernel:

/n/sources/contrib/cinap_lenrek/segdescpatch

it adds the files ldt and gdt to devarch.

heres a linuxemu process where glibc has setup a special descriptor
and loaded %gs to point to it under plan9:

cat /dev/gdt
000b data     WPUBG    3 1819c080 fffff
000c data     -        0 00000000 00000
000d data     -        0 00000000 00000

PC      0x00020439 pread+0x7  /sys/src/libc/9syscall/pread.s:5
SP      0xdeffcd70 ECODE 0xf010080c EFLAG 0x00000286
CS      0x00000023 DS    0x0000001b SS  0x0000001b
GS      0x0000005b FS    0x00000000 ES  0x0000001b
TRAP    0x00000040 system call
AX      0x00000032 BX   0x00032b4c CX   0x00000001 DX   0x00000000
DI      0x080e7468 SI   0x00000000 BP   0xdeffcf2c

format of is simple text:

/*
 * format:
 * idx[4] type[8] flags[8] dpl[1] base[8] limit[5]\n
 */

idx is the descriptor index (the one you load into a segment registers by the 
selector)
type is code or data
dpl is the priority level (usualy just 3 for userspace)
base and limit describe the location of the segment (limit is in pages if G 
flag is set)

/*
 * flags:
 * P = present
 * A = accessed (for code/data)
 * E = expand down (for data)
 * W = writable (for data)
 * R = readable (for code)
 * C = conforming (for code)
 * G = limit granularity in pages (for code/data)
 * D = 32 bit operand size (for code)
 * B = 32 bit stack pointer (for data)
 * Y = busy (for tss and tss16)
 * U = available for use by system software
 */

gdt and ldt are both per process.  the only difference between gdt and
ldt is that gdt has a small fixed number of descriptors in the gdt
that you can modify.  the ldt refers to the local descriptor table
wich can have up to 2^13 user descriptors.

--
cinap
--- Begin Message ---
Can someone remind me of the problem? Is it simply the need to be able
to set %gs?

Could a write to /dev/arch of something like
gs 0xwhatever
which sets %gs for that process solve the problem?

Or is it bigger than that?

ron

--- End Message ---

Reply via email to