Re: Linux Jobs as of 2.3.99pre6-5

From: Alan Cox (alan@lxorguk.ukuu.org.uk)
Date: Mon Apr 24 2000 - 20:31:25 EST


> I've never been able to verify this. As far as I know, the kernel
> handles %fs and %gs just right. You should re-check, and maybe try to
> make a test-case for what you think is incorrect behaviour..

Ulrich provided one a while back. I've not retried it on 2.3.99pre but
I include it below

#include <assert.h>
#include <fcntl.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#include <sys/poll.h>
#include <sys/wait.h>

char seg[4096];
char buf[16386];

#define show_gs(c) \
  { \
    char buf[10]; \
    int gs; \
    asm("movl %%gs,%0":"=g"(gs)); \
    buf[0]='g'; \
    buf[1]='s'; \
    buf[2]=c; \
    buf[3]='='; \
    buf[4]=((gs>>4)&0xf)>9?'a'+((gs>>4)&0x0f)-10:'0'+((gs>>4)&0xf); \
    buf[5]=(gs&0xf)>9?'a'+(gs&0xf)-10:'0'+(gs&0xf); \
    buf[6]='\n'; \
    write(2,buf,7); \
  }

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;
};

static int
fn (void *arg)
{
  sleep (1);
  _exit (0);
}

void
catch (int sig)
{
  unsigned char c;

#if 0
  asm ("movb %%gs:0,%b0" : "=r" (c));

  assert (c == 0);
#endif
}

int
main (void)
{
  int fd = open ("/dev/null", O_RDONLY);
  struct pollfd ufd;
  struct modify_ldt_ldt_s ldt_entry;
  struct sigaction sa;

  ufd.fd = fd;
  ufd.events = POLLIN;

  ldt_entry.entry_number = 0;
  ldt_entry.base_addr = (long int) seg;
  ldt_entry.limit = sizeof (seg);
  ldt_entry.seg_32bit = 1;
  ldt_entry.contents = 0;
  ldt_entry.read_exec_only = 0;
  ldt_entry.limit_in_pages = 0;
  ldt_entry.seg_not_present = 0;
  ldt_entry.useable = 1;
  ldt_entry.empty = 0;

  modify_ldt (1, &ldt_entry, sizeof (ldt_entry));

  asm volatile ("movw %w0,%%gs" : : "r" (7));

  sa.sa_handler = catch;
  sa.sa_flags = 9;
  sigemptyset (&sa.sa_mask);
  sigaddset (&sa.sa_mask, SIGCHLD);
  sigaction (SIGCHLD, &sa, NULL);

  while (1)
    {
      unsigned char c;
      int s;
      int p;

      show_gs ('1');

      p = clone (fn, buf + sizeof buf,
                 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGRTMIN,
                 NULL);

      show_gs ('2');

      poll (&ufd, 1, 2000);

      show_gs ('3');

      asm ("movb %%gs:0,%b0" : "=r" (c));

      show_gs ('4');

      if (c != 0)
        abort ();

      waitpid (p, &s, WNOHANG | __WCLONE);

      show_gs ('5');
    }

  return 0;
}

-
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/

-
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 : Sun Apr 30 2000 - 21:00:08 EST