patch-2.1.121 linux/arch/i386/kernel/traps.c
Next file: linux/arch/i386/math-emu/get_address.c
Previous file: linux/arch/i386/kernel/smp.c
Back to the patch index
Back to the overall index
- Lines: 149
- Date:
Wed Sep 9 08:56:58 1998
- Orig file:
v2.1.120/linux/arch/i386/kernel/traps.c
- Orig date:
Tue Aug 18 22:02:02 1998
diff -u --recursive --new-file v2.1.120/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
@@ -9,7 +9,6 @@
* state in 'asm.s'.
*/
#include <linux/config.h>
-#include <linux/head.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -29,10 +28,20 @@
#include <asm/atomic.h>
#include <asm/debugreg.h>
+#include "desc.h"
+
asmlinkage int system_call(void);
asmlinkage void lcall7(void);
+
struct desc_struct default_ldt = { 0, 0 };
+/*
+ * The IDT has to be page-aligned to simplify the Pentium
+ * F0 0F bug workaround.. We have a special link segment
+ * for this.
+ */
+struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
+
static inline void console_verbose(void)
{
extern int console_loglevel;
@@ -467,12 +476,11 @@
* move the IDT into it and write protect this page.
*/
page = (unsigned long) vmalloc(PAGE_SIZE);
- memcpy((void *) page, idt_table, 256*8);
-
pgd = pgd_offset(&init_mm, page);
pmd = pmd_offset(pgd, page);
pte = pte_offset(pmd, page);
- *pte = pte_wrprotect(*pte);
+ free_page(pte_page(*pte));
+ *pte = mk_pte(&idt_table, PAGE_KERNEL_RO);
local_flush_tlb();
/*
@@ -484,12 +492,77 @@
__asm__ __volatile__("lidt %0": "=m" (idt_descr));
}
+#define _set_gate(gate_addr,type,dpl,addr) \
+__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
+ "movw %2,%%dx\n\t" \
+ "movl %%eax,%0\n\t" \
+ "movl %%edx,%1" \
+ :"=m" (*((long *) (gate_addr))), \
+ "=m" (*(1+(long *) (gate_addr))) \
+ :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
+ "d" ((char *) (addr)),"a" (__KERNEL_CS << 16) \
+ :"ax","dx")
+
+/*
+ * This needs to use 'idt_table' rather than 'idt', and
+ * thus use the _nonmapped_ version of the IDT, as the
+ * Pentium F0 0F bugfix can have resulted in the mapped
+ * IDT being write-protected.
+ */
+void set_intr_gate(unsigned int n, void *addr)
+{
+ _set_gate(idt_table+n,14,0,addr);
+}
+
+static void __init set_trap_gate(unsigned int n, void *addr)
+{
+ _set_gate(idt_table+n,15,0,addr);
+}
+
+static void __init set_system_gate(unsigned int n, void *addr)
+{
+ _set_gate(idt_table+n,15,3,addr);
+}
+
+static void __init set_call_gate(void *a, void *addr)
+{
+ _set_gate(a,12,3,addr);
+}
+
+#define _set_seg_desc(gate_addr,type,dpl,base,limit) {\
+ *((gate_addr)+1) = ((base) & 0xff000000) | \
+ (((base) & 0x00ff0000)>>16) | \
+ ((limit) & 0xf0000) | \
+ ((dpl)<<13) | \
+ (0x00408000) | \
+ ((type)<<8); \
+ *(gate_addr) = (((base) & 0x0000ffff)<<16) | \
+ ((limit) & 0x0ffff); }
+#define _set_tssldt_desc(n,addr,limit,type) \
+__asm__ __volatile__ ("movw %3,0(%2)\n\t" \
+ "movw %%ax,2(%2)\n\t" \
+ "rorl $16,%%eax\n\t" \
+ "movb %%al,4(%2)\n\t" \
+ "movb %4,5(%2)\n\t" \
+ "movb $0,6(%2)\n\t" \
+ "movb %%ah,7(%2)\n\t" \
+ "rorl $16,%%eax" \
+ : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
+
+void set_tss_desc(unsigned int n, void *addr)
+{
+ _set_tssldt_desc(gdt_table+FIRST_TSS_ENTRY+(n<<1), (int)addr, 235, 0x89);
+}
+
+void set_ldt_desc(unsigned int n, void *addr, unsigned int size)
+{
+ _set_tssldt_desc(gdt_table+FIRST_LDT_ENTRY+(n<<1), (int)addr, ((size << 3) - 1), 0x82);
+}
void __init trap_init(void)
{
int i;
- struct desc_struct * p;
if (readl(0x0FFFD9) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
EISA_bus = 1;
@@ -515,19 +588,12 @@
for (i=18;i<48;i++)
set_trap_gate(i,&reserved);
set_system_gate(0x80,&system_call);
-/* set up GDT task & ldt entries */
- p = gdt+FIRST_TSS_ENTRY;
- set_tss_desc(p, &init_task.tss);
- p++;
- set_ldt_desc(p, &default_ldt, 1);
- p++;
- for(i=1 ; i<NR_TASKS ; i++) {
- p->a=p->b=0;
- p++;
- p->a=p->b=0;
- p++;
- }
-/* Clear NT, so that we won't have troubles with that later on */
+
+ /* set up GDT task & ldt entries */
+ set_tss_desc(0, &init_task.tss);
+ set_ldt_desc(0, &default_ldt, 1);
+
+ /* Clear NT, so that we won't have troubles with that later on */
__asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
load_TR(0);
load_ldt(0);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov