x86: merge setup_32/64.c
cover x86: merge setup_32/64.c
please check the patches
it will rename setup.c to setup_percpu.c and make setup_32.c to support 64bit, and then change setup_32.c to setup.c and delete setup_64.c.
Thanks
Yinghai Lu
PATCH 3/16 x86: update reserve_initrd to support 64bit
arch/x86/kernel/setup_32.c +55 -54
@@ -186,43 +186,18 @@ static inline void copy_edd(void) #ifdef CONFIG_BLK_DEV_INITRD -static void __init relocate_initrd (void ); +#ifdef CONFIG_X86_32 -static void __init reserve_initrd (void ) +#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) +static void __init relocate_initrd(void) { + u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; -u64 ramdisk_end = ramdisk_image + ramdisk_size; u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT; u64 ramdisk_here; - -if (!boot_params.hdr.type_of_loader || - !ramdisk_image || !ramdisk_size) -return ;/* No initrd provided by bootloader */ - - initrd_start =0 ; - -if (ramdisk_size >= (end_of_lowmem>>1 )) { -free_early (ramdisk_image, ramdisk_end); -printk (KERN_ERR "initrd too large to handle, " -"disabling initrd\n" ); -return ; - } - -printk (KERN_INFO "old RAMDISK: %08llx - %08llx\n" , ramdisk_image, - ramdisk_end); - - -if (ramdisk_end <= end_of_lowmem) { -/* All in lowmem, easy case */ -/* -* don't need to reserve again, already reserved early -* in i386_start_kernel -*/ - initrd_start = ramdisk_image +PAGE_OFFSET ; - initrd_end = initrd_start + ramdisk_size; -return ; - } + unsigned long slop, clen, mapaddr; + char *p, *q; /* We need to move the initrd down into lowmem */ ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size,
@@ -241,22 +216,6 @@ static void __init reserve_initrd(void)printk (KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n" , ramdisk_here, ramdisk_here + ramdisk_size); -relocate_initrd (); -} - -#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) - -static void __init relocate_initrd (void ) -{ -u64 ramdisk_image = boot_params.hdr.ramdisk_image; -u64 ramdisk_size = boot_params.hdr.ramdisk_size; -u64 end_of_lowmem = max_low_pfn <<PAGE_SHIFT ; -u64 ramdisk_here; -unsigned long slop, clen, mapaddr; -char *p, *q; - - ramdisk_here = initrd_start -PAGE_OFFSET ; - q = (char *)initrd_start;/* Copy any lowmem portion of the initrd */
@@ -286,18 +245,60 @@ static void __init relocate_initrd(void)/* high pages is not converted by early_res_to_bootmem */ ramdisk_image = boot_params.hdr.ramdisk_image; ramdisk_size = boot_params.hdr.ramdisk_size; -printk (KERN_INFO "Copied RAMDISK from %016llx - %016llx to %08llx - %08llx\n" , +printk (KERN_INFO "Move RAMDISK from %016llx - %016llx to" +" %08llx - %08llx\n" , ramdisk_image, ramdisk_image + ramdisk_size -1 , ramdisk_here, ramdisk_here + ramdisk_size -1 ); +} +#endif -/* -* need to free old one, otherwise init cross max_low_pfn could be -* converted to bootmem -*/ - free_early(ramdisk_image, ramdisk_image+ramdisk_size); +static void __init reserve_initrd (void ) +{ +u64 ramdisk_image = boot_params.hdr.ramdisk_image; +u64 ramdisk_size = boot_params.hdr.ramdisk_size; +u64 ramdisk_end = ramdisk_image + ramdisk_size; +u64 end_of_lowmem = max_low_pfn <<PAGE_SHIFT ; + +if (!boot_params.hdr.type_of_loader || + !ramdisk_image || !ramdisk_size) +return ;/* No initrd provided by bootloader */ + + initrd_start =0 ; + +if (ramdisk_size >= (end_of_lowmem>>1 )) { +free_early (ramdisk_image, ramdisk_end); +printk (KERN_ERR "initrd too large to handle, " +"disabling initrd\n" ); +return ; + } + +printk (KERN_INFO "RAMDISK: %08llx - %08llx\n" , ramdisk_image, + ramdisk_end); + + +if (ramdisk_end <= end_of_lowmem) { +/* All in lowmem, easy case */ +/* +* don't need to reserve again, already reserved early +* in i386_start_kernel +*/ + initrd_start = ramdisk_image +PAGE_OFFSET ; + initrd_end = initrd_start + ramdisk_size; +return ; + } + +#ifdef CONFIG_X86_32 +relocate_initrd (); +#else +printk (KERN_ERR "initrd extends beyond end of memory " +"(0x%08llx > 0x%08llx)\ndisabling initrd\n" , + ramdisk_end, end_of_lowmem); + initrd_start =0 ; +#endif +free_early (ramdisk_image, ramdisk_end); }#else -void __init reserve_initrd (void ) +static void __init reserve_initrd (void ) { }#endif /* CONFIG_BLK_DEV_INITRD */
PATCH 4/16 x86: put global variable for 32bit all together
In reply to Yinghai Luthose variables are not needed by 64 bit.
arch/x86/kernel/setup_32.c +33 -24
@@ -100,6 +100,8 @@ static struct resource bss_resource = { .flags = IORESOURCE_BUSY | IORESOURCE_MEM }; + +#ifdef CONFIG_X86_32 static struct resource video_ram_resource = { .name ="Video RAM area" , .start = 0xa0000,
@@ -108,24 +110,47 @@ static struct resource video_ram_resourc };/* cpu data as detected by the assembly code in head.S */ -struct cpuinfo_x86 new_cpu_data__cpuinitdata = {0 ,0 ,0 ,0 ,-1 ,1 ,0 ,0 ,-1 }; +struct cpuinfo_x86 new_cpu_data__cpuinitdata = {0 ,0 ,0 ,0 ,-1 ,1 ,0 ,0 ,-1 };/* common cpu data for all cpus */ -struct cpuinfo_x86 boot_cpu_data__read_mostly = {0 ,0 ,0 ,0 ,-1 ,1 ,0 ,0 ,-1 }; +struct cpuinfo_x86 boot_cpu_data__read_mostly = {0 ,0 ,0 ,0 ,-1 ,1 ,0 ,0 ,-1 };EXPORT_SYMBOL (boot_cpu_data); +static void set_mca_bus (int x) +{ +#ifdef CONFIG_MCA + MCA_bus = x; +#endif +}unsigned int def_to_bigsmp; -#ifndef CONFIG_X86_PAE -unsigned long mmu_cr4_features; -#else -unsigned long mmu_cr4_features =X86_CR4_PAE ; -#endif -/* for MCA, but anyone else can use it if they want */ unsigned int machine_id;unsigned int machine_submodel_id;unsigned int BIOS_revision; +struct apm_info apm_info; +EXPORT_SYMBOL (apm_info); + +#if defined(CONFIG_X86_SPEEDSTEP_SMI ) || \ + defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE ) +struct ist_info ist_info; +EXPORT_SYMBOL (ist_info); +#else +struct ist_info ist_info; +#endif + +#else +struct cpuinfo_x86 boot_cpu_data__read_mostly ; +EXPORT_SYMBOL (boot_cpu_data); +#endif + + +#if !defined(CONFIG_X86_PAE ) || defined(CONFIG_X86_64 ) +unsigned long mmu_cr4_features; +#else +unsigned long mmu_cr4_features =X86_CR4_PAE ; +#endif +/* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type;
@@ -140,15 +165,8 @@ char dmi_alloc_data[DMI_MAX_DATA];*/ struct screen_info screen_info;EXPORT_SYMBOL (screen_info); -struct apm_info apm_info; -EXPORT_SYMBOL (apm_info);struct edid_info edid_info;EXPORT_SYMBOL_GPL (edid_info); -struct ist_info ist_info; -#if defined(CONFIG_X86_SPEEDSTEP_SMI ) || \ - defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE ) -EXPORT_SYMBOL (ist_info); -#endif extern int root_mountflags;
@@ -303,15 +321,6 @@ static void __init reserve_initrd(void) }#endif /* CONFIG_BLK_DEV_INITRD */ -#ifdef CONFIG_MCA -static void set_mca_bus (int x) -{ - MCA_bus = x; -} -#else -static void set_mca_bus (int x) { } -#endif -/* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures
PATCH 5/16 x86: add extra includes for 64bit support
In reply to Yinghai Luarch/x86/kernel/setup_32.c +47 -3
@@ -45,31 +45,75 @@#include <linux/dmi.h> #include <linux/pfn.h> #include <linux/pci.h> +#include <asm/pci-direct.h> #include <linux/init_ohci1394_dma.h> #include <linux/kvm_para.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/stddef.h> +#include <linux/unistd.h> +#include <linux/ptrace.h> +#include <linux/slab.h> +#include <linux/user.h> +#include <linux/delay.h> +#include <linux/highmem.h> + +#include <linux/kallsyms.h> +#include <linux/edd.h> +#include <linux/iscsi_ibft.h> +#include <linux/kexec.h> +#include <linux/cpufreq.h> +#include <linux/dma-mapping.h> +#include <linux/ctype.h> +#include <linux/uaccess.h> + +#include <linux/percpu.h> +#include <linux/crash_dump.h> +#include <video/edid.h> #include <asm/mtrr.h> #include <asm/apic.h> #include <asm/e820.h> #include <asm/mpspec.h> -#include <asm/mmzone.h> #include <asm/setup.h> #include <asm/arch_hooks.h> #include <asm/sections.h> #include <asm/dmi.h> #include <asm/io_apic.h> #include <asm/ist.h> -#include <asm/io.h> #include <asm/vmi.h> #include <setup_arch.h> #include <asm/bios_ebda.h> #include <asm/cacheflush.h> #include <asm/processor.h> -#include <asm/efi.h> #include <asm/bugs.h> +#include <asm/system.h> +#include <asm/vsyscall.h> +#include <asm/smp.h> +#include <asm/desc.h> +#include <asm/dma.h> +#include <asm/gart.h> +#include <asm/mmu_context.h> +#include <asm/proto.h> + +#include <mach_apic.h> +#ifdef CONFIG_PARAVIRT +#include <asm/paravirt.h> +#else +#define ARCH_SETUP +#endif + +#include <asm/percpu.h> +#include <asm/sections.h> +#include <asm/topology.h> +#include <asm/apicdef.h> +#ifdef CONFIG_X86_32 +#include <asm/highmem.h> +#endif +/* This value is set up by the early boot code to point to the value immediately after the boot time page tables. It contains a *physical* address, and must not be in the .bss segment! */
PATCH 6/16 x86: merge 64bit setup_arch into setup_32
In reply to Yinghai Luarch/x86/kernel/setup_32.c +91 -8
@@ -372,26 +372,38 @@ static void __init reserve_initrd(void)* global efi_enabled. This allows the same kernel image to be used on existing * systems (with a traditional BIOS) as well as on EFI systems. */ +/* +* setup_arch - architecture-specific boot-time initializations +* +* Note: On x86_64, fixmaps are ready for use even before this is called. +*/ +void __init setup_arch (char **cmdline_p) { +#ifdef CONFIG_X86_32 memcpy (&boot_cpu_data, &new_cpu_data,sizeof (new_cpu_data));pre_setup_arch_hook ();early_cpu_init ();early_ioremap_init ();reserve_setup_data (); +#else +printk (KERN_INFO "Command line: %s\n" , boot_command_line); +#endif ROOT_DEV =old_decode_dev (boot_params.hdr.root_dev); screen_info = boot_params.screen_info; edid_info = boot_params.edid_info; +#ifdef CONFIG_X86_32 apm_info.bios = boot_params.apm_bios_info; ist_info = boot_params.ist_info; - saved_video_mode = boot_params.hdr.vid_mode; -if ( boot_params.sys_desc_table.length !=0 ) { +if (boot_params.sys_desc_table.length !=0 ) {set_mca_bus (boot_params.sys_desc_table.table[3 ] &0x2 ); machine_id = boot_params.sys_desc_table.table[0 ]; machine_submodel_id = boot_params.sys_desc_table.table[1 ]; BIOS_revision = boot_params.sys_desc_table.table[2 ]; } +#endif + saved_video_mode = boot_params.hdr.vid_mode; bootloader_type = boot_params.hdr.type_of_loader;#ifdef CONFIG_BLK_DEV_RAM
@@ -401,7 +413,12 @@ void __init setup_arch(char **cmdline_p)#endif #ifdef CONFIG_EFI if (!strncmp ((char *)&boot_params.efi_info.efi_loader_signature, -"EL32" ,4 )) { +#ifdef CONFIG_X86_32 +"EL32" , +#else +"EL64" , +#endif +4 )) { efi_enabled =1 ;efi_reserve_early (); }
@@ -417,7 +434,11 @@ void __init setup_arch(char **cmdline_p) init_mm.start_code = (unsigned long ) _text; init_mm.end_code = (unsigned long ) _etext; init_mm.end_data = (unsigned long ) _edata; +#ifdef CONFIG_X86_32 init_mm.brk = init_pg_tables_end +PAGE_OFFSET ; +#else + init_mm.brk = (unsigned long ) &_end; +#endif code_resource.start =virt_to_phys (_text); code_resource.end =virt_to_phys (_etext)-1 ;
@@ -426,6 +447,9 @@ void __init setup_arch(char **cmdline_p) bss_resource.start =virt_to_phys (&__bss_start); bss_resource.end =virt_to_phys (&__bss_stop)-1 ; +#ifdef CONFIG_X86_64 +early_cpu_init (); +#endif strlcpy (command_line, boot_command_line,COMMAND_LINE_SIZE ); *cmdline_p = command_line;
@@ -433,16 +457,27 @@ void __init setup_arch(char **cmdline_p)parse_early_param (); -if (acpi_mps_check ()){ +if (acpi_mps_check ()) {#ifdef CONFIG_X86_LOCAL_APIC +#ifdef CONFIG_X86_32 enable_local_apic =-1 ; +#else + disable_apic =1 ; +#endif #endif clear_cpu_cap (&boot_cpu_data,X86_FEATURE_APIC ); }finish_e820_parsing (); +#ifdef CONFIG_X86_32 probe_roms (); +#else +# ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT +if (init_ohci1394_dma_early) +init_ohci1394_dma_on_all_controllers (); +# endif +#endif /* after parse_early_param, so could debug it */ insert_resource (&iomem_resource, &code_resource);
@@ -452,6 +487,7 @@ void __init setup_arch(char **cmdline_p)if (efi_enabled)efi_init (); +#ifdef CONFIG_X86_32 if (ppro_with_ram_bug ()) {e820_update_range (0x70000000ULL ,0x40000ULL ,E820_RAM ,E820_RESERVED );
@@ -459,6 +495,9 @@ void __init setup_arch(char **cmdline_p)printk (KERN_INFO "fixed physical RAM map:\n" ); e820_print_map("bad_ppro"); } +#else +early_gart_iommu_check (); +#endif e820_register_active_regions (0 ,0 ,-1UL );/*
@@ -477,14 +516,32 @@ void __init setup_arch(char **cmdline_p) max_pfn =e820_end_of_ram (); } +#ifdef CONFIG_X86_32 /* max_low_pfn get updated here */ find_low_pfn_range (); +#else + num_physpages = max_pfn; + +check_efer (); + +/* How many end-of-memory variables you have, grandma! */ +/* need this before calling reserve_initrd */ + max_low_pfn = max_pfn; + high_memory = (void *)__va (max_pfn *PAGE_SIZE -1 ) +1 ; +#endif /* max_pfn_mapped is updated here */ +#ifdef CONFIG_X86_64 + max_pfn_mapped = +#endifinit_memory_mapping (0 , (max_low_pfn <<PAGE_SHIFT ));reserve_initrd (); +#ifdef CONFIG_X86_64 +vsmp_init (); +#endif +dmi_scan_machine ();io_delay_init ();
@@ -494,6 +551,11 @@ void __init setup_arch(char **cmdline_p)*/ acpi_boot_table_init (); +#ifdef CONFIG_X86_64 +/* Remove active ranges so rediscovery with NUMA-awareness happens */ +remove_all_active_ranges (); +#endif +#ifdef CONFIG_ACPI_NUMA /* * Parse SRAT to discover nodes.
@@ -503,13 +565,18 @@ void __init setup_arch(char **cmdline_p)initmem_init (0 , max_pfn); +#ifdef CONFIG_X86_64 +dma32_reserve_bootmem (); +#endif +#ifdef CONFIG_ACPI_SLEEP /* * Reserve low memory region for sleep support. */ acpi_reserve_bootmem ();#endif -#ifdef CONFIG_X86_FIND_SMP_CONFIG +#if defined(CONFIG_X86_FIND_SMP_CONFIG ) && defined(CONFIG_X86_32 ) || \ + defined(CONFIG_X86_MPPARSE ) && defined(CONFIG_X86_64 )/* * Find and reserve possible boot-time SMP configuration: */
@@ -523,7 +590,7 @@ void __init setup_arch(char **cmdline_p)kvmclock_init ();#endif -#ifdef CONFIG_VMI +#if defined(CONFIG_VMI ) && defined(CONFIG_X86_32 )/* * Must be after max_low_pfn is determined, and before kernel * pagetables are setup.
@@ -533,11 +600,15 @@ void __init setup_arch(char **cmdline_p)paging_init (); +#ifdef CONFIG_X86_64 +map_vsyscall (); +#endif +/* * NOTE: On x86-32, only from this point on, fixmaps are ready for use. */ -#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT +#if defined(CONFIG_PROVIDE_OHCI1394_DMA_INIT ) && defined(CONFIG_X86_32 )if (init_ohci1394_dma_early)init_ohci1394_dma_on_all_controllers ();#endif
@@ -553,6 +624,10 @@ void __init setup_arch(char **cmdline_p)*/ acpi_boot_init (); +#ifdef CONFIG_X86_64 +init_cpu_to_node (); +#endif +#if defined(CONFIG_X86_MPPARSE ) || defined(CONFIG_X86_VISWS )/* * get boot-time SMP configuration:
@@ -560,18 +635,26 @@ void __init setup_arch(char **cmdline_p)if (smp_found_config)get_smp_config ();#endif -#if defined(CONFIG_SMP ) && defined(CONFIG_X86_PC ) + +#ifdef CONFIG_X86_64 +init_apic_mappings (); +ioapic_init_mappings (); +#else +# if defined(CONFIG_SMP ) && defined(CONFIG_X86_PC )if (def_to_bigsmp)printk (KERN_WARNING "More than 8 CPUs detected and " "CONFIG_X86_PC cannot handle it.\nUse " "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n" ); +# endif #endif kvm_guest_init ();e820_reserve_resources ();e820_mark_nosave_regions (max_low_pfn); +#ifdef CONFIG_X86_32 request_resource (&iomem_resource, &video_ram_resource); +#endif reserve_standard_io_resources ();e820_setup_gap ();
PATCH 7/16 x86: space to tab in setup_arch
In reply to Yinghai Luarch/x86/kernel/setup_32.c +4 -4
@@ -557,10 +557,10 @@ void __init setup_arch(char **cmdline_p)#endif #ifdef CONFIG_ACPI_NUMA -/* -* Parse SRAT to discover nodes. -*/ -acpi_numa_init (); +/* +* Parse SRAT to discover nodes. +*/ +acpi_numa_init ();#endif initmem_init (0 , max_pfn);
PATCH 8/16 x86: rename setup_32.c to setup.c
In reply to Yinghai Luand let 64 bit use that instead of setup_64.c
--- arch/x86/kernel/Makefile | 2 arch/x86/kernel/setup.c | 671 +++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/setup_32.c | 671 --------------------------------------------- arch/x86/kernel/setup_64.c | 380 ------------------------- 4 files changed, 672 insertions(+), 1052 deletions(-)
arch/x86/kernel/Makefile +1 -1
@@ -26,7 +26,7 @@ CFLAGS_paravirt.o := $(nostackp) obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o obj-y += traps_$(BITS).o irq_$(BITS).o obj-y += time_$(BITS).o ioport.o ldt.o -obj-y += setup_$(BITS).o i8259.o irqinit_$(BITS).o setup_percpu.o +obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o obj-$(CONFIG_X86_32) += probe_roms_32.o obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
arch/x86/kernel/setup.c new file +671 -0
671 lines not on this page · raw message
arch/x86/kernel/setup_32.c deleted +0 -671
671 lines not on this page · raw message
arch/x86/kernel/setup_64.c deleted +0 -380
380 lines not on this page · raw message
PATCH 9/16 x86: move boot_params back to setup.c
In reply to Yinghai Lu--- arch/x86/kernel/setup.c | 6 ++++++ arch/x86/kernel/setup_percpu.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-)
arch/x86/kernel/setup.c +6 -0
@@ -114,6 +114,12 @@#include <asm/highmem.h> #endif +#ifndef CONFIG_DEBUG_BOOT_PARAMS +struct boot_params __initdata boot_params; +#else +struct boot_params boot_params; +#endif +/* This value is set up by the early boot code to point to the value immediately after the boot time page tables. It contains a *physical* address, and must not be in the .bss segment! */
arch/x86/kernel/setup_percpu.c +0 -6
@@ -15,12 +15,6 @@#include <asm/apicdef.h> #include <asm/highmem.h> -#ifndef CONFIG_DEBUG_BOOT_PARAMS -struct boot_params __initdata boot_params; -#else -struct boot_params boot_params; -#endif -#ifdef CONFIG_X86_LOCAL_APIC unsigned int num_processors;unsigned disabled_cpus__cpuinitdata ;
PATCH 10/16 x86: move parse_setup_data back to setup.c
In reply to Yinghai Lu--- arch/x86/kernel/setup.c | 25 +++++++++++++++++++++++++ arch/x86/kernel/setup_percpu.c | 25 ------------------------- 2 files changed, 25 insertions(+), 25 deletions(-)
arch/x86/kernel/setup.c +25 -0
@@ -371,6 +371,31 @@ static void __init reserve_initrd(void) }#endif /* CONFIG_BLK_DEV_INITRD */ +void __init parse_setup_data (void ) +{ +struct setup_data *data; +u64 pa_data; + +if (boot_params.hdr.version <0x0209 ) +return ; + pa_data = boot_params.hdr.setup_data; +while (pa_data) { + data =early_ioremap (pa_data,PAGE_SIZE ); +switch (data->type) { +case SETUP_E820_EXT : +parse_e820_ext (data, pa_data); +break ; +default : +break ; + } +#ifndef CONFIG_DEBUG_BOOT_PARAMS +free_early (pa_data, pa_data+sizeof (*data)+data->len); +#endif + pa_data = data->next; +early_iounmap (data,PAGE_SIZE ); + } +} +/* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures
arch/x86/kernel/setup_percpu.c +0 -25
@@ -214,31 +214,6 @@ void __init setup_per_cpu_areas(void)#endif -void __init parse_setup_data (void ) -{ -struct setup_data *data; -u64 pa_data; - -if (boot_params.hdr.version <0x0209 ) -return ; - pa_data = boot_params.hdr.setup_data; -while (pa_data) { - data =early_ioremap (pa_data,PAGE_SIZE ); -switch (data->type) { -case SETUP_E820_EXT : -parse_e820_ext (data, pa_data); -break ; -default : -break ; - } -#ifndef CONFIG_DEBUG_BOOT_PARAMS -free_early (pa_data, pa_data+sizeof (*data)+data->len); -#endif - pa_data = data->next; -early_iounmap (data,PAGE_SIZE ); - } -} -#ifdef X86_64_NUMA /*
PATCH 11/16 x86: move back crashkernel back to setup.c
In reply to Yinghai Lu--- arch/x86/kernel/setup.c | 58 +++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/setup_percpu.c | 57 ---------------------------------------- 2 files changed, 58 insertions(+), 57 deletions(-)
arch/x86/kernel/setup.c +58 -0
@@ -397,6 +397,64 @@ void __init parse_setup_data(void) }/* +* --------- Crashkernel reservation ------------------------------ +*/ + +#ifdef CONFIG_KEXEC +static inline unsigned long long get_total_mem (void ) +{ +unsigned long long total; + + total = max_low_pfn - min_low_pfn; +#ifdef CONFIG_HIGHMEM + total += highend_pfn - highstart_pfn; +#endif + +return total <<PAGE_SHIFT ; +} + +void __init reserve_crashkernel (void ) +{ +unsigned long long total_mem; +unsigned long long crash_size, crash_base; +int ret; + + total_mem =get_total_mem (); + + ret =parse_crashkernel (boot_command_line, total_mem, + &crash_size, &crash_base); +if (ret ==0 && crash_size >0 ) { +if (crash_base <=0 ) { +printk (KERN_INFO "crashkernel reservation failed - " +"you have to specify a base address\n" ); +return ; + } + +if (reserve_bootmem_generic (crash_base, crash_size, +BOOTMEM_EXCLUSIVE ) <0 ) { +printk (KERN_INFO "crashkernel reservation failed - " +"memory is in use\n" ); +return ; + } + +printk (KERN_INFO "Reserving %ldMB of memory at %ldMB " +"for crashkernel (System RAM: %ldMB)\n" , + (unsigned long )(crash_size >>20 ), + (unsigned long )(crash_base >>20 ), + (unsigned long )(total_mem >>20 )); + + crashk_res.start = crash_base; + crashk_res.end = crash_base + crash_size -1 ; +insert_resource (&iomem_resource, &crashk_res); + } +} +#else +void __init reserve_crashkernel (void ) +{ +} +#endif + +/* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures * for initialization. Note, the efi init code path is determined by the
arch/x86/kernel/setup_percpu.c +0 -57
63 lines not on this page · raw message
PATCH 12/16 x86: move reserve_standard_io_resources back to setup.c
In reply to Yinghai Lu--- arch/x86/kernel/setup.c | 33 +++++++++++++++++++++++++++++++++ arch/x86/kernel/setup_percpu.c | 32 -------------------------------- 2 files changed, 33 insertions(+), 32 deletions(-)
arch/x86/kernel/setup.c +33 -0
@@ -454,6 +454,39 @@ void __init reserve_crashkernel(void) }#endif +static struct resource standard_io_resources[] = { + { .name ="dma1" , .start =0x00 , .end =0x1f , + .flags =IORESOURCE_BUSY |IORESOURCE_IO }, + { .name ="pic1" , .start =0x20 , .end =0x21 , + .flags =IORESOURCE_BUSY |IORESOURCE_IO }, + { .name ="timer0" , .start =0x40 , .end =0x43 , + .flags =IORESOURCE_BUSY |IORESOURCE_IO }, + { .name ="timer1" , .start =0x50 , .end =0x53 , + .flags =IORESOURCE_BUSY |IORESOURCE_IO }, + { .name ="keyboard" , .start =0x60 , .end =0x60 , + .flags =IORESOURCE_BUSY |IORESOURCE_IO }, + { .name ="keyboard" , .start =0x64 , .end =0x64 , + .flags =IORESOURCE_BUSY |IORESOURCE_IO }, + { .name ="dma page reg" , .start =0x80 , .end =0x8f , + .flags =IORESOURCE_BUSY |IORESOURCE_IO }, + { .name ="pic2" , .start =0xa0 , .end =0xa1 , + .flags =IORESOURCE_BUSY |IORESOURCE_IO }, + { .name ="dma2" , .start =0xc0 , .end =0xdf , + .flags =IORESOURCE_BUSY |IORESOURCE_IO }, + { .name ="fpu" , .start =0xf0 , .end =0xff , + .flags =IORESOURCE_BUSY |IORESOURCE_IO } +}; + +void __init reserve_standard_io_resources (void ) +{ +int i; + +/* request I/O space for devices used on all i[345]86 PCs */ +for (i =0 ; i <ARRAY_SIZE (standard_io_resources); i++) +request_resource (&ioport_resource, &standard_io_resources[i]); + +} +/* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures
arch/x86/kernel/setup_percpu.c +0 -32
@@ -387,38 +387,6 @@ EXPORT_SYMBOL(node_to_cpumask);#endif /* X86_64_NUMA */ -static struct resource standard_io_resources[] = { - { .name ="dma1" , .start =0x00 , .end =0x1f , - .flags =IORESOURCE_BUSY |IORESOURCE_IO }, - { .name ="pic1" , .start =0x20 , .end =0x21 , - .flags =IORESOURCE_BUSY |IORESOURCE_IO }, - { .name ="timer0" , .start =0x40 , .end =0x43 , - .flags =IORESOURCE_BUSY |IORESOURCE_IO }, - { .name ="timer1" , .start =0x50 , .end =0x53 , - .flags =IORESOURCE_BUSY |IORESOURCE_IO }, - { .name ="keyboard" , .start =0x60 , .end =0x60 , - .flags =IORESOURCE_BUSY |IORESOURCE_IO }, - { .name ="keyboard" , .start =0x64 , .end =0x64 , - .flags =IORESOURCE_BUSY |IORESOURCE_IO }, - { .name ="dma page reg" , .start =0x80 , .end =0x8f , - .flags =IORESOURCE_BUSY |IORESOURCE_IO }, - { .name ="pic2" , .start =0xa0 , .end =0xa1 , - .flags =IORESOURCE_BUSY |IORESOURCE_IO }, - { .name ="dma2" , .start =0xc0 , .end =0xdf , - .flags =IORESOURCE_BUSY |IORESOURCE_IO }, - { .name ="fpu" , .start =0xf0 , .end =0xff , - .flags =IORESOURCE_BUSY |IORESOURCE_IO } -}; - -void __init reserve_standard_io_resources (void ) -{ -int i; - -/* request I/O space for devices used on all i[345]86 PCs */ -for (i =0 ; i <ARRAY_SIZE (standard_io_resources); i++) -request_resource (&ioport_resource, &standard_io_resources[i]); - -}#ifdef CONFIG_PROC_VMCORE /* elfcorehdr= specifies the location of elf core header
PATCH 13/16 x86: move parse elfvorehdr back to setup.c
In reply to Yinghai Lu--- arch/x86/kernel/setup.c | 16 ++++++++++++++++ arch/x86/kernel/setup_percpu.c | 16 ---------------- 2 files changed, 16 insertions(+), 16 deletions(-)
arch/x86/kernel/setup.c +16 -0
@@ -487,6 +487,22 @@ void __init reserve_standard_io_resource } +#ifdef CONFIG_PROC_VMCORE +/* elfcorehdr= specifies the location of elf core header +* stored by the crashed kernel. This option will be passed +* by kexec loader to the capture kernel. +*/ +static int __init setup_elfcorehdr (char *arg) +{ +char *end; +if (!arg) +return -EINVAL ; + elfcorehdr_addr =memparse (arg, &end); +return end > arg ?0 : -EINVAL ; +} +early_param ("elfcorehdr" , setup_elfcorehdr); +#endif +/* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures
arch/x86/kernel/setup_percpu.c +0 -16
@@ -387,19 +387,3 @@ EXPORT_SYMBOL(node_to_cpumask);#endif /* X86_64_NUMA */ - -#ifdef CONFIG_PROC_VMCORE -/* elfcorehdr= specifies the location of elf core header -* stored by the crashed kernel. This option will be passed -* by kexec loader to the capture kernel. -*/ -static int __init setup_elfcorehdr (char *arg) -{ -char *end; -if (!arg) -return -EINVAL ; - elfcorehdr_addr =memparse (arg, &end); -return end > arg ?0 : -EINVAL ; -} -early_param ("elfcorehdr" , setup_elfcorehdr); -#endif
PATCH 14/16 x86: make x86_find_smp_config depends on 64 bit too
In reply to Yinghai Lu--- arch/x86/Kconfig | 1 - arch/x86/kernel/setup.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-)
arch/x86/Kconfig +0 -1
@@ -236,7 +236,6 @@ config SMP config X86_FIND_SMP_CONFIG def_bool y depends on X86_MPPARSE || X86_VOYAGER || X86_VISWS - depends on X86_32 if ACPI config X86_MPPARSE
arch/x86/kernel/setup.c +1 -2
@@ -713,8 +713,7 @@ void __init setup_arch(char **cmdline_p)*/ acpi_reserve_bootmem ();#endif -#if defined(CONFIG_X86_FIND_SMP_CONFIG ) && defined(CONFIG_X86_32 ) || \ - defined(CONFIG_X86_MPPARSE ) && defined(CONFIG_X86_64 ) +#ifdef CONFIG_X86_FIND_SMP_CONFIG /* * Find and reserve possible boot-time SMP configuration: */
PATCH 15/16 x86: change some functions in setup.c to static
In reply to Yinghai Lu--- arch/x86/kernel/setup.c | 8 ++++---- include/asm-x86/bootparam.h | 1 - include/asm-x86/setup.h | 5 ----- 3 files changed, 4 insertions(+), 10 deletions(-)
arch/x86/kernel/setup.c +4 -4
@@ -371,7 +371,7 @@ static void __init reserve_initrd(void) }#endif /* CONFIG_BLK_DEV_INITRD */ -void __init parse_setup_data (void ) +static void __init parse_setup_data (void ) {struct setup_data *data;u64 pa_data;
@@ -413,7 +413,7 @@ static inline unsigned long long get_totreturn total <<PAGE_SHIFT ; } -void __init reserve_crashkernel (void ) +static void __init reserve_crashkernel (void ) {unsigned long long total_mem;unsigned long long crash_size, crash_base;
@@ -449,7 +449,7 @@ void __init reserve_crashkernel(void) } }#else -void __init reserve_crashkernel (void ) +static void __init reserve_crashkernel (void ) { }#endif
@@ -477,7 +477,7 @@ static struct resource standard_io_resou .flags = IORESOURCE_BUSY | IORESOURCE_IO } }; -void __init reserve_standard_io_resources (void ) +static void __init reserve_standard_io_resources (void ) {int i;
include/asm-x86/bootparam.h +0 -1
@@ -109,6 +109,5 @@ struct boot_params { } __attribute__((packed));void reserve_setup_data (void ); -void parse_setup_data (void );#endif /* _ASM_BOOTPARAM_H */
include/asm-x86/setup.h +0 -5
@@ -8,9 +8,6 @@/* Interrupt control for vSMPowered x86_64 systems */ void vsmp_init (void ); -/* Crashkernel reservation */ -void reserve_crashkernel (void ); -#ifndef CONFIG_PARAVIRT #define paravirt_post_allocator_init () do {} while (0)#endif
@@ -38,8 +35,6 @@ void reserve_crashkernel(void);#ifndef __ASSEMBLY__#include <asm/bootparam.h> -void reserve_standard_io_resources (void ); -#ifndef _SETUP/*
PATCH 16/16 x86: we only have init_pg_tables_end for 32bit
In reply to Yinghai Lu--- arch/x86/kernel/setup.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
arch/x86/kernel/setup.c +6 -6
@@ -120,12 +120,6 @@ struct boot_params __initdata boot_paramstruct boot_params boot_params;#endif -/* This value is set up by the early boot code to point to the value -immediately after the boot time page tables. It contains a *physical* -address, and must not be in the .bss segment! */ -unsigned long init_pg_tables_start__initdata = ~0UL ; -unsigned long init_pg_tables_end__initdata = ~0UL ; -/* * Machine setup.. */
@@ -152,6 +146,12 @@ static struct resource bss_resource = {#ifdef CONFIG_X86_32 +/* This value is set up by the early boot code to point to the value +immediately after the boot time page tables. It contains a *physical* +address, and must not be in the .bss segment! */ +unsigned long init_pg_tables_start__initdata = ~0UL ; +unsigned long init_pg_tables_end__initdata = ~0UL ; +static struct resource video_ram_resource = { .name ="Video RAM area" , .start = 0xa0000,
PATCH 1/1 x86: clean up ARCH_SETUP
In reply to Yinghai Luasm-x86/paravirt.h already have protection with CONFIG_PARAVIRT inside
--- arch/x86/kernel/setup.c | 8 ++++---- include/asm-x86/mach-default/setup_arch.h | 4 ---- include/asm-x86/mach-visws/setup_arch.h | 2 -- 3 files changed, 4 insertions(+), 10 deletions(-)
arch/x86/kernel/setup.c +4 -4
@@ -100,11 +100,7 @@#include <asm/proto.h> #include <mach_apic.h> -#ifdef CONFIG_PARAVIRT #include <asm/paravirt.h> -#else -#define ARCH_SETUP -#endif #include <asm/percpu.h> #include <asm/sections.h>
@@ -114,6 +110,10 @@#include <asm/highmem.h> #endif +#ifndef ARCH_SETUP +#define ARCH_SETUP +#endif +#ifndef CONFIG_DEBUG_BOOT_PARAMS struct boot_params __initdata boot_params;#else
include/asm-x86/mach-default/setup_arch.h +0 -4
@@ -1,7 +1,3 @@/* Hook to call BIOS initialisation function */ /* no action for generic */ - -#ifndef ARCH_SETUP -#define ARCH_SETUP -#endif
include/asm-x86/mach-visws/setup_arch.h +0 -2
@@ -4,5 +4,3 @@ extern unsigned long sgivwfb_mem_phys;extern unsigned long sgivwfb_mem_size;/* no action for visws */ - -#define ARCH_SETUP
Ingo Molnar
AppliedRe: [PATCH] x86: clean up ARCH_SETUP
Quoted 1 line · Yinghai Lu
asm-x86/paravirt.halready have protection withCONFIG_PARAVIRTinside
applied to tip/x86/unify-setup - thanks Yinghai.
Ingo
PATCH 1/1 x86: move fix mapping page table range early
In reply to Yinghai Ludo that in init_memory_mapping
also remove one init_ohci1394_dma_on_all_controllers
--- arch/x86/kernel/setup.c | 23 +++++++++-------------- arch/x86/mm/init_32.c | 15 +++++++++++---- 2 files changed, 20 insertions(+), 18 deletions(-)
arch/x86/kernel/setup.c +9 -14
@@ -615,11 +615,6 @@ void __init setup_arch(char **cmdline_p)#ifdef CONFIG_X86_32 probe_roms (); -#else -# ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT -if (init_ohci1394_dma_early) -init_ohci1394_dma_on_all_controllers (); -# endif #endif /* after parse_early_param, so could debug it */
@@ -679,6 +674,15 @@ void __init setup_arch(char **cmdline_p)#endif init_memory_mapping (0 , (max_low_pfn <<PAGE_SHIFT )); +/* +* NOTE: On x86-32, only from this point on, fixmaps are ready for use. +*/ + +#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT +if (init_ohci1394_dma_early) +init_ohci1394_dma_on_all_controllers (); +#endif +reserve_initrd ();#ifdef CONFIG_X86_64
@@ -746,15 +750,6 @@ void __init setup_arch(char **cmdline_p)map_vsyscall ();#endif -/* -* NOTE: On x86-32, only from this point on, fixmaps are ready for use. -*/ - -#if defined(CONFIG_PROVIDE_OHCI1394_DMA_INIT ) && defined(CONFIG_X86_32 ) -if (init_ohci1394_dma_early) -init_ohci1394_dma_on_all_controllers (); -#endif -#ifdef CONFIG_X86_GENERICARCH generic_apic_probe ();#endif
arch/x86/mm/init_32.c +11 -4
@@ -442,13 +442,10 @@ void __init native_pagetable_setup_done(* be partially populated, and so it avoids stomping on any existing * mappings. */ -static void __init pagetable_init (void ) +static void __init early_ioremap_page_table_range_init (pgd_t *pgd_base) { -pgd_t *pgd_base = swapper_pg_dir;unsigned long vaddr, end; -paravirt_pagetable_setup_start (pgd_base); -/* * Fixed mappings, only the page table structure has to be * created - mappings will be set by set_fixmap():
@@ -458,6 +455,13 @@ static void __init pagetable_init(void) end = (FIXADDR_TOP +PMD_SIZE -1 ) &PMD_MASK ;page_table_range_init (vaddr, end, pgd_base);early_ioremap_reset (); +} + +static void __init pagetable_init (void ) +{ +pgd_t *pgd_base = swapper_pg_dir; + +paravirt_pagetable_setup_start (pgd_base);permanent_kmaps_init (pgd_base);
@@ -783,6 +787,8 @@ unsigned long __init_refok init_memory_mkernel_physical_mapping_init (pgd_base, start, end); +early_ioremap_page_table_range_init (pgd_base); +load_cr3 (swapper_pg_dir);__flush_tlb_all ();
@@ -794,6 +800,7 @@ unsigned long __init_refok init_memory_mreturn end >>PAGE_SHIFT ; } +/* * paging_init() sets up the page tables - note that the first 8MB are * already mapped by head.S.
Ingo Molnar
AppliedRe: [PATCH] x86: move fix mapping page table range early
Quoted 3 lines · Yinghai Lu
do that in
init_memory_mappingalso remove one
init_ohci1394_dma_on_all_controllers
applied to tip/x86/unify-setup - thanks Yinghai.
Ingo
PATCH 1/1 x86: early res print out alignment
In reply to Yinghai Lu--- arch/x86/kernel/e820.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
arch/x86/kernel/e820.c +15 -5
@@ -828,16 +828,26 @@ void __init free_early(u64 start, u64 envoid __init early_res_to_bootmem (u64 start,u64 end) { -int i; +int i, count;u64 final_start, final_end; -for (i =0 ; i <MAX_EARLY_RES && early_res[i].end; i++) { + + count =0 ; +for (i =0 ; i <MAX_EARLY_RES && early_res[i].end; i++) + count++; + +printk (KERN_INFO "(%d early reservations):\n" , count); +for (i =0 ; i < count; i++) {struct early_res *r = &early_res[i]; +printk (KERN_INFO " #%d [%08llx-%08llx] %16s" , i, + r->start, r->end -1 , r->name); final_start =max (start, r->start); final_end =min (end, r->end); -if (final_start >= final_end) +if (final_start >= final_end) { +printk (KERN_INFO "\n" );continue ; -printk (KERN_INFO " early res: %d [%llx-%llx] %s\n" , i, - final_start, final_end -1 , r->name); + } +printk (KERN_CONT " ==> [%08llx-%08llx] converted\n" , + final_start, final_end -1 );reserve_bootmem_generic (final_start, final_end - final_start,BOOTMEM_DEFAULT ); }
PATCH 1/1 x86: let setup_arch call init_apic_mappings for 32bit
instead of calling it from trap_init()
also move init ioapic mapping out of apic_32.c
so 32 bit do same as 64 bit
--- arch/x86/kernel/apic_32.c | 30 ------------------------------ arch/x86/kernel/io_apic_32.c | 32 ++++++++++++++++++++++++++++++++ arch/x86/kernel/setup.c | 6 ++---- arch/x86/kernel/traps_32.c | 4 ---- include/asm-x86/apic.h | 1 + include/asm-x86/io_apic.h | 1 + 6 files changed, 36 insertions(+), 38 deletions(-)
arch/x86/kernel/apic_32.c +0 -30
@@ -1197,36 +1197,6 @@ void __init init_apic_mappings(void)if (boot_cpu_physical_apicid ==-1U ) boot_cpu_physical_apicid =GET_APIC_ID (read_apic_id ()); -#ifdef CONFIG_X86_IO_APIC - { -unsigned long ioapic_phys, idx =FIX_IO_APIC_BASE_0 ; -int i; - -for (i =0 ; i < nr_ioapics; i++) { -if (smp_found_config) { - ioapic_phys = mp_ioapics[i].mp_apicaddr; -if (!ioapic_phys) { -printk (KERN_ERR -"WARNING: bogus zero IO-APIC " -"address found in MPTABLE, " -"disabling IO/APIC support!\n" ); - smp_found_config =0 ; - skip_ioapic_setup =1 ; - goto fake_ioapic_page; - } - }else { -fake_ioapic_page: - ioapic_phys = (unsigned long ) -alloc_bootmem_pages (PAGE_SIZE ); - ioapic_phys =__pa (ioapic_phys); - } -set_fixmap_nocache (idx, ioapic_phys); -printk (KERN_DEBUG "mapped IOAPIC to %08lx (%08lx)\n" , -__fix_to_virt (idx), ioapic_phys); - idx++; - } - } -#endif }/*
arch/x86/kernel/io_apic_32.c +32 -0
@@ -25,6 +25,7 @@#include <linux/init.h> #include <linux/delay.h> #include <linux/sched.h> +#include <linux/bootmem.h> #include <linux/mc146818rtc.h> #include <linux/compiler.h> #include <linux/acpi.h>
@@ -2854,3 +2855,34 @@ static int __init parse_noapic(char *argreturn 0 ; }early_param ("noapic" , parse_noapic); + +void __init ioapic_init_mappings (void ) +{ +unsigned long ioapic_phys, idx =FIX_IO_APIC_BASE_0 ; +int i; + +for (i =0 ; i < nr_ioapics; i++) { +if (smp_found_config) { + ioapic_phys = mp_ioapics[i].mp_apicaddr; +if (!ioapic_phys) { +printk (KERN_ERR +"WARNING: bogus zero IO-APIC " +"address found in MPTABLE, " +"disabling IO/APIC support!\n" ); + smp_found_config =0 ; + skip_ioapic_setup =1 ; + goto fake_ioapic_page; + } + }else { +fake_ioapic_page: + ioapic_phys = (unsigned long ) +alloc_bootmem_pages (PAGE_SIZE ); + ioapic_phys =__pa (ioapic_phys); + } +set_fixmap_nocache (idx, ioapic_phys); +printk (KERN_DEBUG "mapped IOAPIC to %08lx (%08lx)\n" , +__fix_to_virt (idx), ioapic_phys); + idx++; + } +} +
arch/x86/kernel/setup.c +2 -4
@@ -771,16 +771,14 @@ void __init setup_arch(char **cmdline_p)get_smp_config ();#endif -#ifdef CONFIG_X86_64 init_apic_mappings ();ioapic_init_mappings (); -#else -# if defined(CONFIG_SMP ) && defined(CONFIG_X86_PC ) + +#if defined(CONFIG_SMP ) && defined(CONFIG_X86_PC ) && defined(CONFIG_X86_32 )if (def_to_bigsmp)printk (KERN_WARNING "More than 8 CPUs detected and " "CONFIG_X86_PC cannot handle it.\nUse " "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n" ); -# endif #endif kvm_guest_init ();
arch/x86/kernel/traps_32.c +0 -4
@@ -1210,10 +1210,6 @@ void __init trap_init(void)early_iounmap (p,4 );#endif -#ifdef CONFIG_X86_LOCAL_APIC -init_apic_mappings (); -#endif -set_trap_gate (0 , ÷_error);set_intr_gate (1 , &debug);set_intr_gate (2 , &nmi);set_system_intr_gate (3 , &int3);/* int3/4 can be called from all */
include/asm-x86/apic.h +1 -0
@@ -135,6 +135,7 @@ extern int apic_is_clustered_box(void);#else /* !CONFIG_X86_LOCAL_APIC */ static inline void lapic_shutdown (void ) { }#define local_apic_timer_c2_ok 1 +static inline void init_apic_mappings (void ) { }#endif /* !CONFIG_X86_LOCAL_APIC */
include/asm-x86/io_apic.h +1 -0
@@ -196,6 +196,7 @@ extern void ioapic_init_mappings(void);#else /* !CONFIG_X86_IO_APIC */ #define io_apic_assign_pci_irqs 0static const int timer_through_8259 =0 ; +static inline void ioapic_init_mappings (void ) { }#endif #endif
Ingo Molnar
AppliedRe: [PATCH] x86: let setup_arch call init_apic_mappings for 32bit
Quoted 5 lines · Yinghai Lu
instead of calling it from
trap_init()also move init ioapic mapping out of
apic_32.cso 32 bit do same as 64 bit
applied to tip/x86/unify-setup - thanks Yinghai.
Ingo
PATCH 1/1 x86: early res print out alignment v2
In reply to Yinghai Luv2: fix print info to cont
[ - ] change to xxx - xxx
--- arch/x86/kernel/e820.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
arch/x86/kernel/e820.c +15 -5
@@ -828,16 +828,26 @@ void __init free_early(u64 start, u64 envoid __init early_res_to_bootmem (u64 start,u64 end) { -int i; +int i, count;u64 final_start, final_end; -for (i =0 ; i <MAX_EARLY_RES && early_res[i].end; i++) { + + count =0 ; +for (i =0 ; i <MAX_EARLY_RES && early_res[i].end; i++) + count++; + +printk (KERN_INFO "(%d early reservations) ==> bootmem\n" , count); +for (i =0 ; i < count; i++) {struct early_res *r = &early_res[i]; +printk (KERN_INFO " #%d %010llx - %010llx %16s" , i, + r->start, r->end, r->name); final_start =max (start, r->start); final_end =min (end, r->end); -if (final_start >= final_end) +if (final_start >= final_end) { +printk (KERN_CONT "\n" );continue ; -printk (KERN_INFO " early res: %d [%llx-%llx] %s\n" , i, - final_start, final_end -1 , r->name); + } +printk (KERN_CONT " ==> %010llx - %010llx\n" , + final_start, final_end);reserve_bootmem_generic (final_start, final_end - final_start,BOOTMEM_DEFAULT ); }
Ingo Molnar
AppliedRe: [PATCH] x86: early res print out alignment v2
Quoted 1 line · Yinghai Lu
v2: fix print info to cont
applied to tip/x86/unify-setup.
Quoted 1 line
[ - ] change to xxx - xxx
hm, i changed this back to "[ xxx - yyy ]" - i think it's slightly more structured hence more readable.
Ingo
Re: [PATCH] x86: early res print out alignment v2
Quoted 11 lines · Ingo Molnar
Quoted 1 line · Yinghai Lu
v2: fix print info to cont
applied to tip/x86/unify-setup.
Quoted 1 line
[ - ] change to xxx - xxx
hm, i changed this back to "[ xxx - yyy ]" - i think it's slightly more structured hence more readable.
should change [ xxx - yyy ] to [xxx - yyy]
otherwise print out width is bigger than 80
YH
PATCH 1/1 x86: fix init_memory_mapping over boundary
In reply to Yinghai Lusome end boundary is only page alignment, instead of 2M alignment, so call ker_phycial_mapping_init three times.
then don't overmap above the max_low_pfn
--- arch/x86/mm/init_32.c | 74 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 24 deletions(-)
arch/x86/mm/init_32.c +50 -24
@@ -184,8 +184,9 @@ static inline int is_kernel_text(unsigne* PAGE_OFFSET: */ static void __init kernel_physical_mapping_init (pgd_t *pgd_base, -unsigned long start, -unsigned long end) +unsigned long start_pfn, +unsigned long end_pfn, +int use_pse) {int pgd_idx, pmd_idx, pte_ofs;unsigned long pfn;
@@ -193,32 +194,30 @@ static void __init kernel_physical_mappipmd_t *pmd;pte_t *pte;unsigned pages_2m =0 , pages_4k =0 ; -unsigned limit_pfn = end >>PAGE_SHIFT ; - pgd_idx =pgd_index (PAGE_OFFSET ); - pgd = pgd_base + pgd_idx; - pfn = start >>PAGE_SHIFT ; +if (!cpu_has_pse) + use_pse =0 ; + pfn = start_pfn; + pgd_idx =pgd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pgd = pgd_base + pgd_idx;for (; pgd_idx <PTRS_PER_PGD ; pgd++, pgd_idx++) { pmd =one_md_table_init (pgd); -if (pfn >= limit_pfn) + +if (pfn >= end_pfn)continue ; -for (pmd_idx =0 ; - pmd_idx <PTRS_PER_PMD && pfn < limit_pfn; + pmd_idx =pmd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pmd += pmd_idx; +for (; pmd_idx <PTRS_PER_PMD && pfn < end_pfn; pmd++, pmd_idx++) {unsigned int addr = pfn *PAGE_SIZE +PAGE_OFFSET ;/* * Map with big pages if possible, otherwise * create normal page tables: -* -* Don't use a large page for the first 2/4MB of memory -* because there are often fixed size MTRRs in there -* and overlapping MTRRs into large pages can cause -* slowdowns. */ -if (cpu_has_pse && !(pgd_idx ==0 && pmd_idx ==0 )) { +if (use_pse) {unsigned int addr2;pgprot_t prot =PAGE_KERNEL_LARGE ;
@@ -233,13 +232,12 @@ static void __init kernel_physical_mappiset_pmd (pmd,pfn_pmd (pfn, prot)); pfn +=PTRS_PER_PTE ; - max_pfn_mapped = pfn;continue ; } pte =one_page_table_init (pmd);for (pte_ofs =0 ; - pte_ofs <PTRS_PER_PTE && pfn < max_low_pfn; + pte_ofs <PTRS_PER_PTE && pfn < end_pfn; pte++, pfn++, pte_ofs++, addr +=PAGE_SIZE ) {pgprot_t prot =PAGE_KERNEL ;
@@ -249,7 +247,6 @@ static void __init kernel_physical_mappi pages_4k++;set_pte (pte,pfn_pte (pfn, prot)); } - max_pfn_mapped = pfn; } }update_page_count (PG_LEVEL_2M , pages_2m);
@@ -729,7 +726,7 @@ void __init setup_bootmem_allocator(voidstatic void __init find_early_table_space (unsigned long end) { -unsigned long puds, pmds, tables, start; +unsigned long puds, pmds, ptes, tables, start; puds = (end +PUD_SIZE -1 ) >>PUD_SHIFT ; tables =PAGE_ALIGN (puds *sizeof (pud_t));
@@ -737,10 +734,15 @@ static void __init find_early_table_spac pmds = (end +PMD_SIZE -1 ) >>PMD_SHIFT ; tables +=PAGE_ALIGN (pmds *sizeof (pmd_t)); -if (!cpu_has_pse) { -int ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); - } +if (cpu_has_pse) { +int extra; + extra = end - ((end>>21 ) <<21 ); + extra += (2 <<20 ); + ptes = (extra +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + }else + ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + + tables +=PAGE_ALIGN (ptes *sizeof (pte_t));/* * RED-PEN putting page tables only on node 0 could
@@ -766,6 +768,7 @@ unsigned long __init_refok init_memory_m unsigned long end) {pgd_t *pgd_base = swapper_pg_dir; +unsigned long start_pfn, end_pfn;/* * Find space for the kernel direct mapping tables.
@@ -790,7 +793,30 @@ unsigned long __init_refok init_memory_m __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL; } -kernel_physical_mapping_init (pgd_base, start, end); +/* +* Don't use a large page for the first 2/4MB of memory +* because there are often fixed size MTRRs in there +* and overlapping MTRRs into large pages can cause +* slowdowns. +*/ +if (start < (2 <<20 )) { + start_pfn = start >>PAGE_SHIFT ; + end_pfn =min (2UL <<(20 -PAGE_SHIFT ), end>>PAGE_SHIFT ); +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn,0 ); + } + +if (end >= (2 <<20 )) { + start_pfn =2 << (20 -PAGE_SHIFT ); + end_pfn = (end >>21 ) << (21 -PAGE_SHIFT ); +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn, + cpu_has_pse); + + start_pfn = end_pfn; + end_pfn = end >>PAGE_SHIFT ; +if (end_pfn > start_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, + end_pfn,0 ); + }early_ioremap_page_table_range_init (pgd_base);
PATCH 1/1 x86: fix init_memory_mapping over boundary v2
some end boundary is only page alignment, instead of 2M alignment, so call ker_phycial_mapping_init three times.
then don't overmap above the max_low_pfn
v2: make init_memory_mapping more solid: start could be any value other than 0
--- arch/x86/mm/init_32.c | 86 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 24 deletions(-)
arch/x86/mm/init_32.c +62 -24
@@ -184,8 +184,9 @@ static inline int is_kernel_text(unsigne* PAGE_OFFSET: */ static void __init kernel_physical_mapping_init (pgd_t *pgd_base, -unsigned long start, -unsigned long end) +unsigned long start_pfn, +unsigned long end_pfn, +int use_pse) {int pgd_idx, pmd_idx, pte_ofs;unsigned long pfn;
@@ -193,32 +194,30 @@ static void __init kernel_physical_mappipmd_t *pmd;pte_t *pte;unsigned pages_2m =0 , pages_4k =0 ; -unsigned limit_pfn = end >>PAGE_SHIFT ; - pgd_idx =pgd_index (PAGE_OFFSET ); - pgd = pgd_base + pgd_idx; - pfn = start >>PAGE_SHIFT ; +if (!cpu_has_pse) + use_pse =0 ; + pfn = start_pfn; + pgd_idx =pgd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pgd = pgd_base + pgd_idx;for (; pgd_idx <PTRS_PER_PGD ; pgd++, pgd_idx++) { pmd =one_md_table_init (pgd); -if (pfn >= limit_pfn) + +if (pfn >= end_pfn)continue ; -for (pmd_idx =0 ; - pmd_idx <PTRS_PER_PMD && pfn < limit_pfn; + pmd_idx =pmd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pmd += pmd_idx; +for (; pmd_idx <PTRS_PER_PMD && pfn < end_pfn; pmd++, pmd_idx++) {unsigned int addr = pfn *PAGE_SIZE +PAGE_OFFSET ;/* * Map with big pages if possible, otherwise * create normal page tables: -* -* Don't use a large page for the first 2/4MB of memory -* because there are often fixed size MTRRs in there -* and overlapping MTRRs into large pages can cause -* slowdowns. */ -if (cpu_has_pse && !(pgd_idx ==0 && pmd_idx ==0 )) { +if (use_pse) {unsigned int addr2;pgprot_t prot =PAGE_KERNEL_LARGE ;
@@ -233,13 +232,12 @@ static void __init kernel_physical_mappiset_pmd (pmd,pfn_pmd (pfn, prot)); pfn +=PTRS_PER_PTE ; - max_pfn_mapped = pfn;continue ; } pte =one_page_table_init (pmd);for (pte_ofs =0 ; - pte_ofs <PTRS_PER_PTE && pfn < max_low_pfn; + pte_ofs <PTRS_PER_PTE && pfn < end_pfn; pte++, pfn++, pte_ofs++, addr +=PAGE_SIZE ) {pgprot_t prot =PAGE_KERNEL ;
@@ -249,7 +247,6 @@ static void __init kernel_physical_mappi pages_4k++;set_pte (pte,pfn_pte (pfn, prot)); } - max_pfn_mapped = pfn; } }update_page_count (PG_LEVEL_2M , pages_2m);
@@ -729,7 +726,7 @@ void __init setup_bootmem_allocator(voidstatic void __init find_early_table_space (unsigned long end) { -unsigned long puds, pmds, tables, start; +unsigned long puds, pmds, ptes, tables, start; puds = (end +PUD_SIZE -1 ) >>PUD_SHIFT ; tables =PAGE_ALIGN (puds *sizeof (pud_t));
@@ -737,10 +734,15 @@ static void __init find_early_table_spac pmds = (end +PMD_SIZE -1 ) >>PMD_SHIFT ; tables +=PAGE_ALIGN (pmds *sizeof (pmd_t)); -if (!cpu_has_pse) { -int ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); - } +if (cpu_has_pse) { +int extra; + extra = end - ((end>>21 ) <<21 ); + extra += (2 <<20 ); + ptes = (extra +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + }else + ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + + tables +=PAGE_ALIGN (ptes *sizeof (pte_t));/* * RED-PEN putting page tables only on node 0 could
@@ -766,6 +768,8 @@ unsigned long __init_refok init_memory_m unsigned long end) {pgd_t *pgd_base = swapper_pg_dir; +unsigned long start_pfn, end_pfn; +unsigned long big_page_start;/* * Find space for the kernel direct mapping tables.
@@ -790,7 +794,41 @@ unsigned long __init_refok init_memory_m __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL; } -kernel_physical_mapping_init (pgd_base, start, end); +/* +* Don't use a large page for the first 2/4MB of memory +* because there are often fixed size MTRRs in there +* and overlapping MTRRs into large pages can cause +* slowdowns. +*/ + big_page_start =2UL <<20 ; +if (start < big_page_start) { + start_pfn = start >>PAGE_SHIFT ; + end_pfn =min (big_page_start>>PAGE_SHIFT , end>>PAGE_SHIFT ); + }else { +/* head is not 2M alignment ? */ + start_pfn = (start >>21 ) << (21 -PAGE_SHIFT ); + end_pfn = start >>PAGE_SHIFT ; + } +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn,0 ); + +/* big page range */ + start_pfn = ((start + ((2UL <<20 ) -1 )) >>21 ) << (21 -PAGE_SHIFT ); +if (start_pfn < (big_page_start >>PAGE_SHIFT )) + start_pfn = big_page_start >>PAGE_SHIFT ; + end_pfn = (end >>21 ) << (21 -PAGE_SHIFT ); +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn, + cpu_has_pse); + +/* tail is not 2M alignment ? */ + start_pfn = end_pfn; +if (start_pfn > (big_page_start>>PAGE_SHIFT )) { + end_pfn = end >>PAGE_SHIFT ; +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, + end_pfn,0 ); + }early_ioremap_page_table_range_init (pgd_base);
Ingo Molnar
AppliedRe: [PATCH] x86: fix init_memory_mapping over boundary v2
Quoted 3 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times. then don't overmap above themax_low_pfn
applied to tip/x86/unify-setup, thanks Yinghai.
Quoted 2 lines
v2: make
init_memory_mappingmore solid: start could be any value other than 0
very good idea!
Ingo
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
Quoted 7 lines · Ingo Molnar
Quoted 3 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times. then don't overmap above themax_low_pfn
Quoted 6 lines
applied to tip/x86/unify-setup, thanks Yinghai.
Quoted 2 lines
v2: make
init_memory_mappingmore solid: start could be any value other than 0very good idea!
could changemap_pfn_mapped = init_memory_mapping(0, map_low_pfn<<PAGE_SHIFT); tomap_pfn_mapped = init_memory_mapping(map_pfn_mapped<<PAGE_SHIFT, map_low_pfn<<PAGE_SHIFT);
only concern isinit_memory_mapping set _EXEC in page table for kernel code.
YH
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
In reply to Ingo MolnarQuoted 7 lines · Ingo Molnar
Quoted 3 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times. then don't overmap above themax_low_pfnapplied to tip/x86/unify-setup, thanks Yinghai.
-tip testing found a 32-bit spontaneous reboot during bootup, with this config:
http://redhat.com/~mingo/misc/config-Sat_Jun_28_08_43_52_CEST_2008.bad
no serial log produced at all.
doing the reverts below fixes the problem.
Ingo
commit 4ae56755fa1e1bd1500c97b5bf82d6519a261ffd
Author: Ingo Molnar <[email protected]> Date: Sat Jun 28 08:59:44 2008 +0200
Revert "x86: let setup_arch call init_apic_mappings for 32bit"
This reverts commit 7fce3bb20100e5b6c42ad66c495e6348522bfd37.
commit 2703b959fc588f1b77290272f60bcf0bd8f6e557
Author: Ingo Molnar <[email protected]> Date: Sat Jun 28 08:59:39 2008 +0200
Revert "x86: fix init_memory_mapping over boundary v2"
This reverts commit 7a41ed2c98f860da38a944d8de5b29e6ec39cf76.
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
Quoted 30 lines · Ingo Molnar
Quoted 7 lines · Ingo Molnar
Quoted 3 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times. then don't overmap above themax_low_pfnapplied to tip/x86/unify-setup, thanks Yinghai.
-tip testing found a 32-bit spontaneous reboot during bootup, with this config:
http://redhat.com/~mingo/misc/config-Sat_Jun_28_08_43_52_CEST_2008.bad
no serial log produced at all.
doing the reverts below fixes the problem.
Ingo
commit
4ae56755fa1e1bd1500c97b5bf82d6519a261ffdAuthor: Ingo Molnar <[email protected]> Date: Sat Jun 28 08:59:44 2008 +0200Revert "x86: let
setup_archcallinit_apic_mappingsfor 32bit"This reverts commit 7fce3bb20100e5b6c42ad66c495e6348522bfd37.
Quoted 8 lines
commit
2703b959fc588f1b77290272f60bcf0bd8f6e557Author: Ingo Molnar <[email protected]> Date: Sat Jun 28 08:59:39 2008 +0200Revert "x86: fix
init_memory_mappingover boundary v2"This reverts commit 7a41ed2c98f860da38a944d8de5b29e6ec39cf76.
the system with 512M ?
YH
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
Quoted 35 lines · Yinghai Lu
Quoted 34 lines · Ingo Molnar
Quoted 7 lines · Ingo Molnar
Quoted 3 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times. then don't overmap above themax_low_pfnapplied to tip/x86/unify-setup, thanks Yinghai.
-tip testing found a 32-bit spontaneous reboot during bootup, with this config:
http://redhat.com/~mingo/misc/config-Sat_Jun_28_08_43_52_CEST_2008.bad
no serial log produced at all.
doing the reverts below fixes the problem.
Ingo
commit
4ae56755fa1e1bd1500c97b5bf82d6519a261ffdAuthor: Ingo Molnar <[email protected]> Date: Sat Jun 28 08:59:44 2008 +0200Revert "x86: let
setup_archcallinit_apic_mappingsfor 32bit"This reverts commit 7fce3bb20100e5b6c42ad66c495e6348522bfd37.commit
2703b959fc588f1b77290272f60bcf0bd8f6e557Author: Ingo Molnar <[email protected]> Date: Sat Jun 28 08:59:39 2008 +0200
Quoted 5 lines
Quoted 4 lines
Revert "x86: fix
init_memory_mappingover boundary v2"This reverts commit 7a41ed2c98f860da38a944d8de5b29e6ec39cf76.the system with 512M ?
no, other 32-bit testsystems: 1GB RAM, 2GB RAM, etc.
Ingo
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
Quoted 38 lines · Ingo Molnar
Quoted 35 lines · Yinghai Lu
Quoted 34 lines · Ingo Molnar
Quoted 7 lines · Ingo Molnar
Quoted 3 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times. then don't overmap above themax_low_pfnapplied to tip/x86/unify-setup, thanks Yinghai.
-tip testing found a 32-bit spontaneous reboot during bootup, with this config:
http://redhat.com/~mingo/misc/config-Sat_Jun_28_08_43_52_CEST_2008.bad
no serial log produced at all.
doing the reverts below fixes the problem.
Ingo
commit
4ae56755fa1e1bd1500c97b5bf82d6519a261ffdAuthor: Ingo Molnar <[email protected]> Date: Sat Jun 28 08:59:44 2008 +0200Revert "x86: let
setup_archcallinit_apic_mappingsfor 32bit"This reverts commit 7fce3bb20100e5b6c42ad66c495e6348522bfd37.commit
2703b959fc588f1b77290272f60bcf0bd8f6e557Author: Ingo Molnar <[email protected]> Date: Sat Jun 28 08:59:39 2008 +0200
Quoted 7 lines
Quoted 5 lines
Quoted 4 lines
Revert "x86: fix
init_memory_mappingover boundary v2"This reverts commit 7a41ed2c98f860da38a944d8de5b29e6ec39cf76.the system with 512M ?
no, other 32-bit testsystems: 1GB RAM, 2GB RAM, etc.
good, i duplicate that one server with your config.
YH
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
In reply to Ingo MolnarQuoted 9 lines · Ingo Molnar
Quoted 6 lines · Ingo Molnar
Quoted 3 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times. then don't overmap above themax_low_pfn
Quoted 8 lines
Quoted 1 line
applied to tip/x86/unify-setup, thanks Yinghai.
-tip testing found a 32-bit spontaneous reboot during bootup, with this config:
http://redhat.com/~mingo/misc/config-Sat_Jun_28_08_43_52_CEST_2008.bad
no serial log produced at all.
even with console=uart8250,io,0x03f8,115200n8 ?
YH
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
Quoted 12 lines · Yinghai Lu
Quoted 11 lines · Ingo Molnar
Quoted 7 lines · Ingo Molnar
Quoted 3 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times. then don't overmap above themax_low_pfnapplied to tip/x86/unify-setup, thanks Yinghai.
Quoted 7 lines
Quoted 6 lines
-tip testing found a 32-bit spontaneous reboot during bootup, with this config:
http://redhat.com/~mingo/misc/config-Sat_Jun_28_08_43_52_CEST_2008.bad
no serial log produced at all.
even with console=uart8250,io,0x03f8,115200n8 ?
correct, i use earlyprintk=serial,ttyS0,115200.
i just re-tested it - doing "git merge tip/x86/unify-setup" in the tip/master branch triggers the failure with that config on a wide range of 32-bit boxes.
Ingo
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
Quoted 20 lines · Ingo Molnar
Quoted 17 lines · Yinghai Lu
Quoted 16 lines · Ingo Molnar
Quoted 7 lines · Ingo Molnar
Quoted 3 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times. then don't overmap above themax_low_pfnapplied to tip/x86/unify-setup, thanks Yinghai.
-tip testing found a 32-bit spontaneous reboot during bootup, with this config:
http://redhat.com/~mingo/misc/config-Sat_Jun_28_08_43_52_CEST_2008.bad
Quoted 8 lines
Quoted 2 lines
Quoted 1 line
no serial log produced at all.
even with console=uart8250,io,0x03f8,115200n8 ?
correct, i use earlyprintk=serial,ttyS0,115200.
i just re-tested it - doing "git merge tip/x86/unify-setup" in the tip/master branch triggers the failure with that config on a wide range of 32-bit boxes.
please check attached v3..., that is less intrusive.
YH
[PATCH] x86: fix init_memory_mapping over boundary v3
some end boundary is only page alignment, instead of 2M alignment,
v2: make init_memory_mapping more solid: start could be any value other than 0
v3: fix NON PAE by handling left over in kernel_physical_mapping
--- arch/x86/mm/init_32.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
arch/x86/mm/init_32.c +14 -10
@@ -195,7 +195,7 @@ static void __init kernel_physical_mappiunsigned pages_2m =0 , pages_4k =0 ;unsigned limit_pfn = end >>PAGE_SHIFT ; - pgd_idx =pgd_index (PAGE_OFFSET ); + pgd_idx =pgd_index (start +PAGE_OFFSET ); pgd = pgd_base + pgd_idx; pfn = start >>PAGE_SHIFT ;
@@ -218,7 +218,8 @@ static void __init kernel_physical_mappi* and overlapping MTRRs into large pages can cause * slowdowns. */ -if (cpu_has_pse && !(pgd_idx ==0 && pmd_idx ==0 )) { +if (cpu_has_pse && !(pgd_idx ==0 && pmd_idx ==0 ) && + (pfn +PTRS_PER_PTE ) <= limit_pfn) {unsigned int addr2;pgprot_t prot =PAGE_KERNEL_LARGE ;
@@ -233,13 +234,12 @@ static void __init kernel_physical_mappiset_pmd (pmd,pfn_pmd (pfn, prot)); pfn +=PTRS_PER_PTE ; - max_pfn_mapped = pfn;continue ; } pte =one_page_table_init (pmd);for (pte_ofs =0 ; - pte_ofs <PTRS_PER_PTE && pfn < max_low_pfn; + pte_ofs <PTRS_PER_PTE && pfn < limit_pfn; pte++, pfn++, pte_ofs++, addr +=PAGE_SIZE ) {pgprot_t prot =PAGE_KERNEL ;
@@ -249,7 +249,6 @@ static void __init kernel_physical_mappi pages_4k++;set_pte (pte,pfn_pte (pfn, prot)); } - max_pfn_mapped = pfn; } }update_page_count (PG_LEVEL_2M , pages_2m);
@@ -729,7 +728,7 @@ void __init setup_bootmem_allocator(voidstatic void __init find_early_table_space (unsigned long end) { -unsigned long puds, pmds, tables, start; +unsigned long puds, pmds, ptes, tables, start; puds = (end +PUD_SIZE -1 ) >>PUD_SHIFT ; tables =PAGE_ALIGN (puds *sizeof (pud_t));
@@ -737,10 +736,15 @@ static void __init find_early_table_spac pmds = (end +PMD_SIZE -1 ) >>PMD_SHIFT ; tables +=PAGE_ALIGN (pmds *sizeof (pmd_t)); -if (!cpu_has_pse) { -int ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); - } +if (cpu_has_pse) { +unsigned long extra; + extra = end - ((end>>21 ) <<21 ); + extra += (2UL <<20 ); + ptes = (extra +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + }else + ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + + tables +=PAGE_ALIGN (ptes *sizeof (pte_t));/* * RED-PEN putting page tables only on node 0 could
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
Quoted 10 lines · Yinghai Lu
Quoted 3 lines
i just re-tested it - doing "git merge tip/x86/unify-setup" in the tip/master branch triggers the failure with that config on a wide range of 32-bit boxes.
please check attached v3..., that is less intrusive.
some end boundary is only page alignment, instead of 2M alignment,
v2: make
init_memory_mappingmore solid: start could be any value other than 0
v3: fix NON PAE by handling left over inkernel_physical_mapping
ok, this one seems to be working better.
Ingo
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
In reply to Yinghai LuQuoted 17 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times.
then don't overmap above themax_low_pfnv2: make
init_memory_mappingmore solid: start could be any value other than 0Signed-off-by Yinghai Lu <[email protected]>--- arch/x86/mm/init_32.c | 86 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 24 deletions(-)Index:
linux-2.6/arch/x86/mm/init_32.c
===================================================================
arch/x86/mm/init_32.c static inline int is_kernel_text(unsigne · line 190
Quoted 9 lines
arch/x86/mm/init_32.c +3
-2@@ -184,8 +184,9 @@ static inline int is_kernel_text(unsigne* PAGE_OFFSET: */ static void __init kernel_physical_mapping_init (pgd_t *pgd_base, -unsigned long start, -unsigned long end) +unsigned long start_pfn, +unsigned long end_pfn, +int use_pse)
Better to use bool for use_pse.
Quoted 5 lines
arch/x86/mm/init_32.c +0
-0{int pgd_idx, pmd_idx, pte_ofs;arch/x86/mm/init_32.c +0
-0unsigned long pfn;@@ -193,32 +194,30 @@ static void __init kernel_physical_mappipmd_t *pmd;
arch/x86/mm/init_32.c static void __init kernel_physical_mappi · line 200
Quoted 10 lines
arch/x86/mm/init_32.c +2
-4pte_t *pte;unsigned pages_2m =0 , pages_4k =0 ; -unsigned limit_pfn = end >>PAGE_SHIFT ; - pgd_idx =pgd_index (PAGE_OFFSET ); - pgd = pgd_base + pgd_idx; - pfn = start >>PAGE_SHIFT ; +if (!cpu_has_pse) + use_pse =0 ;
What are the semantics of the use_pse argument? Is it just a hint? If so, then the caller below should just pass a constant 1/true.
Quoted 67 lines
arch/x86/mm/init_32.c +11
-13+ pfn = start_pfn; + pgd_idx =pgd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pgd = pgd_base + pgd_idx;for (; pgd_idx <PTRS_PER_PGD ; pgd++, pgd_idx++) { pmd =one_md_table_init (pgd); -if (pfn >= limit_pfn) + +if (pfn >= end_pfn)continue ; -for (pmd_idx =0 ; - pmd_idx <PTRS_PER_PMD && pfn < limit_pfn; + pmd_idx =pmd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pmd += pmd_idx; +for (; pmd_idx <PTRS_PER_PMD && pfn < end_pfn; pmd++, pmd_idx++) {unsigned int addr = pfn *PAGE_SIZE +PAGE_OFFSET ;/* * Map with big pages if possible, otherwise * create normal page tables: -* -* Don't use a large page for the first 2/4MB of memory -* because there are often fixed size MTRRs in there -* and overlapping MTRRs into large pages can cause -* slowdowns. */ -if (cpu_has_pse && !(pgd_idx ==0 && pmd_idx ==0 )) { +if (use_pse) {unsigned int addr2;pgprot_t prot =PAGE_KERNEL_LARGE ;@@ -233,13 +232,12 @@ static void __init kernel_physical_mappiset_pmd (pmd,pfn_pmd (pfn, prot)); pfn +=PTRS_PER_PTE ; - max_pfn_mapped = pfn;continue ; } pte =one_page_table_init (pmd);for (pte_ofs =0 ; - pte_ofs <PTRS_PER_PTE && pfn < max_low_pfn; + pte_ofs <PTRS_PER_PTE && pfn < end_pfn; pte++, pfn++, pte_ofs++, addr +=PAGE_SIZE ) {pgprot_t prot =PAGE_KERNEL ;@@ -249,7 +247,6 @@ static void __init kernel_physical_mappi pages_4k++;set_pte (pte,pfn_pte (pfn, prot)); } - max_pfn_mapped = pfn; } }update_page_count (PG_LEVEL_2M , pages_2m);@@ -729,7 +726,7 @@ void __init setup_bootmem_allocator(voidstatic void __init find_early_table_space (unsigned long end) { -unsigned long puds, pmds, tables, start; +unsigned long puds, pmds, ptes, tables, start; puds = (end +PUD_SIZE -1 ) >>PUD_SHIFT ; tables =PAGE_ALIGN (puds *sizeof (pud_t));@@ -737,10 +734,15 @@ static void __init find_early_table_spac pmds = (end +PMD_SIZE -1 ) >>PMD_SHIFT ;
arch/x86/mm/init_32.c static void __init find_early_table_spac · line 740
Quoted 10 lines
arch/x86/mm/init_32.c +3
-4tables +=PAGE_ALIGN (pmds *sizeof (pmd_t)); -if (!cpu_has_pse) { -int ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); - } +if (cpu_has_pse) { +int extra; + extra = end - ((end>>21 ) <<21 );
That's a bit magic. Isn't that just "extra = end & ((1 << 21) - 1)"? And what are you actually computing here anyway?
arch/x86/mm/init_32.c static void __init find_early_table_spac · line 746
Quoted 2 lines
arch/x86/mm/init_32.c +1
-0+ extra += (2 <<20 );
PMD_SIZE? The comment below says "2/4MB", which corresponds to a PAE/non-PAE large PMD.
Quoted 20 lines
arch/x86/mm/init_32.c +5
-0+ ptes = (extra +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + }else + ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + + tables +=PAGE_ALIGN (ptes *sizeof (pte_t));arch/x86/mm/init_32.c +2
-0/* * RED-PEN putting page tables only on node 0 could @@ -766,6 +768,8 @@ unsigned long __init_refok init_memory_m unsigned long end) {pgd_t *pgd_base = swapper_pg_dir; +unsigned long start_pfn, end_pfn; +unsigned long big_page_start;/* * Find space for the kernel direct mapping tables. @@ -790,7 +794,41 @@ unsigned long __init_refok init_memory_m __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL; }
arch/x86/mm/init_32.c unsigned long __init_refok init_memory_m · line 804
Quoted 10 lines
arch/x86/mm/init_32.c +7
-1-kernel_physical_mapping_init (pgd_base, start, end); +/* +* Don't use a large page for the first 2/4MB of memory +* because there are often fixed size MTRRs in there +* and overlapping MTRRs into large pages can cause +* slowdowns. +*/ + big_page_start =2UL <<20 ;
PMD_SIZE again? Non-PAE big pages are 4MB.
Quoted 4 lines
arch/x86/mm/init_32.c +4
-0+if (start < big_page_start) { + start_pfn = start >>PAGE_SHIFT ; + end_pfn =min (big_page_start>>PAGE_SHIFT , end>>PAGE_SHIFT ); + }else {
arch/x86/mm/init_32.c unsigned long __init_refok init_memory_m · line 832
Quoted 10 lines
arch/x86/mm/init_32.c +9
-0+/* head is not 2M alignment ? */ + start_pfn = (start >>21 ) << (21 -PAGE_SHIFT ); + end_pfn = start >>PAGE_SHIFT ; + } +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn,0 ); + +/* big page range */ + start_pfn = ((start + ((2UL <<20 ) -1 )) >>21 ) << (21 -PAGE_SHIFT );
More magic.
Quoted 5 lines
arch/x86/mm/init_32.c +5
-0+if (start_pfn < (big_page_start >>PAGE_SHIFT )) + start_pfn = big_page_start >>PAGE_SHIFT ; + end_pfn = (end >>21 ) << (21 -PAGE_SHIFT ); +if (start_pfn < end_pfn) + kernel_physical_mapping_init(pgd_base, start_pfn, end_pfn,
arch/x86/mm/init_32.c unsigned long __init_refok init_memory_m · line 831
Quoted 10 lines
arch/x86/mm/init_32.c +10
-0+ cpu_has_pse); + +/* tail is not 2M alignment ? */ + start_pfn = end_pfn; +if (start_pfn > (big_page_start>>PAGE_SHIFT )) { + end_pfn = end >>PAGE_SHIFT ; +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, + end_pfn,0 ); + }
I think this code could do with a dose of comments and some symbolic constants. And perhaps the tactical use of round_up/down.
But it's a nice simplification of kernel_physical_mapping_init().
J
Re: [PATCH] x86: fix init_memory_mapping over boundary v2
Quoted 153 lines · Jeremy Fitzhardinge
Quoted 20 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times.
then don't overmap above themax_low_pfnv2: make
init_memory_mappingmore solid: start could be any value other than 0Signed-off-by Yinghai Lu <[email protected]>--- arch/x86/mm/init_32.c | 86 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 24 deletions(-)Index:
linux-2.6/arch/x86/mm/init_32.c
===================================================================arch/x86/mm/init_32.c static inline int is_kernel_text(unsigne · line 190
Quoted 9 lines
arch/x86/mm/init_32.c +3
-2@@ -184,8 +184,9 @@ static inline int is_kernel_text(unsigne* PAGE_OFFSET: */ static void __init kernel_physical_mapping_init (pgd_t *pgd_base, -unsigned long start, -unsigned long end) +unsigned long start_pfn, +unsigned long end_pfn, +int use_pse)Better to use bool for
use_pse.Quoted 4 lines
arch/x86/mm/init_32.c +0
-0{int pgd_idx, pmd_idx, pte_ofs;unsigned long pfn;arch/x86/mm/init_32.c static void __init kernel_physical_mappi · line 200
Quoted 10 lines
arch/x86/mm/init_32.c +2
-3@@ -193,32 +194,30 @@ static void __init kernel_physical_mappipmd_t *pmd;pte_t *pte;unsigned pages_2m =0 , pages_4k =0 ; -unsigned limit_pfn = end >>PAGE_SHIFT ; - pgd_idx =pgd_index (PAGE_OFFSET ); - pgd = pgd_base + pgd_idx; - pfn = start >>PAGE_SHIFT ; +if (!cpu_has_pse) + use_pse =0 ;What are the semantics of the
use_pseargument? Is it just a hint? If so, then the caller below should just pass a constant 1/true.Quoted 61 lines
arch/x86/mm/init_32.c +7
-4+ pfn = start_pfn; + pgd_idx =pgd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pgd = pgd_base + pgd_idx;for (; pgd_idx <PTRS_PER_PGD ; pgd++, pgd_idx++) { pmd =one_md_table_init (pgd); -if (pfn >= limit_pfn) + +if (pfn >= end_pfn)continue ; - for (pmd_idx = 0; - pmd_idx <PTRS_PER_PMD && pfn < limit_pfn; + pmd_idx =pmd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pmd += pmd_idx; +for (; pmd_idx <PTRS_PER_PMD && pfn < end_pfn; pmd++, pmd_idx++) {unsigned int addr = pfn *PAGE_SIZE +PAGE_OFFSET ;/* * Map with big pages if possible, otherwise * create normal page tables: -* -* Don't use a large page for the first 2/4MB of memory
- * because there are often fixed size MTRRs in
there
- * and overlapping MTRRs into large pages can
causearch/x86/mm/init_32.c +0
-2-* slowdowns. */ - if (cpu_has_pse && !(pgd_idx == 0 && pmd_idx ==0)) {
arch/x86/mm/init_32.c +3
-4+if (use_pse) {unsigned int addr2;pgprot_t prot =PAGE_KERNEL_LARGE ; @@ -233,13 +232,12 @@ static void __init kernel_physical_mappiset_pmd (pmd,pfn_pmd (pfn, prot)); pfn +=PTRS_PER_PTE ; - max_pfn_mapped = pfn;continue ; } pte =one_page_table_init (pmd);for (pte_ofs =0 ; - pte_ofs <PTRS_PER_PTE && pfn < max_low_pfn; + pte_ofs <PTRS_PER_PTE && pfn < end_pfn; pte++, pfn++, pte_ofs++, addr +=PAGE_SIZE ) {pgprot_t prot =PAGE_KERNEL ; @@ -249,7 +247,6 @@ static void __init kernel_physical_mappi pages_4k++;set_pte (pte,pfn_pte (pfn, prot)); } - max_pfn_mapped = pfn; } }update_page_count (PG_LEVEL_2M , pages_2m);@@ -729,7 +726,7 @@ void __init setup_bootmem_allocator(voidstatic void __init find_early_table_space (unsigned long end) { -unsigned long puds, pmds, tables, start; +unsigned long puds, pmds, ptes, tables, start; puds = (end +PUD_SIZE -1 ) >>PUD_SHIFT ; tables =PAGE_ALIGN (puds *sizeof (pud_t));arch/x86/mm/init_32.c static void __init find_early_table_spac · line 740
Quoted 10 lines
arch/x86/mm/init_32.c +3
-3@@ -737,10 +734,15 @@ static void __init find_early_table_spac pmds = (end +PMD_SIZE -1 ) >>PMD_SHIFT ; tables +=PAGE_ALIGN (pmds *sizeof (pmd_t)); - if (!cpu_has_pse) { -int ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); - } +if (cpu_has_pse) { +int extra; + extra = end - ((end>>21 ) <<21 );That's a bit magic. Isn't that just "extra = end & ((1 << 21) - 1)"? And what are you actually computing here anyway?
arch/x86/mm/init_32.c static void __init find_early_table_spac · line 746
Quoted 2 lines
arch/x86/mm/init_32.c +1
-0+ extra += (2 <<20 );
PMD_SIZE? The comment below says "2/4MB", which corresponds to a PAE/non-PAE large PMD.Quoted 21 lines
arch/x86/mm/init_32.c +9
-0+ ptes = (extra +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + }else + ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + + tables +=PAGE_ALIGN (ptes *sizeof (pte_t));/* * RED-PEN putting page tables only on node 0 could @@ -766,6 +768,8 @@ unsigned long __init_refok init_memory_m unsigned long end) {pgd_t *pgd_base = swapper_pg_dir; +unsigned long start_pfn, end_pfn; +unsigned long big_page_start;/* * Find space for the kernel direct mapping tables. @@ -790,7 +794,41 @@ unsigned long __init_refok init_memory_m __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL; } -kernel_physical_mapping_init (pgd_base, start, end); +/* +* Don't use a large page for the first 2/4MB of memory
Quoted 8 lines
arch/x86/mm/init_32.c unsigned long __init_refok init_memory_m · line 832
Quoted 6 lines
arch/x86/mm/init_32.c +5
-0+* because there are often fixed size MTRRs in there +* and overlapping MTRRs into large pages can cause +* slowdowns. +*/ + big_page_start =2UL <<20 ;
PMD_SIZEagain? Non-PAE big pages are 4MB.
thanks, I will try to revive v2...
PATCH 1/1 x86: fix init_memory_mapping over boundary v4
In reply to Yinghai Lusome end boundary is only page alignment, instead of 2M alignment, so call ker_phycial_mapping_init three times.
then don't overmap above the max_low_pfn
v2: make init_memory_mapping more solid: start could be any value other than 0
v3: fix NON PAE by handling left over in kernel_physical_mapping
v4: revert back to v2, and use PMD_SHIFT to calculate boundary
also adjust size for pre-allocated table size
--- arch/x86/mm/init_32.c | 101 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 26 deletions(-)
arch/x86/mm/init_32.c +75 -26
@@ -184,8 +184,9 @@ static inline int is_kernel_text(unsigne* PAGE_OFFSET: */ static void __init kernel_physical_mapping_init (pgd_t *pgd_base, -unsigned long start, -unsigned long end) +unsigned long start_pfn, +unsigned long end_pfn, +int use_pse) {int pgd_idx, pmd_idx, pte_ofs;unsigned long pfn;
@@ -193,32 +194,33 @@ static void __init kernel_physical_mappipmd_t *pmd;pte_t *pte;unsigned pages_2m =0 , pages_4k =0 ; -unsigned limit_pfn = end >>PAGE_SHIFT ; - pgd_idx =pgd_index (PAGE_OFFSET ); - pgd = pgd_base + pgd_idx; - pfn = start >>PAGE_SHIFT ; +if (!cpu_has_pse) + use_pse =0 ; + pfn = start_pfn; + pgd_idx =pgd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pgd = pgd_base + pgd_idx;for (; pgd_idx <PTRS_PER_PGD ; pgd++, pgd_idx++) { pmd =one_md_table_init (pgd); -if (pfn >= limit_pfn) -continue ; -for (pmd_idx =0 ; - pmd_idx <PTRS_PER_PMD && pfn < limit_pfn; +if (pfn >= end_pfn) +continue ; +#ifdef CONFIG_X86_PAE + pmd_idx =pmd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pmd += pmd_idx; +#else + pmd_idx =0 ; +#endif +for (; pmd_idx <PTRS_PER_PMD && pfn < end_pfn; pmd++, pmd_idx++) {unsigned int addr = pfn *PAGE_SIZE +PAGE_OFFSET ;/* * Map with big pages if possible, otherwise * create normal page tables: -* -* Don't use a large page for the first 2/4MB of memory -* because there are often fixed size MTRRs in there -* and overlapping MTRRs into large pages can cause -* slowdowns. */ -if (cpu_has_pse && !(pgd_idx ==0 && pmd_idx ==0 )) { +if (use_pse) {unsigned int addr2;pgprot_t prot =PAGE_KERNEL_LARGE ;
@@ -233,13 +235,13 @@ static void __init kernel_physical_mappiset_pmd (pmd,pfn_pmd (pfn, prot)); pfn +=PTRS_PER_PTE ; - max_pfn_mapped = pfn;continue ; } pte =one_page_table_init (pmd); -for (pte_ofs =0 ; - pte_ofs <PTRS_PER_PTE && pfn < max_low_pfn; + pte_ofs =pte_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pte += pte_ofs; +for (; pte_ofs <PTRS_PER_PTE && pfn < end_pfn; pte++, pfn++, pte_ofs++, addr +=PAGE_SIZE ) {pgprot_t prot =PAGE_KERNEL ;
@@ -249,7 +251,6 @@ static void __init kernel_physical_mappi pages_4k++;set_pte (pte,pfn_pte (pfn, prot)); } - max_pfn_mapped = pfn; } }update_page_count (PG_LEVEL_2M , pages_2m);
@@ -729,7 +730,7 @@ void __init setup_bootmem_allocator(voidstatic void __init find_early_table_space (unsigned long end) { -unsigned long puds, pmds, tables, start; +unsigned long puds, pmds, ptes, tables, start; puds = (end +PUD_SIZE -1 ) >>PUD_SHIFT ; tables =PAGE_ALIGN (puds *sizeof (pud_t));
@@ -737,10 +738,19 @@ static void __init find_early_table_spac pmds = (end +PMD_SIZE -1 ) >>PMD_SHIFT ; tables +=PAGE_ALIGN (pmds *sizeof (pmd_t)); -if (!cpu_has_pse) { -int ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); - } +if (cpu_has_pse) { +unsigned long extra; + + extra = end - ((end>>PMD_SHIFT ) <<PMD_SHIFT ); + extra +=PMD_SIZE ; + ptes = (extra +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + }else + ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + + tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); + +/* for fixmap */ + tables +=PAGE_SIZE *2 ;/* * RED-PEN putting page tables only on node 0 could
@@ -766,6 +776,8 @@ unsigned long __init_refok init_memory_m unsigned long end) {pgd_t *pgd_base = swapper_pg_dir; +unsigned long start_pfn, end_pfn; +unsigned long big_page_start;/* * Find space for the kernel direct mapping tables.
@@ -790,7 +802,44 @@ unsigned long __init_refok init_memory_m __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL; } -kernel_physical_mapping_init (pgd_base, start, end); +/* +* Don't use a large page for the first 2/4MB of memory +* because there are often fixed size MTRRs in there +* and overlapping MTRRs into large pages can cause +* slowdowns. +*/ + big_page_start =PMD_SIZE ; + +if (start < big_page_start) { + start_pfn = start >>PAGE_SHIFT ; + end_pfn =min (big_page_start>>PAGE_SHIFT , end>>PAGE_SHIFT ); + }else { +/* head is not big page alignment ? */ + start_pfn = start >>PAGE_SHIFT ; + end_pfn = ((start +PMD_SIZE -1 )>>PMD_SHIFT ) + << (PMD_SHIFT -PAGE_SHIFT ); + } +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn,0 ); + +/* big page range */ + start_pfn = ((start +PMD_SIZE -1 )>>PMD_SHIFT ) + << (PMD_SHIFT -PAGE_SHIFT ); +if (start_pfn < (big_page_start >>PAGE_SHIFT )) + start_pfn = big_page_start >>PAGE_SHIFT ; + end_pfn = (end>>PMD_SHIFT ) << (PMD_SHIFT -PAGE_SHIFT ); +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn, + cpu_has_pse); + +/* tail is not big page alignment ? */ + start_pfn = end_pfn; +if (start_pfn > (big_page_start>>PAGE_SHIFT )) { + end_pfn = end >>PAGE_SHIFT ; +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, + end_pfn,0 ); + }early_ioremap_page_table_range_init (pgd_base);
Re: [PATCH] x86: fix init_memory_mapping over boundary v4
Quoted 52 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times.
then don't overmap above themax_low_pfnv2: make
init_memory_mappingmore solid: start could be any value other than 0
v3: fix NON PAE by handling left over inkernel_physical_mapping
v4: revert back to v2, and usePMD_SHIFTto calculate boundary
also adjust size for pre-allocated table sizeSigned-off-by Yinghai Lu <[email protected]>--- arch/x86/mm/init_32.c | 101 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 26 deletions(-)Index:
linux-2.6/arch/x86/mm/init_32.c
===================================================================arch/x86/mm/init_32.c +8
-9@@ -184,8 +184,9 @@ static inline int is_kernel_text(unsigne* PAGE_OFFSET: */ static void __init kernel_physical_mapping_init (pgd_t *pgd_base, -unsigned long start, -unsigned long end) +unsigned long start_pfn, +unsigned long end_pfn, +int use_pse) {int pgd_idx, pmd_idx, pte_ofs;unsigned long pfn;@@ -193,32 +194,33 @@ static void __init kernel_physical_mappipmd_t *pmd;pte_t *pte;unsigned pages_2m =0 , pages_4k =0 ; -unsigned limit_pfn = end >>PAGE_SHIFT ; - pgd_idx =pgd_index (PAGE_OFFSET ); - pgd = pgd_base + pgd_idx; - pfn = start >>PAGE_SHIFT ; +if (!cpu_has_pse) + use_pse =0 ; + pfn = start_pfn; + pgd_idx =pgd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pgd = pgd_base + pgd_idx;for (; pgd_idx <PTRS_PER_PGD ; pgd++, pgd_idx++) { pmd =one_md_table_init (pgd); -if (pfn >= limit_pfn) -continue ; - for (pmd_idx = 0;
arch/x86/mm/init_32.c static void __init kernel_physical_mappi · line 215
Quoted 10 lines
arch/x86/mm/init_32.c +8
-1- pmd_idx <PTRS_PER_PMD && pfn < limit_pfn; +if (pfn >= end_pfn) +continue ; +#ifdef CONFIG_X86_PAE + pmd_idx =pmd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pmd += pmd_idx; +#else + pmd_idx =0 ; +#endif
We should really define X_index() to return 0 for folded pagetable level X. I've had to put similar #ifdefs in other code. Also, for the purposes of making this code more unifiable, it's probably better to test for "#if PAGETABLE_LEVELS >= 3" rather than for PAE specifically.
Quoted 56 lines
arch/x86/mm/init_32.c +6
-11+for (; pmd_idx <PTRS_PER_PMD && pfn < end_pfn; pmd++, pmd_idx++) {unsigned int addr = pfn *PAGE_SIZE +PAGE_OFFSET ;/* * Map with big pages if possible, otherwise * create normal page tables: -* -* Don't use a large page for the first 2/4MB of memory -* because there are often fixed size MTRRs in there -* and overlapping MTRRs into large pages can cause -* slowdowns. */ -if (cpu_has_pse && !(pgd_idx ==0 && pmd_idx ==0 )) { +if (use_pse) {unsigned int addr2;pgprot_t prot =PAGE_KERNEL_LARGE ;@@ -233,13 +235,13 @@ static void __init kernel_physical_mappiset_pmd (pmd,pfn_pmd (pfn, prot)); pfn +=PTRS_PER_PTE ; - max_pfn_mapped = pfn;continue ; } pte =one_page_table_init (pmd); -for (pte_ofs =0 ; - pte_ofs <PTRS_PER_PTE && pfn < max_low_pfn; + pte_ofs =pte_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pte += pte_ofs; +for (; pte_ofs <PTRS_PER_PTE && pfn < end_pfn; pte++, pfn++, pte_ofs++, addr +=PAGE_SIZE ) {pgprot_t prot =PAGE_KERNEL ;@@ -249,7 +251,6 @@ static void __init kernel_physical_mappi pages_4k++;set_pte (pte,pfn_pte (pfn, prot)); } - max_pfn_mapped = pfn; } }update_page_count (PG_LEVEL_2M , pages_2m);@@ -729,7 +730,7 @@ void __init setup_bootmem_allocator(voidstatic void __init find_early_table_space (unsigned long end) { -unsigned long puds, pmds, tables, start; +unsigned long puds, pmds, ptes, tables, start; puds = (end +PUD_SIZE -1 ) >>PUD_SHIFT ; tables =PAGE_ALIGN (puds *sizeof (pud_t));@@ -737,10 +738,19 @@ static void __init find_early_table_spac pmds = (end +PMD_SIZE -1 ) >>PMD_SHIFT ; tables +=PAGE_ALIGN (pmds *sizeof (pmd_t));
arch/x86/mm/init_32.c static void __init find_early_table_spac · line 746
Quoted 10 lines
arch/x86/mm/init_32.c +5
-4-if (!cpu_has_pse) { -int ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); - } +if (cpu_has_pse) { +unsigned long extra; + + extra = end - ((end>>PMD_SHIFT ) <<PMD_SHIFT ); + extra +=PMD_SIZE ;
Is this the same as "extra = (end + PMD_SIZE + 1) & PMD_MASK"?
arch/x86/mm/init_32.c static void __init find_early_table_spac · line 754
Quoted 9 lines
arch/x86/mm/init_32.c +8
-0+ ptes = (extra +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + }else + ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + + tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); + +/* for fixmap */ + tables +=PAGE_SIZE *2 ;
Why not correct for fixmaps by putting "ptes += __end_of_fixed_addresses;" above?
Quoted 48 lines
arch/x86/mm/init_32.c +0
-0/* arch/x86/mm/init_32.c +33
-1* RED-PEN putting page tables only on node 0 could @@ -766,6 +776,8 @@ unsigned long __init_refok init_memory_m unsigned long end) {pgd_t *pgd_base = swapper_pg_dir; +unsigned long start_pfn, end_pfn; +unsigned long big_page_start;/* * Find space for the kernel direct mapping tables. @@ -790,7 +802,44 @@ unsigned long __init_refok init_memory_m __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL; } -kernel_physical_mapping_init (pgd_base, start, end); +/* +* Don't use a large page for the first 2/4MB of memory +* because there are often fixed size MTRRs in there +* and overlapping MTRRs into large pages can cause +* slowdowns. +*/ + big_page_start =PMD_SIZE ; + +if (start < big_page_start) { + start_pfn = start >>PAGE_SHIFT ; + end_pfn =min (big_page_start>>PAGE_SHIFT , end>>PAGE_SHIFT ); + }else { +/* head is not big page alignment ? */ + start_pfn = start >>PAGE_SHIFT ; + end_pfn = ((start +PMD_SIZE -1 )>>PMD_SHIFT ) + << (PMD_SHIFT -PAGE_SHIFT ); + } +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn,0 ); + +/* big page range */ + start_pfn = ((start +PMD_SIZE -1 )>>PMD_SHIFT ) + << (PMD_SHIFT -PAGE_SHIFT ); +if (start_pfn < (big_page_start >>PAGE_SHIFT )) + start_pfn = big_page_start >>PAGE_SHIFT ; + end_pfn = (end>>PMD_SHIFT ) << (PMD_SHIFT -PAGE_SHIFT ); +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn, + cpu_has_pse); + +/* tail is not big page alignment ? */
arch/x86/mm/init_32.c unsigned long __init_refok init_memory_m · line 845
Quoted 10 lines
arch/x86/mm/init_32.c +7
-0+ start_pfn = end_pfn; +if (start_pfn > (big_page_start>>PAGE_SHIFT )) { + end_pfn = end >>PAGE_SHIFT ; +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, + end_pfn,0 ); + }early_ioremap_page_table_range_init (pgd_base);
J
Re: [PATCH] x86: fix init_memory_mapping over boundary v4
Quoted 60 lines · Jeremy Fitzhardinge
Quoted 59 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times.
then don't overmap above themax_low_pfnv2: make
init_memory_mappingmore solid: start could be any value other than 0
v3: fix NON PAE by handling left over inkernel_physical_mapping
v4: revert back to v2, and usePMD_SHIFTto calculate boundary
also adjust size for pre-allocated table sizeSigned-off-by Yinghai Lu <[email protected]>--- arch/x86/mm/init_32.c | 101 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 26 deletions(-)Index:
linux-2.6/arch/x86/mm/init_32.c
===================================================================arch/x86/mm/init_32.c +13
-8@@ -184,8 +184,9 @@ static inline int is_kernel_text(unsigne* PAGE_OFFSET: */ static void __init kernel_physical_mapping_init (pgd_t *pgd_base, -unsigned long start, -unsigned long end) +unsigned long start_pfn, +unsigned long end_pfn, +int use_pse) {int pgd_idx, pmd_idx, pte_ofs;unsigned long pfn;@@ -193,32 +194,33 @@ static void __init kernel_physical_mappipmd_t *pmd;pte_t *pte;unsigned pages_2m =0 , pages_4k =0 ; -unsigned limit_pfn = end >>PAGE_SHIFT ; - pgd_idx =pgd_index (PAGE_OFFSET ); - pgd = pgd_base + pgd_idx; - pfn = start >>PAGE_SHIFT ; +if (!cpu_has_pse) + use_pse =0 ; + pfn = start_pfn; + pgd_idx =pgd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pgd = pgd_base + pgd_idx;for (; pgd_idx <PTRS_PER_PGD ; pgd++, pgd_idx++) { pmd =one_md_table_init (pgd); -if (pfn >= limit_pfn) -continue ; - for (pmd_idx = 0; - pmd_idx <PTRS_PER_PMD && pfn < limit_pfn; +if (pfn >= end_pfn) +continue ; +#ifdef CONFIG_X86_PAE + pmd_idx =pmd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pmd += pmd_idx; +#else
Quoted 8 lines
arch/x86/mm/init_32.c static void __init kernel_physical_mappi · line 218
Quoted 3 lines
arch/x86/mm/init_32.c +2
-0+ pmd_idx =0 ; +#endif We should really define
X_index()to return 0 for folded pagetable level X.
I've had to put similar #ifdefs in other code. Also, for the purposes of
making this code more unifiable, it's probably better to test for "#ifPAGETABLE_LEVELS>= 3" rather than for PAE specifically.
does all cpu support >=3?
Quoted 54 lines
Quoted 54 lines
arch/x86/mm/init_32.c +1
-2+for (; pmd_idx <PTRS_PER_PMD && pfn < end_pfn; pmd++, pmd_idx++) {unsigned int addr = pfn *PAGE_SIZE +PAGE_OFFSET ;/* * Map with big pages if possible, otherwise * create normal page tables: -* -* Don't use a large page for the first 2/4MB of memory
- * because there are often fixed size MTRRs in
there
- * and overlapping MTRRs into large pages can
causearch/x86/mm/init_32.c +0
-2-* slowdowns. */ - if (cpu_has_pse && !(pgd_idx == 0 && pmd_idx ==0)) {
arch/x86/mm/init_32.c +2
-2+if (use_pse) {unsigned int addr2;pgprot_t prot =PAGE_KERNEL_LARGE ; @@ -233,13 +235,13 @@ static void __init kernel_physical_mappiset_pmd (pmd,pfn_pmd (pfn, prot)); pfn +=PTRS_PER_PTE ; - max_pfn_mapped = pfn;continue ; } pte =one_page_table_init (pmd); - for (pte_ofs = 0; - pte_ofs <PTRS_PER_PTE && pfn < max_low_pfn; + pte_ofs = pte_index((pfn<<PAGE_SHIFT) +
PAGE_OFFSET);arch/x86/mm/init_32.c +3
-2+ pte += pte_ofs; +for (; pte_ofs <PTRS_PER_PTE && pfn < end_pfn; pte++, pfn++, pte_ofs++, addr +=PAGE_SIZE ) {pgprot_t prot =PAGE_KERNEL ; @@ -249,7 +251,6 @@ static void __init kernel_physical_mappi pages_4k++;set_pte (pte,pfn_pte (pfn, prot)); } - max_pfn_mapped = pfn; } }update_page_count (PG_LEVEL_2M , pages_2m);@@ -729,7 +730,7 @@ void __init setup_bootmem_allocator(voidstatic void __init find_early_table_space (unsigned long end) { -unsigned long puds, pmds, tables, start; +unsigned long puds, pmds, ptes, tables, start; puds = (end +PUD_SIZE -1 ) >>PUD_SHIFT ; tables =PAGE_ALIGN (puds *sizeof (pud_t));@@ -737,10 +738,19 @@ static void __init find_early_table_spac pmds = (end +PMD_SIZE -1 ) >>PMD_SHIFT ; tables +=PAGE_ALIGN (pmds *sizeof (pmd_t));
Quoted 8 lines
arch/x86/mm/init_32.c static void __init find_early_table_spac · line 744
Quoted 8 lines
arch/x86/mm/init_32.c +4
-3- if (!cpu_has_pse) { -int ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; - tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); - } +if (cpu_has_pse) { +unsigned long extra; + + extra = end - ((end>>PMD_SHIFT ) <<PMD_SHIFT );
left over at tail
Quoted 1 line
arch/x86/mm/init_32.c static void __init find_early_table_spac · line 745
Quoted 1 line
arch/x86/mm/init_32.c +1
-0+ extra +=PMD_SIZE ;
head...
Quoted 3 lines
Quoted 1 line
Is this the same as "extra = (end +
PMD_SIZE+ 1) &PMD_MASK"?
extra = end & PMD_MASK;
extra+ = PMD_SIZE;
;
Quoted 13 lines
arch/x86/mm/init_32.c static void __init find_early_table_spac · line 753
Quoted 10 lines
arch/x86/mm/init_32.c +8
-0+ ptes = (extra +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + }else + ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; + + tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); + +/* for fixmap */ + tables +=PAGE_SIZE *2 ;Why not correct for fixmaps by putting "ptes +=
__end_of_fixed_addresses;" above?
yes
YH
Re: [PATCH] x86: fix init_memory_mapping over boundary v4
Quoted 8 lines · Yinghai Lu
Quoted 5 lines
We should really define
X_index()to return 0 for folded pagetable level X.
I've had to put similar #ifdefs in other code. Also, for the purposes of
making this code more unifiable, it's probably better to test for "#ifPAGETABLE_LEVELS>= 3" rather than for PAE specifically.does all cpu support >=3?
Well, x86 32-bit PAE is 3 level, and 64-bit is 4 level; both have a meaningful set of pmd operations.
Quoted 7 lines
Quoted 3 lines
Is this the same as "extra = (end +
PMD_SIZE+ 1) &PMD_MASK"?extra = end &
PMD_MASK;
extra+ =PMD_SIZE;
OK. I wasn't sure if your intent was to round up to the next PMD_SIZE or add a whole new PMD_SIZE.
J
Re: [PATCH] x86: fix init_memory_mapping over boundary v4
In reply to Yinghai LuQuoted 8 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times.
then don't overmap above themax_low_pfnv2: make
init_memory_mappingmore solid: start could be any value other than 0
v3: fix NON PAE by handling left over inkernel_physical_mapping
v4: revert back to v2, and usePMD_SHIFTto calculate boundary
also adjust size for pre-allocated table size
i've got v3 applied to tip/master and it worked well in testing - on the old, 512m RAM problem laptop too. So could you send v4 as a delta patch instead please, against tip/master?
Ingo
Re: [PATCH] x86: fix init_memory_mapping over boundary v4
Quoted 7 lines · Ingo Molnar
Quoted 4 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times.
then don't overmap above themax_low_pfn
Quoted 8 lines
Quoted 4 lines
v2: make
init_memory_mappingmore solid: start could be any value other than 0
v3: fix NON PAE by handling left over inkernel_physical_mapping
v4: revert back to v2, and usePMD_SHIFTto calculate boundary
also adjust size for pre-allocated table sizei've got v3 applied to tip/master and it worked well in testing - on the old, 512m RAM problem laptop too. So could you send v4 as a delta patch instead please, against tip/master?
will. before that delta patch please do test on your 512M system .
YH
Re: [PATCH] x86: fix init_memory_mapping over boundary v4
Quoted 13 lines · Yinghai Lu
Quoted 12 lines · Ingo Molnar
Quoted 8 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times.
then don't overmap above themax_low_pfnv2: make
init_memory_mappingmore solid: start could be any value other than 0
v3: fix NON PAE by handling left over inkernel_physical_mapping
v4: revert back to v2, and usePMD_SHIFTto calculate boundary
also adjust size for pre-allocated table size
Quoted 5 lines
Quoted 3 lines
i've got v3 applied to tip/master and it worked well in testing - on the old, 512m RAM problem laptop too. So could you send v4 as a delta patch instead please, against tip/master?
will. before that delta patch please do test on your 512M system .
i've tested it thoroughly on all systems over the weekend and it's all fine now. Thanks,
Ingo
PATCH 1/1 x86: fix init_memory_mapping over boundary v4 - diff to v3
In reply to Yinghai Lusome end boundary is only page alignment, instead of 2M alignment, so call ker_phycial_mapping_init three times.
then don't overmap above the max_low_pfn
v2: make init_memory_mapping more solid: start could be any value other than 0
v3: fix NON PAE by handling left over in kernel_physical_mapping
v4: revert back to v2, and use PMD_SHIFT to calculate boundary
also adjust size for pre-allocated table size
--- arch/x86/mm/init_32.c | 89 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 22 deletions(-)
arch/x86/mm/init_32.c +67 -22
@@ -184,8 +184,9 @@ static inline int is_kernel_text(unsigne* PAGE_OFFSET: */ static void __init kernel_physical_mapping_init (pgd_t *pgd_base, -unsigned long start, -unsigned long end) +unsigned long start_pfn, +unsigned long end_pfn, +int use_pse) {int pgd_idx, pmd_idx, pte_ofs;unsigned long pfn;
@@ -193,33 +194,33 @@ static void __init kernel_physical_mappipmd_t *pmd;pte_t *pte;unsigned pages_2m =0 , pages_4k =0 ; -unsigned limit_pfn = end >>PAGE_SHIFT ; - pgd_idx =pgd_index (start +PAGE_OFFSET ); - pgd = pgd_base + pgd_idx; - pfn = start >>PAGE_SHIFT ; +if (!cpu_has_pse) + use_pse =0 ; + pfn = start_pfn; + pgd_idx =pgd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pgd = pgd_base + pgd_idx;for (; pgd_idx <PTRS_PER_PGD ; pgd++, pgd_idx++) { pmd =one_md_table_init (pgd); -if (pfn >= limit_pfn) -continue ; -for (pmd_idx =0 ; - pmd_idx <PTRS_PER_PMD && pfn < limit_pfn; +if (pfn >= end_pfn) +continue ; +#ifdef CONFIG_X86_PAE + pmd_idx =pmd_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pmd += pmd_idx; +#else + pmd_idx =0 ; +#endif +for (; pmd_idx <PTRS_PER_PMD && pfn < end_pfn; pmd++, pmd_idx++) {unsigned int addr = pfn *PAGE_SIZE +PAGE_OFFSET ;/* * Map with big pages if possible, otherwise * create normal page tables: -* -* Don't use a large page for the first 2/4MB of memory -* because there are often fixed size MTRRs in there -* and overlapping MTRRs into large pages can cause -* slowdowns. */ -if (cpu_has_pse && !(pgd_idx ==0 && pmd_idx ==0 ) && - (pfn +PTRS_PER_PTE ) <= limit_pfn) { +if (use_pse) {unsigned int addr2;pgprot_t prot =PAGE_KERNEL_LARGE ;
@@ -238,8 +239,9 @@ static void __init kernel_physical_mappi } pte =one_page_table_init (pmd); -for (pte_ofs =0 ; - pte_ofs <PTRS_PER_PTE && pfn < limit_pfn; + pte_ofs =pte_index ((pfn<<PAGE_SHIFT ) +PAGE_OFFSET ); + pte += pte_ofs; +for (; pte_ofs <PTRS_PER_PTE && pfn < end_pfn; pte++, pfn++, pte_ofs++, addr +=PAGE_SIZE ) {pgprot_t prot =PAGE_KERNEL ;
@@ -738,14 +740,18 @@ static void __init find_early_table_spacif (cpu_has_pse) {unsigned long extra; - extra = end - ((end>>21 ) <<21 ); - extra += (2UL <<20 ); + + extra = end - ((end>>PMD_SHIFT ) <<PMD_SHIFT ); + extra +=PMD_SIZE ; ptes = (extra +PAGE_SIZE -1 ) >>PAGE_SHIFT ; }else ptes = (end +PAGE_SIZE -1 ) >>PAGE_SHIFT ; tables +=PAGE_ALIGN (ptes *sizeof (pte_t)); +/* for fixmap */ + tables +=PAGE_SIZE *2 ; +/* * RED-PEN putting page tables only on node 0 could * cause a hotspot and fill up ZONE_DMA. The page tables
@@ -770,6 +776,8 @@ unsigned long __init_refok init_memory_m unsigned long end) {pgd_t *pgd_base = swapper_pg_dir; +unsigned long start_pfn, end_pfn; +unsigned long big_page_start;/* * Find space for the kernel direct mapping tables.
@@ -794,7 +802,44 @@ unsigned long __init_refok init_memory_m __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL; } -kernel_physical_mapping_init (pgd_base, start, end); +/* +* Don't use a large page for the first 2/4MB of memory +* because there are often fixed size MTRRs in there +* and overlapping MTRRs into large pages can cause +* slowdowns. +*/ + big_page_start =PMD_SIZE ; + +if (start < big_page_start) { + start_pfn = start >>PAGE_SHIFT ; + end_pfn =min (big_page_start>>PAGE_SHIFT , end>>PAGE_SHIFT ); + }else { +/* head is not big page alignment ? */ + start_pfn = start >>PAGE_SHIFT ; + end_pfn = ((start + (PMD_SIZE -1 ))>>PMD_SHIFT ) + << (PMD_SHIFT -PAGE_SHIFT ); + } +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn,0 ); + +/* big page range */ + start_pfn = ((start + (PMD_SIZE -1 ))>>PMD_SHIFT ) + << (PMD_SHIFT -PAGE_SHIFT ); +if (start_pfn < (big_page_start >>PAGE_SHIFT )) + start_pfn = big_page_start >>PAGE_SHIFT ; + end_pfn = (end>>PMD_SHIFT ) << (PMD_SHIFT -PAGE_SHIFT ); +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, end_pfn, + cpu_has_pse); + +/* tail is not big page alignment ? */ + start_pfn = end_pfn; +if (start_pfn > (big_page_start>>PAGE_SHIFT )) { + end_pfn = end >>PAGE_SHIFT ; +if (start_pfn < end_pfn) +kernel_physical_mapping_init (pgd_base, start_pfn, + end_pfn,0 ); + }early_ioremap_page_table_range_init (pgd_base);
Ingo Molnar
AppliedRe: [PATCH] x86: fix init_memory_mapping over boundary v4 - diff to v3
Quoted 8 lines · Yinghai Lu
some end boundary is only page alignment, instead of 2M alignment, so call
ker_phycial_mapping_initthree times.
then don't overmap above themax_low_pfnv2: make
init_memory_mappingmore solid: start could be any value other than 0
v3: fix NON PAE by handling left over inkernel_physical_mapping
v4: revert back to v2, and usePMD_SHIFTto calculate boundary
also adjust size for pre-allocated table size
applied, thanks Yinghai.
Ingo
PATCH 1/1 x86: fix warning in e820_reserve_resources with 32bit
In reply to Yinghai Luwhen 64bit resource is not enabled, got:
arch/x86/kernel/e820.c: In function ‘e820_reserve_resources’:arch/x86/kernel/e820.c:1217: warning: comparison is always false due to limited range of data type
because res->start/end is resource_t aka u32. it will overflow.
fix it with temp end of u64
arch/x86/kernel/e820.c +6 -3
@@ -1202,6 +1202,7 @@ void __init e820_reserve_resources(void) {int i;struct resource *res; +u64 end; res =alloc_bootmem_low (sizeof (struct resource ) * e820.nr_map);for (i =0 ; i < e820.nr_map; i++) {
@@ -1211,14 +1212,16 @@ void __init e820_reserve_resources(void)case E820_NVS : res->name ="ACPI Non-volatile Storage" ;break ;default : res->name ="reserved" ; } - res->start = e820.map[i].addr; - res->end = res->start + e820.map[i].size -1 ; + end = e820.map[i].addr + e820.map[i].size -1 ;#ifndef CONFIG_RESOURCES_64BIT -if (res->end >0x100000000ULL ) { +if (end >0x100000000ULL ) { res++;continue ; }#endif + res->start = e820.map[i].addr; + res->end = end; + res->flags =IORESOURCE_MEM |IORESOURCE_BUSY ;insert_resource (&iomem_resource, res); res++;
Ingo Molnar
AppliedRe: [PATCH] x86: fix warning in e820_reserve_resources with 32bit
Quoted 8 lines · Yinghai Lu
when 64bit resource is not enabled, got:
arch/x86/kernel/e820.c: In function ‘e820_reserve_resources’:arch/x86/kernel/e820.c:1217: warning: comparison is always false due to limited range of data typebecause res->start/end is
resource_taka u32. it will overflow.fix it with temp end of u64
applied, thanks.
Ingo
Ingo Molnar
AppliedQuoted 5 lines · Yinghai Lu
please check the patches
it will rename
setup.ctosetup_percpu.cand makesetup_32.cto support 64bit, and then changesetup_32.ctosetup.cand deletesetup_64.c.
applied them to tip/x86/unify-setup:
Yinghai Lu (17):
x86: fix memory setup bug
x86: rename setup.c to setup_percpu.c
x86: we can use full bootmem after have init_memory_mapping
x86: update reserve_initrd to support 64bit
x86: put global variable for 32bit all together
x86: add extra includes for 64bit support
x86: merge 64bit setup_arch into setup_32
x86: space to tab in setup_arch
x86: rename setup_32.c to setup.c
x86: move boot_params back to setup.c
x86: move parse_setup_data back to setup.c
x86: move back crashkernel back to setup.c
x86: move reserve_standard_io_resources back to setup.c
x86: move parse elfvorehdr back to setup.c
x86: make x86_find_smp_config depends on 64 bit too
x86: change some functions in setup.c to static
x86: we only have init_pg_tables_end for 32bit
thanks Yinghai.
Ingo
Quoted 1 line · Ingo Molnar
x86: rename
setup.ctosetup_percpu.c
this brought a build failure:
arch/x86/kernel/setup.c: In function ‘setup_arch':
arch/x86/kernel/setup.c:561: error: implicit declaration of function ‘efi_reserve_early'
09865f3049050458a5c236e5b4630f137d9b179d is first bad commit commit 09865f3049050458a5c236e5b4630f137d9b179d
Author: Yinghai Lu <[email protected]> Date: Wed Jun 25 17:48:14 2008 -0700
x86: rename setup.c to setup_percpu.c
we lost an asm/efi.h include. (which, a bit illogically, is not implicit via the existing linux/efi.h include.) Fixed below.
Ingo
-------------->
commit 9faea5db92f5ff3b39e7b66656f847dcb9618caa
Author: Ingo Molnar <[email protected]> Date: Thu Jun 26 12:02:01 2008 +0200
x86: build fix
fix:
arch/x86/kernel/setup.c: In function ‘setup_arch':
arch/x86/kernel/setup.c:561: error: implicit declaration of function ‘efi_reserve_early'
arch/x86/kernel/setup.c +1 -0
@@ -79,6 +79,7 @@#include <asm/mpspec.h> #include <asm/setup.h> #include <asm/arch_hooks.h> +#include <asm/efi.h> #include <asm/sections.h> #include <asm/dmi.h> #include <asm/io_apic.h>
Quoted 41 lines · Ingo Molnar
Quoted 1 line · Ingo Molnar
x86: rename
setup.ctosetup_percpu.cthis brought a build failure:
arch/x86/kernel/setup.c: In function 'setup_arch':
arch/x86/kernel/setup.c:561: error: implicit declaration of function 'efi_reserve_early'
09865f3049050458a5c236e5b4630f137d9b179dis first bad commit commit09865f3049050458a5c236e5b4630f137d9b179dAuthor: Yinghai Lu <[email protected]> Date: Wed Jun 25 17:48:14 2008 -0700x86: rename
setup.ctosetup_percpu.cwe lost an
asm/efi.hinclude. (which, a bit illogically, is not implicit via the existinglinux/efi.hinclude.) Fixed below.Ingo
-------------->
commit9faea5db92f5ff3b39e7b66656f847dcb9618caaAuthor: Ingo Molnar <[email protected]> Date: Thu Jun 26 12:02:01 2008 +0200x86: build fix
fix:
arch/x86/kernel/setup.c: In function 'setup_arch':
arch/x86/kernel/setup.c:561: error: implicit declaration of function 'efi_reserve_early'Signed-off-by Ingo Molnar <[email protected]>arch/x86/kernel/setup.c +0
-0
arch/x86/kernel/setup.c line 85
Quoted 7 lines
arch/x86/kernel/setup.c +1
-0@@ -79,6 +79,7 @@#include <asm/mpspec.h> #include <asm/setup.h> #include <asm/arch_hooks.h> +#include <asm/efi.h> #include <asm/sections.h> #include <asm/dmi.h> #include <asm/io_apic.h>
checkpatch.pl want me to remove that.
YH
Quoted 9 lines · Yinghai Lu
Quoted 7 lines
#include <
asm/mpspec.h>
#include <asm/setup.h>
#include <asm/arch_hooks.h>
+#include <asm/efi.h>
#include <asm/sections.h>
#include <asm/dmi.h>
#include <asm/io_apic.h>checkpatch.pl want me to remove that.
checkpatch.pl is right about that, but the proper fix would be to decode this dependency - why isnt it enough to include linux/efi.h?
Ingo
Quoted 10 lines · Ingo Molnar
Quoted 8 lines · Yinghai Lu
Quoted 7 lines
#include <
asm/mpspec.h>
#include <asm/setup.h>
#include <asm/arch_hooks.h>
+#include <asm/efi.h>
#include <asm/sections.h>
#include <asm/dmi.h>
#include <asm/io_apic.h>
Quoted 4 lines
Quoted 1 line
checkpatch.pl want me to remove that.
checkpatch.pl is right about that, but the proper fix would be to decode this dependency - why isnt it enough to include
linux/efi.h?
There is one dependency for asm/efi.h: declaration of efi_reserve_early(). This declaration can be moved to linux/efi.h, maybe after being renamed to efi_reserve_memmap().
Best Regards,
Huang Ying