SOURCES (LINUX_2_6): grsecurity-2.1.9-2.6.16.9.patch (NEW) - grsec...

cieciwa cieciwa at pld-linux.org
Thu Apr 20 10:29:26 CEST 2006


Author: cieciwa                      Date: Thu Apr 20 08:29:26 2006 GMT
Module: SOURCES                       Tag: LINUX_2_6
---- Log message:
- grsecurity patch from 2.6.16.2 fixed for 2.6.16.9

---- Files affected:
SOURCES:
   grsecurity-2.1.9-2.6.16.9.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/grsecurity-2.1.9-2.6.16.9.patch
diff -u /dev/null SOURCES/grsecurity-2.1.9-2.6.16.9.patch:1.1.2.1
--- /dev/null	Thu Apr 20 10:29:26 2006
+++ SOURCES/grsecurity-2.1.9-2.6.16.9.patch	Thu Apr 20 10:29:21 2006
@@ -0,0 +1,24434 @@
+diff -urNp linux-2.6.16.2/arch/alpha/kernel/module.c linux-2.6.16.2/arch/alpha/kernel/module.c
+--- linux-2.6.16.2/arch/alpha/kernel/module.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/alpha/kernel/module.c	2006-04-09 21:23:54.000000000 -0400
+@@ -177,7 +177,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, 
+ 
+ 	/* The small sections were sorted to the end of the segment.
+ 	   The following should definitely cover them.  */
+-	gp = (u64)me->module_core + me->core_size - 0x8000;
++	gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
+ 	got = sechdrs[me->arch.gotsecindex].sh_addr;
+ 
+ 	for (i = 0; i < n; i++) {
+diff -urNp linux-2.6.16.2/arch/alpha/kernel/osf_sys.c linux-2.6.16.2/arch/alpha/kernel/osf_sys.c
+--- linux-2.6.16.2/arch/alpha/kernel/osf_sys.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/alpha/kernel/osf_sys.c	2006-04-09 21:23:54.000000000 -0400
+@@ -1274,6 +1274,10 @@ arch_get_unmapped_area(struct file *filp
+ 	   merely specific addresses, but regions of memory -- perhaps
+ 	   this feature should be incorporated into all ports?  */
+ 
++#ifdef CONFIG_PAX_RANDMMAP
++	if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
++#endif
++
+ 	if (addr) {
+ 		addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
+ 		if (addr != (unsigned long) -ENOMEM)
+@@ -1281,8 +1285,8 @@ arch_get_unmapped_area(struct file *filp
+ 	}
+ 
+ 	/* Next, try allocating at TASK_UNMAPPED_BASE.  */
+-	addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
+-					 len, limit);
++	addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
++
+ 	if (addr != (unsigned long) -ENOMEM)
+ 		return addr;
+ 
+diff -urNp linux-2.6.16.2/arch/alpha/kernel/ptrace.c linux-2.6.16.2/arch/alpha/kernel/ptrace.c
+--- linux-2.6.16.2/arch/alpha/kernel/ptrace.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/alpha/kernel/ptrace.c	2006-04-09 21:23:54.000000000 -0400
+@@ -15,6 +15,7 @@
+ #include <linux/slab.h>
+ #include <linux/security.h>
+ #include <linux/signal.h>
++#include <linux/grsecurity.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -283,6 +284,9 @@ do_sys_ptrace(long request, long pid, lo
+ 		goto out_notsk;
+ 	}
+ 
++	if (gr_handle_ptrace(child, request))
++		goto out;
++
+ 	if (request == PTRACE_ATTACH) {
+ 		ret = ptrace_attach(child);
+ 		goto out;
+diff -urNp linux-2.6.16.2/arch/alpha/mm/fault.c linux-2.6.16.2/arch/alpha/mm/fault.c
+--- linux-2.6.16.2/arch/alpha/mm/fault.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/alpha/mm/fault.c	2006-04-09 21:23:54.000000000 -0400
+@@ -25,6 +25,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
++#include <linux/binfmts.h>
+ 
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+@@ -56,6 +57,124 @@ __load_new_mm_context(struct mm_struct *
+ 	__reload_thread(pcb);
+ }
+ 
++#ifdef CONFIG_PAX_PAGEEXEC
++/*
++ * PaX: decide what to do with offenders (regs->pc = fault address)
++ *
++ * returns 1 when task should be killed
++ *         2 when patched PLT trampoline was detected
++ *         3 when unpatched PLT trampoline was detected
++ */
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++
++#ifdef CONFIG_PAX_EMUPLT
++	int err;
++
++	do { /* PaX: patched PLT emulation #1 */
++		unsigned int ldah, ldq, jmp;
++
++		err = get_user(ldah, (unsigned int *)regs->pc);
++		err |= get_user(ldq, (unsigned int *)(regs->pc+4));
++		err |= get_user(jmp, (unsigned int *)(regs->pc+8));
++
++		if (err)
++			break;
++
++		if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
++		    (ldq & 0xFFFF0000U) == 0xA77B0000U &&
++		    jmp == 0x6BFB0000U)
++		{
++			unsigned long r27, addr;
++			unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
++			unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
++
++			addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
++			err = get_user(r27, (unsigned long*)addr);
++			if (err)
++				break;
++
++			regs->r27 = r27;
++			regs->pc = r27;
++			return 2;
++		}
++	} while (0);
++
++	do { /* PaX: patched PLT emulation #2 */
++		unsigned int ldah, lda, br;
++
++		err = get_user(ldah, (unsigned int *)regs->pc);
++		err |= get_user(lda, (unsigned int *)(regs->pc+4));
++		err |= get_user(br, (unsigned int *)(regs->pc+8));
++
++		if (err)
++			break;
++
++		if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
++		    (lda & 0xFFFF0000U) == 0xA77B0000U &&
++		    (br & 0xFFE00000U) == 0xC3E00000U)
++		{
++			unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
++			unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
++			unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
++
++			regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
++			regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
++			return 2;
++		}
++	} while (0);
++
++	do { /* PaX: unpatched PLT emulation */
++		unsigned int br;
++
++		err = get_user(br, (unsigned int *)regs->pc);
++
++		if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
++			unsigned int br2, ldq, nop, jmp;
++			unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
++
++			addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
++			err = get_user(br2, (unsigned int *)addr);
++			err |= get_user(ldq, (unsigned int *)(addr+4));
++			err |= get_user(nop, (unsigned int *)(addr+8));
++			err |= get_user(jmp, (unsigned int *)(addr+12));
++			err |= get_user(resolver, (unsigned long *)(addr+16));
++
++			if (err)
++				break;
++
++			if (br2 == 0xC3600000U &&
++			    ldq == 0xA77B000CU &&
++			    nop == 0x47FF041FU &&
++			    jmp == 0x6B7B0000U)
++			{
++				regs->r28 = regs->pc+4;
++				regs->r27 = addr+16;
++				regs->pc = resolver;
++				return 3;
++			}
++		}
++	} while (0);
++#endif
++
++	return 1;
++}
++
++void pax_report_insns(void *pc, void *sp)
++{
++	unsigned long i;
++
++	printk(KERN_ERR "PAX: bytes at PC: ");
++	for (i = 0; i < 5; i++) {
++		unsigned int c;
++		if (get_user(c, (unsigned int*)pc+i))
++			printk("???????? ");
++		else
++			printk("%08x ", c);
++	}
++	printk("\n");
++}
++#endif
+ 
+ /*
+  * This routine handles page faults.  It determines the address,
+@@ -133,8 +252,29 @@ do_page_fault(unsigned long address, uns
+  good_area:
+ 	si_code = SEGV_ACCERR;
+ 	if (cause < 0) {
+-		if (!(vma->vm_flags & VM_EXEC))
++		if (!(vma->vm_flags & VM_EXEC)) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++			if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
++				goto bad_area;
++
++			up_read(&mm->mmap_sem);
++			switch(pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_PAX_EMUPLT
++			case 2:
++			case 3:
++				return;
++#endif
++
++			}
++			pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
++			do_exit(SIGKILL);
++#else
+ 			goto bad_area;
++#endif
++
++		}
+ 	} else if (!cause) {
+ 		/* Allow reads even for write-only mappings */
+ 		if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
+diff -urNp linux-2.6.16.2/arch/arm/mm/mmap.c linux-2.6.16.2/arch/arm/mm/mmap.c
+--- linux-2.6.16.2/arch/arm/mm/mmap.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/arm/mm/mmap.c	2006-04-09 21:23:54.000000000 -0400
+@@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
+ 	if (len > TASK_SIZE)
+ 		return -ENOMEM;
+ 
++#ifdef CONFIG_PAX_RANDMMAP
++	if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
++#endif
++
+ 	if (addr) {
+ 		if (do_align)
+ 			addr = COLOUR_ALIGN(addr, pgoff);
+@@ -76,7 +80,7 @@ arch_get_unmapped_area(struct file *filp
+ 	if (len > mm->cached_hole_size) {
+ 	        start_addr = addr = mm->free_area_cache;
+ 	} else {
+-	        start_addr = addr = TASK_UNMAPPED_BASE;
++	        start_addr = addr = mm->mmap_base;
+ 	        mm->cached_hole_size = 0;
+ 	}
+ 
+@@ -93,8 +97,8 @@ full_search:
+ 			 * Start a new search - just in case we missed
+ 			 * some holes.
+ 			 */
+-			if (start_addr != TASK_UNMAPPED_BASE) {
+-				start_addr = addr = TASK_UNMAPPED_BASE;
++			if (start_addr != mm->mmap_base) {
++				start_addr = addr = mm->mmap_base;
+ 				mm->cached_hole_size = 0;
+ 				goto full_search;
+ 			}
+diff -urNp linux-2.6.16.2/arch/i386/boot/compressed/head.S linux-2.6.16.2/arch/i386/boot/compressed/head.S
+--- linux-2.6.16.2/arch/i386/boot/compressed/head.S	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/boot/compressed/head.S	2006-04-09 21:23:54.000000000 -0400
+@@ -39,11 +39,13 @@ startup_32:
+ 	movl %eax,%gs
+ 
+ 	lss stack_start,%esp
++	movl 0x000000,%ecx
+ 	xorl %eax,%eax
+ 1:	incl %eax		# check that A20 really IS enabled
+ 	movl %eax,0x000000	# loop forever if it isn't
+ 	cmpl %eax,0x100000
+ 	je 1b
++	movl %ecx,0x000000
+ 
+ /*
+  * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
+diff -urNp linux-2.6.16.2/arch/i386/Kconfig linux-2.6.16.2/arch/i386/Kconfig
+--- linux-2.6.16.2/arch/i386/Kconfig	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/Kconfig	2006-04-09 21:23:54.000000000 -0400
+@@ -963,7 +963,7 @@ endchoice
+ 
+ config PCI_BIOS
+ 	bool
+-	depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
++	depends on !X86_VISWS && PCI && PCI_GOBIOS
+ 	default y
+ 
+ config PCI_DIRECT
+diff -urNp linux-2.6.16.2/arch/i386/Kconfig.cpu linux-2.6.16.2/arch/i386/Kconfig.cpu
+--- linux-2.6.16.2/arch/i386/Kconfig.cpu	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/Kconfig.cpu	2006-04-09 21:23:54.000000000 -0400
+@@ -251,7 +251,7 @@ config X86_PPRO_FENCE
+ 
+ config X86_F00F_BUG
+ 	bool
+-	depends on M586MMX || M586TSC || M586 || M486 || M386
++	depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
+ 	default y
+ 
+ config X86_WP_WORKS_OK
+@@ -281,7 +281,7 @@ config X86_CMPXCHG64
+ 
+ config X86_ALIGNMENT_16
+ 	bool
+-	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
++	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
+ 	default y
+ 
+ config X86_GOOD_APIC
+diff -urNp linux-2.6.16.2/arch/i386/Kconfig.debug linux-2.6.16.2/arch/i386/Kconfig.debug
+--- linux-2.6.16.2/arch/i386/Kconfig.debug	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/Kconfig.debug	2006-04-09 21:24:03.000000000 -0400
+@@ -44,7 +44,7 @@ config DEBUG_PAGEALLOC
+ 
+ config DEBUG_RODATA
+ 	bool "Write protect kernel read-only data structures"
+-	depends on DEBUG_KERNEL
++	depends on DEBUG_KERNEL && 0
+ 	help
+ 	  Mark the kernel read-only data as write-protected in the pagetables,
+ 	  in order to catch accidental (and incorrect) writes to such const
+diff -urNp linux-2.6.16.2/arch/i386/kernel/acpi/sleep.c linux-2.6.16.2/arch/i386/kernel/acpi/sleep.c
+--- linux-2.6.16.2/arch/i386/kernel/acpi/sleep.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/kernel/acpi/sleep.c	2006-04-09 21:23:54.000000000 -0400
+@@ -10,6 +10,7 @@
+ #include <linux/dmi.h>
+ #include <asm/smp.h>
+ #include <asm/tlbflush.h>
++#include <asm/desc.h>
+ 
+ /* address in low memory of the wakeup routine. */
+ unsigned long acpi_wakeup_address = 0;
+@@ -24,11 +25,22 @@ static void init_low_mapping(pgd_t * pgd
+ {
+ 	int pgd_ofs = 0;
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++	unsigned long cr0;
++
++	pax_open_kernel(cr0);
++#endif
++
+ 	while ((pgd_ofs < pgd_limit)
+ 	       && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
+ 		set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD));
+ 		pgd_ofs++, pgd++;
+ 	}
++
++#ifdef CONFIG_PAX_KERNEXEC
++	pax_close_kernel(cr0);
++#endif
++
+ 	flush_tlb_all();
+ }
+ 
+@@ -55,7 +67,18 @@ int acpi_save_state_mem(void)
+  */
+ void acpi_restore_state_mem(void)
+ {
++#ifdef CONFIG_PAX_KERNEXEC
++	unsigned long cr0;
++
++	pax_open_kernel(cr0);
++#endif
++
+ 	zap_low_mappings();
++
++#ifdef CONFIG_PAX_KERNEXEC
++	pax_close_kernel(cr0);
++#endif
++
+ }
+ 
+ /**
+diff -urNp linux-2.6.16.2/arch/i386/kernel/apic.c linux-2.6.16.2/arch/i386/kernel/apic.c
+--- linux-2.6.16.2/arch/i386/kernel/apic.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/kernel/apic.c	2006-04-09 21:23:54.000000000 -0400
+@@ -1150,7 +1150,7 @@ inline void smp_local_timer_interrupt(st
+ {
+ 	profile_tick(CPU_PROFILING, regs);
+ #ifdef CONFIG_SMP
+-	update_process_times(user_mode_vm(regs));
++	update_process_times(user_mode(regs));
+ #endif
+ 
+ 	/*
+diff -urNp linux-2.6.16.2/arch/i386/kernel/apm.c linux-2.6.16.2/arch/i386/kernel/apm.c
+--- linux-2.6.16.2/arch/i386/kernel/apm.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/kernel/apm.c	2006-04-09 21:23:54.000000000 -0400
+@@ -589,9 +589,18 @@ static u8 apm_bios_call(u32 func, u32 eb
+ 	struct desc_struct	save_desc_40;
+ 	struct desc_struct	*gdt;
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++	unsigned long		cr0;
++#endif
++
+ 	cpus = apm_save_cpus();
+ 	
+ 	cpu = get_cpu();
++
++#ifdef CONFIG_PAX_KERNEXEC
++	pax_open_kernel(cr0);
++#endif
++
+ 	gdt = get_cpu_gdt_table(cpu);
+ 	save_desc_40 = gdt[0x40 / 8];
+ 	gdt[0x40 / 8] = bad_bios_desc;
+@@ -603,6 +612,11 @@ static u8 apm_bios_call(u32 func, u32 eb
+ 	APM_DO_RESTORE_SEGS;
+ 	local_irq_restore(flags);
+ 	gdt[0x40 / 8] = save_desc_40;
++
++#ifdef CONFIG_PAX_KERNEXEC
++	pax_close_kernel(cr0);
++#endif
++
+ 	put_cpu();
+ 	apm_restore_cpus(cpus);
+ 	
+@@ -633,9 +647,18 @@ static u8 apm_bios_call_simple(u32 func,
+ 	struct desc_struct	save_desc_40;
+ 	struct desc_struct	*gdt;
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++	unsigned long		cr0;
++#endif
++
+ 	cpus = apm_save_cpus();
+ 	
+ 	cpu = get_cpu();
++
++#ifdef CONFIG_PAX_KERNEXEC
++	pax_open_kernel(cr0);
++#endif
++
+ 	gdt = get_cpu_gdt_table(cpu);
+ 	save_desc_40 = gdt[0x40 / 8];
+ 	gdt[0x40 / 8] = bad_bios_desc;
+@@ -647,6 +670,11 @@ static u8 apm_bios_call_simple(u32 func,
+ 	APM_DO_RESTORE_SEGS;
+ 	local_irq_restore(flags);
+ 	gdt[0x40 / 8] = save_desc_40;
++
++#ifdef CONFIG_PAX_KERNEXEC
++	pax_close_kernel(cr0);
++#endif
++
+ 	put_cpu();
+ 	apm_restore_cpus(cpus);
+ 	return error;
+diff -urNp linux-2.6.16.2/arch/i386/kernel/asm-offsets.c linux-2.6.16.2/arch/i386/kernel/asm-offsets.c
+--- linux-2.6.16.2/arch/i386/kernel/asm-offsets.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/kernel/asm-offsets.c	2006-04-09 21:23:54.000000000 -0400
+@@ -68,5 +68,6 @@ void foo(void)
+ 		 sizeof(struct tss_struct));
+ 
+ 	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
++	DEFINE(PTRS_PER_PTE_asm, PTRS_PER_PTE);
+ 	DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
+ }
+diff -urNp linux-2.6.16.2/arch/i386/kernel/cpu/common.c linux-2.6.16.2/arch/i386/kernel/cpu/common.c
+--- linux-2.6.16.2/arch/i386/kernel/cpu/common.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/kernel/cpu/common.c	2006-04-09 21:23:54.000000000 -0400
+@@ -4,7 +4,6 @@
+ #include <linux/smp.h>
+ #include <linux/module.h>
+ #include <linux/percpu.h>
+-#include <linux/bootmem.h>
+ #include <asm/semaphore.h>
+ #include <asm/processor.h>
+ #include <asm/i387.h>
+@@ -19,9 +18,6 @@
+ 
+ #include "cpu.h"
+ 
+-DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
+-EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
+-
+ DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
+ EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
+ 
+@@ -387,6 +383,10 @@ void __devinit identify_cpu(struct cpuin
+ 	if (this_cpu->c_init)
+ 		this_cpu->c_init(c);
+ 
++#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_NOVSYSCALL)
++	clear_bit(X86_FEATURE_SEP, c->x86_capability);
++#endif
++
+ 	/* Disable the PN if appropriate */
+ 	squash_the_stupid_serial_number(c);
+ 
+@@ -573,11 +573,10 @@ void __init early_cpu_init(void)
+ void __devinit cpu_init(void)
+ {
+ 	int cpu = smp_processor_id();
+-	struct tss_struct * t = &per_cpu(init_tss, cpu);
++	struct tss_struct * t = init_tss + cpu;
+ 	struct thread_struct *thread = &current->thread;
+-	struct desc_struct *gdt;
++	struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+ 	__u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
+-	struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
+ 
+ 	if (cpu_test_and_set(cpu, cpu_initialized)) {
+ 		printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
+@@ -595,29 +594,11 @@ void __devinit cpu_init(void)
+ 	}
+ 
+ 	/*
+-	 * This is a horrible hack to allocate the GDT.  The problem
+-	 * is that cpu_init() is called really early for the boot CPU
+-	 * (and hence needs bootmem) but much later for the secondary
+-	 * CPUs, when bootmem will have gone away
+-	 */
+-	if (NODE_DATA(0)->bdata->node_bootmem_map) {
+-		gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE);
+-		/* alloc_bootmem_pages panics on failure, so no check */
+-		memset(gdt, 0, PAGE_SIZE);
+-	} else {
+-		gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
+-		if (unlikely(!gdt)) {
+-			printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
+-			for (;;)
+-				local_irq_enable();
+-		}
+-	}
+-
+-	/*
+ 	 * Initialize the per-CPU GDT with the boot GDT,
+ 	 * and set up the GDT descriptor:
+ 	 */
+- 	memcpy(gdt, cpu_gdt_table, GDT_SIZE);
++	if (cpu)
++		memcpy(gdt, cpu_gdt_table, GDT_SIZE);
+ 
+ 	/* Set up GDT entry for 16bit stack */
+  	*(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
+@@ -625,10 +606,10 @@ void __devinit cpu_init(void)
+ 		((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
+ 		(CPU_16BIT_STACK_SIZE - 1);
+ 
+-	cpu_gdt_descr->size = GDT_SIZE - 1;
+- 	cpu_gdt_descr->address = (unsigned long)gdt;
++	cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
++	cpu_gdt_descr[cpu].address = (unsigned long)gdt;
+ 
+-	load_gdt(cpu_gdt_descr);
++	load_gdt(&cpu_gdt_descr[cpu]);
+ 	load_idt(&idt_descr);
+ 
+ 	/*
+@@ -643,7 +624,7 @@ void __devinit cpu_init(void)
+ 	load_esp0(t, thread);
+ 	set_tss_desc(cpu,t);
+ 	load_TR_desc();
+-	load_LDT(&init_mm.context);
++	_load_LDT(&init_mm.context);
+ 
+ #ifdef CONFIG_DOUBLEFAULT
+ 	/* Set up doublefault TSS pointer in the GDT */
+diff -urNp linux-2.6.16.2/arch/i386/kernel/doublefault.c linux-2.6.16.2/arch/i386/kernel/doublefault.c
+--- linux-2.6.16.2/arch/i386/kernel/doublefault.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/kernel/doublefault.c	2006-04-09 21:23:54.000000000 -0400
+@@ -11,7 +11,7 @@
+ 
+ #define DOUBLEFAULT_STACKSIZE (1024)
+ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
+-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
+ 
+ #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
+ 
+diff -urNp linux-2.6.16.2/arch/i386/kernel/efi.c linux-2.6.16.2/arch/i386/kernel/efi.c
+--- linux-2.6.16.2/arch/i386/kernel/efi.c	2006-04-07 12:56:47.000000000 -0400
++++ linux-2.6.16.2/arch/i386/kernel/efi.c	2006-04-09 21:23:54.000000000 -0400
+@@ -64,82 +64,58 @@ extern void * boot_ioremap(unsigned long
+ 
+ static unsigned long efi_rt_eflags;
+ static DEFINE_SPINLOCK(efi_rt_lock);
+-static pgd_t efi_bak_pg_dir_pointer[2];
++static pgd_t __initdata efi_bak_pg_dir_pointer[4];
+ 
+-static void efi_call_phys_prelog(void)
++static void __init efi_call_phys_prelog(void)
+ {
+-	unsigned long cr4;
+-	unsigned long temp;
+-	struct Xgt_desc_struct *cpu_gdt_descr;
+-
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list