Commit f6c2e333 authored by Siddha, Suresh B's avatar Siddha, Suresh B Committed by Linus Torvalds
Browse files

[PATCH] x86_64: Unmap NULL during early bootup



We should zap the low mappings, as soon as possible, so that we can catch
kernel bugs more effectively. Previously early boot had NULL mapped
and didn't trap on NULL references.

This patch introduces boot_level4_pgt, which will always have low identity
addresses mapped.  Druing boot, all the processors will use this as their
level4 pgt.  On BP, we will switch to init_level4_pgt as soon as we enter C
code and zap the low mappings as soon as we are done with the usage of
identity low mapped addresses.  On AP's we will zap the low mappings as
soon as we jump to C code.

Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: default avatarAshok Raj <ashok.raj@intel.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 69d81fcd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -542,7 +542,7 @@ acpi_scan_rsdp(unsigned long start, unsigned long length)
	 * RSDP signature.
	 */
	for (offset = 0; offset < length; offset += 16) {
		if (strncmp((char *)(start + offset), "RSD PTR ", sig_len))
		if (strncmp((char *)(phys_to_virt(start) + offset), "RSD PTR ", sig_len))
			continue;
		return (start + offset);
	}
+23 −14
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@

#include <linux/linkage.h>
#include <linux/threads.h>
#include <linux/init.h>
#include <asm/desc.h>
#include <asm/segment.h>
#include <asm/page.h>
@@ -70,7 +71,7 @@ startup_32:
	movl	%eax, %cr4

	/* Setup early boot stage 4 level pagetables */
	movl	$(init_level4_pgt - __START_KERNEL_map), %eax
	movl	$(boot_level4_pgt - __START_KERNEL_map), %eax
	movl	%eax, %cr3

	/* Setup EFER (Extended Feature Enable Register) */
@@ -113,7 +114,7 @@ startup_64:
	movq	%rax, %cr4

	/* Setup early boot stage 4 level pagetables. */
	movq	$(init_level4_pgt - __START_KERNEL_map), %rax
	movq	$(boot_level4_pgt - __START_KERNEL_map), %rax
	movq	%rax, %cr3

	/* Check if nx is implemented */
@@ -240,20 +241,10 @@ ljumpvector:
ENTRY(stext)
ENTRY(_stext)

	/*
	 * This default setting generates an ident mapping at address 0x100000
	 * and a mapping for the kernel that precisely maps virtual address
	 * 0xffffffff80000000 to physical address 0x000000. (always using
	 * 2Mbyte large pages provided by PAE mode)
	 */
.org 0x1000
ENTRY(init_level4_pgt)
	.quad	0x0000000000002007 + __PHYSICAL_START	/* -> level3_ident_pgt */
	.fill	255,8,0
	.quad	0x000000000000a007 + __PHYSICAL_START
	.fill	254,8,0
	/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
	.quad	0x0000000000003007 + __PHYSICAL_START	/* -> level3_kernel_pgt */
	/* This gets initialized in x86_64_start_kernel */
	.fill	512,8,0

.org 0x2000
ENTRY(level3_ident_pgt)
@@ -350,6 +341,24 @@ ENTRY(wakeup_level4_pgt)
	.quad	0x0000000000003007 + __PHYSICAL_START	/* -> level3_kernel_pgt */
#endif

#ifndef CONFIG_HOTPLUG_CPU
	__INITDATA
#endif
	/*
	 * This default setting generates an ident mapping at address 0x100000
	 * and a mapping for the kernel that precisely maps virtual address
	 * 0xffffffff80000000 to physical address 0x000000. (always using
	 * 2Mbyte large pages provided by PAE mode)
	 */
	.align PAGE_SIZE
ENTRY(boot_level4_pgt)
	.quad	0x0000000000002007 + __PHYSICAL_START	/* -> level3_ident_pgt */
	.fill	255,8,0
	.quad	0x000000000000a007 + __PHYSICAL_START
	.fill	254,8,0
	/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
	.quad	0x0000000000003007 + __PHYSICAL_START	/* -> level3_kernel_pgt */

	.data

	.align 16
+8 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <asm/bootsetup.h>
#include <asm/setup.h>
#include <asm/desc.h>
#include <asm/pgtable.h>

/* Don't add a printk in there. printk relies on the PDA which is not initialized 
   yet. */
@@ -86,6 +87,13 @@ void __init x86_64_start_kernel(char * real_mode_data)
		set_intr_gate(i, early_idt_handler);
	asm volatile("lidt %0" :: "m" (idt_descr));
	clear_bss();

	/*
	 * switch to init_level4_pgt from boot_level4_pgt
	 */
	memcpy(init_level4_pgt, boot_level4_pgt, PTRS_PER_PGD*sizeof(pgd_t));
	asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));

	pda_init(0);
	copy_bootdata(real_mode_data);
#ifdef CONFIG_SMP
+1 −1
Original line number Diff line number Diff line
@@ -549,7 +549,7 @@ void __init get_smp_config (void)
		 * Read the physical hardware table.  Anything here will
		 * override the defaults.
		 */
		if (!smp_read_mpc((void *)(unsigned long)mpf->mpf_physptr)) {
		if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr))) {
			smp_found_config = 0;
			printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
			printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
+2 −0
Original line number Diff line number Diff line
@@ -571,6 +571,8 @@ void __init setup_arch(char **cmdline_p)

	init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));

	zap_low_mappings(0);

#ifdef CONFIG_ACPI
	/*
	 * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
Loading