I can see what the problem is now.
The kernel assumes that if current->mm->segments == NULL then the
ldt points to the default ldt. But when release_segments() is called
it is setting current->mm->segments to NULL and setting the ldt to 0.
Patch follows.
BTW can some one please tell me why the modify_ldt system call does not
copy over the default ldt when it sets up a new ldt?
regards
David Bruce.
--- linux/arch/i386/kernel/process.c.org Tue Jul 21 01:22:35 1998
+++ linux/arch/i386/kernel/process.c Tue Aug 11 11:41:09 1998
@@ -476,27 +476,30 @@
} else
free_pages((unsigned long) p, 1);
}
void release_segments(struct mm_struct *mm)
{
- void * ldt = mm->segments;
- int nr;
/* forget local segments */
- __asm__ __volatile__("movl %w0,%%fs ; movl %w0,%%gs ; lldt %w0"
+ __asm__ __volatile__("movl %w0,%%fs ; movl %w0,%%gs"
: /* no outputs */
: "r" (0));
current->tss.ldt = 0;
- /*
- * Set the GDT entry back to the default.
- */
- nr = current->tarray_ptr - &task[0];
- set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY, &default_ldt, 1);
- if (ldt) {
+ if (mm->segments) {
+ void * ldt = mm->segments;
+ int nr;
+
+ /*
+ * Set the GDT entry back to the default.
+ */
+ nr = current->tarray_ptr - &task[0];
+ set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY, &default_ldt, 1);
+ load_ldt(0);
+
mm->segments = NULL;
vfree(ldt);
}
}
/*
-
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.altern.org/andrebalsa/doc/lkml-faq.html