A 2.4.19-pre4 kernel with this patch applied has been running here on
our 50 user production system since march without any problems. At
another site which had experienced the same problems, a 2.4.18 kernel with
this patch has been running flawlessly for just over two months on a SMP
production system as well.
non-x86 architectures should not be affectes by this patch. The patch is
against 2.4.19-rc3.
diff -urN linux-2.4.19-rc3.orig/arch/i386/kernel/ldt.c linux/arch/i386/kernel/ldt.c
--- linux-2.4.19-rc3.orig/arch/i386/kernel/ldt.c 2001-10-17 23:46:29.000000000 +0200
+++ linux/arch/i386/kernel/ldt.c 2002-07-23 09:57:08.000000000 +0200
@@ -101,7 +101,6 @@
memset(segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE);
wmb();
mm->context.segments = segments;
- mm->context.cpuvalid = 1UL << smp_processor_id();
load_LDT(mm);
}
diff -urN linux-2.4.19-rc3.orig/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- linux-2.4.19-rc3.orig/arch/i386/kernel/process.c 2002-07-22 08:41:28.000000000 +0200
+++ linux/arch/i386/kernel/process.c 2002-07-23 09:57:08.000000000 +0200
@@ -569,7 +569,6 @@
memcpy(ldt, old_ldt, LDT_ENTRIES*LDT_ENTRY_SIZE);
}
new_mm->context.segments = ldt;
- new_mm->context.cpuvalid = ~0UL; /* valid on all CPU's - they can't have stale data */
}
/*
diff -urN linux-2.4.19-rc3.orig/include/asm-i386/mmu.h linux/include/asm-i386/mmu.h
--- linux-2.4.19-rc3.orig/include/asm-i386/mmu.h 2001-07-26 03:03:04.000000000 +0200
+++ linux/include/asm-i386/mmu.h 2002-07-23 09:57:08.000000000 +0200
@@ -7,7 +7,6 @@
*/
typedef struct {
void *segments;
- unsigned long cpuvalid;
} mm_context_t;
#endif
diff -urN linux-2.4.19-rc3.orig/include/asm-i386/mmu_context.h linux/include/asm-i386/mmu_context.h
--- linux-2.4.19-rc3.orig/include/asm-i386/mmu_context.h 2002-07-22 08:41:30.000000000 +0200
+++ linux/include/asm-i386/mmu_context.h 2002-07-23 09:57:08.000000000 +0200
@@ -27,20 +27,31 @@
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
{
+ void *new_ldt;
+ void *old_ldt;
+
+ /*
+ * Re-load LDT if necessary
+ */
+ new_ldt = default_ldt;
+ if (next->context.segments)
+ new_ldt = next->context.segments;
+ asm ("movb 7(%1),%%ah\n"
+ "movb 4(%1),%%al\n"
+ "shl $16,%%eax\n"
+ "movw 2(%1),%%ax" : "=&a"(old_ldt) :
+ "r"(gdt_table + __LDT(cpu)));
+ if (old_ldt != new_ldt)
+ load_LDT(next);
+
if (prev != next) {
/* stop flush ipis for the previous mm */
clear_bit(cpu, &prev->cpu_vm_mask);
- /*
- * Re-load LDT if necessary
- */
- if (prev->context.segments != next->context.segments)
- load_LDT(next);
#ifdef CONFIG_SMP
cpu_tlbstate[cpu].state = TLBSTATE_OK;
cpu_tlbstate[cpu].active_mm = next;
#endif
set_bit(cpu, &next->cpu_vm_mask);
- set_bit(cpu, &next->context.cpuvalid);
/* Re-load page tables */
load_cr3(next->pgd);
}
@@ -55,8 +66,6 @@
*/
load_cr3(next->pgd);
}
- if (!test_and_set_bit(cpu, &next->context.cpuvalid))
- load_LDT(next);
}
#endif
}
-- Stephan Springl BFW Werner Völk GmbH springl@bfw-online.de Büro für Wärmemeßgeräte +49 89 82917-452 Drosselgasse 5 82166 Gräfelfing/München- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/