Ever since the %gs handling was fixed in the 2.3.99 series the
appended test program worked. Now with 2.4.0-test6 it's not working
again. Looking briefly over the patch from test5 to test6 I haven't
seen an immediate candidate for the breakage. It could be missing
propagation of the LDT to the new process (and therefore an invalid
segment descriptor) or simply clearing %gs.
Anyway, this is what you should see and what you get with test5:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a = 42
%gs = 0x0007
%gs = 0x0007
a = 99
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is what you get with test6:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a = 42
%gs = 0x0007
%gs = 0x0000
<SEGFAULT>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If somebody is actually creating a test suite for the kernel, please
add this program. It's mostly self-contained. The correct handling
of %gs is really important since glibc 2.2 will make heavy use of it.
-- ---------------. ,-. 1325 Chesapeake Terrace Ulrich Drepper \ ,-------------------' \ Sunnyvale, CA 94089 USA Red Hat `--' drepper at redhat.com `------------------------~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include <unistd.h>
struct modify_ldt_ldt_s { unsigned int entry_number; unsigned long int base_addr; unsigned int limit; unsigned int seg_32bit:1; unsigned int contents:2; unsigned int read_exec_only:1; unsigned int limit_in_pages:1; unsigned int seg_not_present:1; unsigned int useable:1; unsigned int empty:25; };
asm(" .type modify_ldt,@function modify_ldt: push %ebx mov 0x10(%esp,1),%edx mov 0xc(%esp,1),%ecx mov 0x8(%esp,1),%ebx mov $0x7b,%eax int $0x80 pop %ebx ret");
int a = 42;
int main () { struct modify_ldt_ldt_s ldt0; int lo; pid_t pid; int res;
ldt0.entry_number = 0; ldt0.base_addr = (long) &a; ldt0.limit = 4; ldt0.seg_32bit = 1; ldt0.contents = 0; ldt0.read_exec_only = 0; ldt0.limit_in_pages = 0; ldt0.seg_not_present = 0; ldt0.useable = 1; ldt0.empty = 0;
modify_ldt (1, &ldt0, sizeof (ldt0));
asm ("movw %w0, %%gs" : : "q" (7));
asm ("movl %%gs:0, %0" : "=r" (lo)); printf ("a = %d\n", lo);
asm ("pushl %%gs; popl %0" : "=q" (lo)); printf ("%%gs = %#06hx\n", lo);
asm ("movl %0, %%gs:0" : : "r" (99));
pid = fork (); if (pid == 0) { asm ("pushl %%gs; popl %0" : "=q" (lo)); printf ("%%gs = %#06hx\n", lo);
asm ("movl %%gs:0, %0" : "=r" (lo)); printf ("a = %d\n", lo);
exit (lo != 99); }
waitpid (pid, &res);
return res; }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Tue Aug 15 2000 - 21:00:28 EST