patch-2.1.96 linux/arch/i386/kernel/ldt.c
Next file: linux/arch/i386/kernel/process.c
Previous file: linux/arch/arm/vmlinux.lds
Back to the patch index
Back to the overall index
- Lines: 56
- Date:
Tue Apr 14 13:05:25 1998
- Orig file:
v2.1.95/linux/arch/i386/kernel/ldt.c
- Orig date:
Tue Mar 10 10:03:30 1998
diff -u --recursive --new-file v2.1.95/linux/arch/i386/kernel/ldt.c linux/arch/i386/kernel/ldt.c
@@ -18,7 +18,7 @@
static int read_ldt(void * ptr, unsigned long bytecount)
{
- void * address = current->ldt;
+ void * address = current->mm->segments;
unsigned long size;
if (!ptr)
@@ -37,6 +37,7 @@
{
struct modify_ldt_ldt_s ldt_info;
unsigned long *lp;
+ struct mm_struct * mm;
int error, i;
if (bytecount != sizeof(ldt_info))
@@ -48,19 +49,32 @@
if ((ldt_info.contents == 3 && (oldmode || ldt_info.seg_not_present == 0)) || ldt_info.entry_number >= LDT_ENTRIES)
return -EINVAL;
- if (!current->ldt) {
+ mm = current->mm;
+
+ /*
+ * Horrible dependencies! Try to get rid of this. This is wrong,
+ * as it only reloads the ldt for the first process with this
+ * mm. The implications are that you should really make sure that
+ * you have a ldt before you do the first clone(), otherwise
+ * you get strange behaviour (the kernel is safe, it's just user
+ * space strangeness).
+ *
+ * For no good reason except historical, the GDT index of the LDT
+ * is chosen to follow the index number in the task[] array.
+ */
+ if (!mm->segments) {
for (i=1 ; i<NR_TASKS ; i++) {
- if (task[i] == current) {
- if (!(current->ldt = (struct desc_struct*) vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE)))
+ if (task[i]->mm == mm) {
+ if (!(mm->segments = (void *) vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE)))
return -ENOMEM;
- memset(current->ldt, 0, LDT_ENTRIES*LDT_ENTRY_SIZE);
- set_ldt_desc(gdt+(i<<1)+FIRST_LDT_ENTRY, current->ldt, LDT_ENTRIES);
+ memset(mm->segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE);
+ set_ldt_desc(gdt+(i<<1)+FIRST_LDT_ENTRY, mm->segments, LDT_ENTRIES);
load_ldt(i);
}
}
}
- lp = (unsigned long *) ¤t->ldt[ldt_info.entry_number];
+ lp = (unsigned long *) (LDT_ENTRY_SIZE * ldt_info.entry_number + (unsigned long) mm->segments);
/* Allow LDTs to be cleared by the user. */
if (ldt_info.base_addr == 0 && ldt_info.limit == 0
&& (oldmode ||
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov