patch-2.1.96 linux/arch/i386/kernel/process.c
Next file: linux/arch/i386/lib/checksum.c
Previous file: linux/arch/i386/kernel/ldt.c
Back to the patch index
Back to the overall index
- Lines: 111
- Date:
Tue Apr 14 12:24:06 1998
- Orig file:
v2.1.95/linux/arch/i386/kernel/process.c
- Orig date:
Wed Apr 1 20:11:47 1998
diff -u --recursive --new-file v2.1.95/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
@@ -418,43 +418,37 @@
0xffff & regs->xds,0xffff & regs->xes);
}
-/*
- * Free current thread data structures etc..
- */
-
-void exit_thread(void)
+void release_segments(struct mm_struct *mm)
{
- /* forget lazy i387 state */
- if (last_task_used_math == current)
- last_task_used_math = NULL;
+ void * ldt;
+
/* forget local segments */
__asm__ __volatile__("movl %w0,%%fs ; movl %w0,%%gs ; lldt %w0"
: /* no outputs */
: "r" (0));
current->tss.ldt = 0;
- if (current->ldt) {
- void * ldt = current->ldt;
- current->ldt = NULL;
+
+ ldt = mm->segments;
+ if (ldt) {
+ mm->segments = NULL;
vfree(ldt);
}
}
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+ /* forget lazy i387 state */
+ if (last_task_used_math == current)
+ last_task_used_math = NULL;
+}
+
void flush_thread(void)
{
int i;
- if (current->ldt) {
- free_page((unsigned long) current->ldt);
- current->ldt = NULL;
- for (i=1 ; i<NR_TASKS ; i++) {
- if (task[i] == current) {
- set_ldt_desc(gdt+(i<<1)+
- FIRST_LDT_ENTRY,&default_ldt, 1);
- load_ldt(i);
- }
- }
- }
-
for (i=0 ; i<8 ; i++)
current->debugreg[i] = 0;
@@ -479,13 +473,30 @@
{
}
+void copy_segments(int nr, struct task_struct *p, struct mm_struct *new_mm)
+{
+ int ldt_size = 1;
+ void * ldt = &default_ldt;
+ struct mm_struct * old_mm = current->mm;
+
+ p->tss.ldt = _LDT(nr);
+ if (old_mm->segments) {
+ new_mm->segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
+ if (new_mm->segments) {
+ ldt = new_mm->segments;
+ ldt_size = LDT_ENTRIES;
+ memcpy(ldt, old_mm->segments, LDT_ENTRIES*LDT_ENTRY_SIZE);
+ }
+ }
+ set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY, ldt, LDT_ENTRIES);
+}
+
int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
p->tss.tr = _TSS(nr);
- p->tss.ldt = _LDT(nr);
p->tss.es = __KERNEL_DS;
p->tss.cs = __KERNEL_CS;
p->tss.ss = __KERNEL_DS;
@@ -508,16 +519,8 @@
childregs->eax = 0;
childregs->esp = esp;
p->tss.back_link = 0;
- if (p->ldt) {
- p->ldt = (struct desc_struct*) vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
- if (p->ldt != NULL)
- memcpy(p->ldt, current->ldt, LDT_ENTRIES*LDT_ENTRY_SIZE);
- }
set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));
- if (p->ldt)
- set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,p->ldt, 512);
- else
- set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&default_ldt, 1);
+
/*
* a bitmap offset pointing outside of the TSS limit causes a nicely
* controllable SIGSEGV. The first sys_ioperm() call sets up the
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov