[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



Here is a test from Ulrich Drepper that Jeff Garzik pointed out to me.
It would be a good thing to add, but I'm not sure where it should be put
in the tree.  

The test is supposed to show a bug in 2.4.0-test6.  I don't think tests
like this have a place yet in the tree and they should.  I would suggest
a directory such as "bugs" which can be divided more as more of these
tests are created and submitted.  

Toughts?

-- 
Nate Straz                                              nstraz@sgi.com
sgi, inc                                           http://www.sgi.com/
Linux Test Project                    http://oss.sgi.com/projects/ltp/

----- Forwarded message from Jeff Garzik <jgarzik@mandrakesoft.com> -----

Date: Sat, 12 Aug 2000 16:00:27 -0400
From: Jeff Garzik <jgarzik@mandrakesoft.com>
Organization: MandrakeSoft
To: Nathan Straz <nstraz@sgi.com>
Subject: [Fwd: 2.4.0-tes6 broke %gs handling again (x86 of course)]


-- 
Jeff Garzik              |
Building 1024            | Andre the Giant has a posse.
MandrakeSoft, Inc.       |
To: VGER kernel list <linux-kernel@vger.rutgers.edu>
Cc: Linus Torvalds <torvalds@transmeta.com>
Subject: 2.4.0-tes6 broke %gs handling again (x86 of course)
Reply-To: drepper@cygnus.com (Ulrich Drepper)
From: Ulrich Drepper <drepper@redhat.com>
Date: 	12 Aug 2000 12:47:31 -0700
User-Agent: Gnus/5.0807 (Gnus v5.8.7) XEmacs/21.1 (Capitol Reef)

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/


----- End forwarded message -----