2.4.0-tes6 broke %gs handling again (x86 of course)

From: Ulrich Drepper (drepper@redhat.com)
Date: Sat Aug 12 2000 - 14:47:31 EST


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