> 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