diff -u --recursive --new-file v2.4.0-test12/linux/arch/i386/kernel/ldt.c linux/arch/i386/kernel/ldt.c --- v2.4.0-test12/linux/arch/i386/kernel/ldt.c Sat May 20 10:39:58 2000 +++ linux/arch/i386/kernel/ldt.c Fri Dec 15 13:01:59 2000 @@ -31,7 +31,7 @@ struct mm_struct * mm = current->mm; err = 0; - if (!mm->segments) + if (!mm->context.segments) goto out; size = LDT_ENTRIES*LDT_ENTRY_SIZE; @@ -39,7 +39,7 @@ size = bytecount; err = size; - if (copy_to_user(ptr, mm->segments, size)) + if (copy_to_user(ptr, mm->context.segments, size)) err = -EFAULT; out: return err; @@ -87,13 +87,12 @@ * limited by MAX_LDT_DESCRIPTORS. */ down(&mm->mmap_sem); - if (!mm->segments) { - + if (!mm->context.segments) { error = -ENOMEM; - mm->segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); - if (!mm->segments) + mm->context.segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); + if (!mm->context.segments) goto out_unlock; - memset(mm->segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE); + memset(mm->context.segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE); if (atomic_read(&mm->mm_users) > 1) printk(KERN_WARNING "LDT allocated for cloned task!\n"); @@ -104,7 +103,7 @@ load_LDT(mm); } - lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->segments); + lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.segments); /* Allow LDTs to be cleared by the user. */ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { diff -u --recursive --new-file v2.4.0-test12/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.4.0-test12/linux/arch/i386/kernel/process.c Mon Dec 11 17:59:43 2000 +++ linux/arch/i386/kernel/process.c Fri Dec 15 15:37:09 2000 @@ -412,15 +412,15 @@ /* * No need to lock the MM as we are the last user */ -void release_segments(struct mm_struct *mm) +void destroy_context(struct mm_struct *mm) { - void * ldt = mm->segments; + void * ldt = mm->context.segments; /* * free the LDT */ if (ldt) { - mm->segments = NULL; + mm->context.segments = NULL; clear_LDT(); vfree(ldt); } @@ -478,7 +478,7 @@ void release_thread(struct task_struct *dead_task) { if (dead_task->mm) { - void * ldt = dead_task->mm->segments; + void * ldt = dead_task->mm->context.segments; // temporary debugging check if (ldt) { @@ -493,29 +493,24 @@ * we do not have to muck with descriptors here, that is * done in switch_mm() as needed. */ -void copy_segments(struct task_struct *p, struct mm_struct *new_mm) +int init_new_context(struct task_struct *p, struct mm_struct *new_mm) { - struct mm_struct * old_mm = current->mm; - void * old_ldt = old_mm->segments, * ldt; + struct mm_struct * old_mm; + void *old_ldt, *ldt; - if (!old_ldt) { + ldt = NULL; + old_mm = current->mm; + if (old_mm && (old_ldt = old_mm->context.segments) != NULL) { /* - * default LDT - use the one from init_task + * Completely new LDT, we initialize it from the parent: */ - new_mm->segments = NULL; - return; - } - - /* - * Completely new LDT, we initialize it from the parent: - */ - ldt = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); - if (!ldt) - printk(KERN_WARNING "ldt allocation failed\n"); - else + ldt = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); + if (!ldt) + return -ENOMEM; memcpy(ldt, old_ldt, LDT_ENTRIES*LDT_ENTRY_SIZE); - new_mm->segments = ldt; - return; + } + new_mm->context.segments = ldt; + return 0; } /* diff -u --recursive --new-file v2.4.0-test12/linux/include/asm-i386/desc.h linux/include/asm-i386/desc.h --- v2.4.0-test12/linux/include/asm-i386/desc.h Sat Sep 4 13:06:08 1999 +++ linux/include/asm-i386/desc.h Fri Dec 15 12:40:53 2000 @@ -82,7 +82,7 @@ extern inline void load_LDT (struct mm_struct *mm) { int cpu = smp_processor_id(); - void *segments = mm->segments; + void *segments = mm->context.segments; int count = LDT_ENTRIES; if (!segments) { diff -u --recursive --new-file v2.4.0-test12/linux/include/asm-i386/mmu.h linux/include/asm-i386/mmu.h --- v2.4.0-test12/linux/include/asm-i386/mmu.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-i386/mmu.h Fri Dec 15 12:38:24 2000 @@ -0,0 +1,12 @@ +#ifndef __i386_MMU_H +#define __i386_MMU_H + +/* + * The i386 doesn't have a mmu context, but + * we put the segment information here. + */ +typedef struct { + void *segments; +} mm_context_t; + +#endif diff -u --recursive --new-file v2.4.0-test12/linux/include/asm-i386/mmu_context.h linux/include/asm-i386/mmu_context.h --- v2.4.0-test12/linux/include/asm-i386/mmu_context.h Fri Sep 8 12:52:41 2000 +++ linux/include/asm-i386/mmu_context.h Fri Dec 15 18:29:19 2000 @@ -6,11 +6,9 @@ #include #include -/* - * possibly do the LDT unload here? - */ -#define destroy_context(mm) do { } while(0) -#define init_new_context(tsk,mm) 0 +/* Segment information */ +extern void destroy_context(struct mm_struct *); +extern int init_new_context(struct task_struct *, struct mm_struct *); #ifdef CONFIG_SMP @@ -33,7 +31,7 @@ /* * Re-load LDT if necessary */ - if (prev->segments != next->segments) + if (prev->context.segments != next->context.segments) load_LDT(next); #ifdef CONFIG_SMP cpu_tlbstate[cpu].state = TLBSTATE_OK; diff -u --recursive --new-file v2.4.0-test12/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h --- v2.4.0-test12/linux/include/asm-i386/processor.h Mon Dec 11 17:59:45 2000 +++ linux/include/asm-i386/processor.h Fri Dec 15 18:29:18 2000 @@ -427,11 +427,6 @@ */ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); -/* Copy and release all segment info associated with a VM */ -extern void copy_segments(struct task_struct *p, struct mm_struct * mm); -extern void release_segments(struct mm_struct * mm); -extern void forget_segments(void); - /* * Return saved PC of a blocked thread. */ diff -u --recursive --new-file v2.4.0-test12/linux/include/linux/sched.h linux/include/linux/sched.h --- v2.4.0-test12/linux/include/linux/sched.h Mon Dec 11 17:59:45 2000 +++ linux/include/linux/sched.h Fri Dec 15 18:29:19 2000 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -208,7 +209,6 @@ int map_count; /* number of VMAs */ struct semaphore mmap_sem; spinlock_t page_table_lock; - unsigned long context; unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; @@ -217,11 +217,9 @@ unsigned long cpu_vm_mask; unsigned long swap_cnt; /* number of pages to swap on next pass */ unsigned long swap_address; - /* - * This is an architecture-specific pointer: the portable - * part of Linux does not know about any segments. - */ - void * segments; + + /* Architecture-specific MM context */ + mm_context_t context; }; #define INIT_MM(name) \ @@ -235,7 +233,6 @@ map_count: 1, \ mmap_sem: __MUTEX_INITIALIZER(name.mmap_sem), \ page_table_lock: SPIN_LOCK_UNLOCKED, \ - segments: NULL \ } struct signal_struct { diff -u --recursive --new-file v2.4.0-test12/linux/kernel/fork.c linux/kernel/fork.c --- v2.4.0-test12/linux/kernel/fork.c Mon Dec 11 17:59:45 2000 +++ linux/kernel/fork.c Fri Dec 15 12:45:58 2000 @@ -133,11 +133,9 @@ mm->mmap_avl = NULL; mm->mmap_cache = NULL; mm->map_count = 0; - mm->context = 0; mm->cpu_vm_mask = 0; mm->swap_cnt = 0; mm->swap_address = 0; - mm->segments = NULL; pprev = &mm->mmap; for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) { struct file *file; @@ -319,11 +317,6 @@ up(¤t->mm->mmap_sem); if (retval) goto free_pt; - - /* - * child gets a private LDT (if there was an LDT in the parent) - */ - copy_segments(tsk, mm); if (init_new_context(tsk,mm)) goto free_pt; diff -u --recursive --new-file v2.4.0-test12/linux/mm/mmap.c linux/mm/mmap.c --- v2.4.0-test12/linux/mm/mmap.c Mon Dec 11 17:59:45 2000 +++ linux/mm/mmap.c Fri Dec 15 12:57:54 2000 @@ -885,7 +885,6 @@ { struct vm_area_struct * mpnt; - release_segments(mm); spin_lock(&mm->page_table_lock); mpnt = mm->mmap; mm->mmap = mm->mmap_avl = mm->mmap_cache = NULL;