ia64/linux-2.6.18-xen.hg

changeset 640:9c730ffb48f7

linux/x86: fix issues with the assignment of huge amounts of memory

At the same time remove the non-applicable and broken support for the
memmap= command line option.
Also fix the overlap of the modules area with the fixmaps on x86-64.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Aug 08 14:24:33 2008 +0100 (2008-08-08)
parents abcb2a10ff2f
children 56902bb0ce6d
files arch/i386/kernel/setup-xen.c arch/x86_64/kernel/e820-xen.c arch/x86_64/kernel/setup-xen.c arch/x86_64/mm/init-xen.c drivers/xen/core/machine_reboot.c include/asm-x86_64/mach-xen/asm/pgtable.h
line diff
     1.1 --- a/arch/i386/kernel/setup-xen.c	Fri Aug 08 14:22:52 2008 +0100
     1.2 +++ b/arch/i386/kernel/setup-xen.c	Fri Aug 08 14:24:33 2008 +0100
     1.3 @@ -405,7 +405,7 @@ shared_info_t *HYPERVISOR_shared_info = 
     1.4  EXPORT_SYMBOL(HYPERVISOR_shared_info);
     1.5  
     1.6  unsigned long *phys_to_machine_mapping;
     1.7 -unsigned long *pfn_to_mfn_frame_list_list, *pfn_to_mfn_frame_list[16];
     1.8 +unsigned long *pfn_to_mfn_frame_list_list, **pfn_to_mfn_frame_list;
     1.9  EXPORT_SYMBOL(phys_to_machine_mapping);
    1.10  
    1.11  /* Raw start-of-day parameters from the hypervisor. */
    1.12 @@ -831,6 +831,7 @@ static void __init parse_cmdline_early (
    1.13  			}
    1.14  		}
    1.15  
    1.16 +#ifndef CONFIG_XEN
    1.17  		else if (!memcmp(from, "memmap=", 7)) {
    1.18  			if (to != command_line)
    1.19  				to--;
    1.20 @@ -872,6 +873,7 @@ static void __init parse_cmdline_early (
    1.21  				}
    1.22  			}
    1.23  		}
    1.24 +#endif
    1.25  
    1.26  		else if (!memcmp(from, "noexec=", 7))
    1.27  			noexec_setup(from + 7);
    1.28 @@ -1617,7 +1619,7 @@ void __init setup_arch(char **cmdline_p)
    1.29  	int i, j, k, fpp;
    1.30  	struct physdev_set_iopl set_iopl;
    1.31  	unsigned long max_low_pfn;
    1.32 -	unsigned long p2m_pages;
    1.33 +	unsigned long p2m_pages, size;
    1.34  
    1.35  	/* Force a quick death if the kernel panics (not domain 0). */
    1.36  	extern int panic_timeout;
    1.37 @@ -1779,11 +1781,11 @@ void __init setup_arch(char **cmdline_p)
    1.38  	if (!xen_feature(XENFEAT_auto_translated_physmap)) {
    1.39  		phys_to_machine_mapping = alloc_bootmem_low_pages(
    1.40  		     max_pfn * sizeof(unsigned long));
    1.41 -		memset(phys_to_machine_mapping, ~0,
    1.42 -		       max_pfn * sizeof(unsigned long));
    1.43  		memcpy(phys_to_machine_mapping,
    1.44  		       (unsigned long *)xen_start_info->mfn_list,
    1.45  		       p2m_pages * sizeof(unsigned long));
    1.46 +		memset(phys_to_machine_mapping + p2m_pages, ~0,
    1.47 +		       (max_pfn - p2m_pages) * sizeof(unsigned long));
    1.48  		free_bootmem(
    1.49  		     __pa(xen_start_info->mfn_list),
    1.50  		     PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
    1.51 @@ -1793,13 +1795,18 @@ void __init setup_arch(char **cmdline_p)
    1.52  		 * Initialise the list of the frames that specify the list of
    1.53  		 * frames that make up the p2m table. Used by save/restore
    1.54  		 */
    1.55 -		pfn_to_mfn_frame_list_list = alloc_bootmem_low_pages(PAGE_SIZE);
    1.56 +		fpp = PAGE_SIZE/sizeof(unsigned long);
    1.57 +		size = (max_pfn + fpp - 1) / fpp;
    1.58 +		size = (size + fpp - 1) / fpp;
    1.59 +		size *= sizeof(unsigned long);
    1.60 +		BUG_ON(size > PAGE_SIZE);
    1.61 +		pfn_to_mfn_frame_list_list = alloc_bootmem_low_pages(size);
    1.62 +		pfn_to_mfn_frame_list = alloc_bootmem_low(size);
    1.63  
    1.64 -		fpp = PAGE_SIZE/sizeof(unsigned long);
    1.65  		for (i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++) {
    1.66  			if ((j % fpp) == 0) {
    1.67  				k++;
    1.68 -				BUG_ON(k>=16);
    1.69 +				BUG_ON(k * sizeof(unsigned long) >= size);
    1.70  				pfn_to_mfn_frame_list[k] =
    1.71  					alloc_bootmem_low_pages(PAGE_SIZE);
    1.72  				pfn_to_mfn_frame_list_list[k] =
     2.1 --- a/arch/x86_64/kernel/e820-xen.c	Fri Aug 08 14:22:52 2008 +0100
     2.2 +++ b/arch/x86_64/kernel/e820-xen.c	Fri Aug 08 14:24:33 2008 +0100
     2.3 @@ -703,6 +703,24 @@ void __init parse_memopt(char *p, char *
     2.4  	i = e820.nr_map-1;
     2.5  	current_end = e820.map[i].addr + e820.map[i].size;
     2.6  
     2.7 +	/*
     2.8 +	 * A little less than 2% of available memory are needed for page
     2.9 +	 * tables, p2m map, and mem_map. Hence the maximum amount of memory
    2.10 +	 * we can potentially balloon up to cannot exceed about 50 times
    2.11 +	 * what we've been given initially.
    2.12 +	 */
    2.13 +#define PAGE_OVERHEAD (PAGE_SIZE \
    2.14 +		       / (sizeof(pte_t) + sizeof(long) + sizeof(struct page)))
    2.15 +	if (end_user_pfn / (PAGE_OVERHEAD - 1) > xen_start_info->nr_pages) {
    2.16 +		end = (xen_start_info->nr_pages * (PAGE_OVERHEAD - 1))
    2.17 +		      << PAGE_SHIFT;
    2.18 +		printk(KERN_WARNING "mem=%lu is invalid for an initial"
    2.19 +				    " allocation of %lu, using %lu\n",
    2.20 +		       end_user_pfn << PAGE_SHIFT,
    2.21 +		       xen_start_info->nr_pages << PAGE_SHIFT, end);
    2.22 +		end_user_pfn = end >> PAGE_SHIFT;
    2.23 +	}
    2.24 +
    2.25  	if (current_end < end) {
    2.26  		/*
    2.27                   * The e820 map ends before our requested size so
    2.28 @@ -715,6 +733,7 @@ void __init parse_memopt(char *p, char *
    2.29  	}
    2.30  } 
    2.31  
    2.32 +#ifndef CONFIG_XEN
    2.33  void __init parse_memmapopt(char *p, char **from)
    2.34  {
    2.35  	unsigned long long start_at, mem_size;
    2.36 @@ -735,6 +754,7 @@ void __init parse_memmapopt(char *p, cha
    2.37  	}
    2.38  	p = *from;
    2.39  }
    2.40 +#endif
    2.41  
    2.42  unsigned long pci_mem_start = 0xaeedbabe;
    2.43  EXPORT_SYMBOL(pci_mem_start);
     3.1 --- a/arch/x86_64/kernel/setup-xen.c	Fri Aug 08 14:22:52 2008 +0100
     3.2 +++ b/arch/x86_64/kernel/setup-xen.c	Fri Aug 08 14:24:33 2008 +0100
     3.3 @@ -97,7 +97,7 @@ static struct notifier_block xen_panic_b
     3.4  };
     3.5  
     3.6  unsigned long *phys_to_machine_mapping;
     3.7 -unsigned long *pfn_to_mfn_frame_list_list, *pfn_to_mfn_frame_list[512];
     3.8 +unsigned long *pfn_to_mfn_frame_list_list, **pfn_to_mfn_frame_list;
     3.9  
    3.10  EXPORT_SYMBOL(phys_to_machine_mapping);
    3.11  
    3.12 @@ -419,6 +419,7 @@ static __init void parse_cmdline_early (
    3.13  		if (!memcmp(from, "mem=", 4))
    3.14  			parse_memopt(from+4, &from); 
    3.15  
    3.16 +#ifndef CONFIG_XEN
    3.17  		if (!memcmp(from, "memmap=", 7)) {
    3.18  			/* exactmap option is for used defined memory */
    3.19  			if (!memcmp(from+7, "exactmap", 8)) {
    3.20 @@ -440,6 +441,7 @@ static __init void parse_cmdline_early (
    3.21  				userdef = 1;
    3.22  			}
    3.23  		}
    3.24 +#endif
    3.25  
    3.26  #ifdef CONFIG_NUMA
    3.27  		if (!memcmp(from, "numa=", 5))
    3.28 @@ -776,7 +778,7 @@ void __init setup_arch(char **cmdline_p)
    3.29  #ifdef CONFIG_XEN
    3.30  	{
    3.31  		int i, j, k, fpp;
    3.32 -		unsigned long p2m_pages;
    3.33 +		unsigned long p2m_pages, size;
    3.34  
    3.35  		p2m_pages = end_pfn;
    3.36  		if (xen_start_info->nr_pages > end_pfn) {
    3.37 @@ -808,11 +810,11 @@ void __init setup_arch(char **cmdline_p)
    3.38  			/* Make sure we have a large enough P->M table. */
    3.39  			phys_to_machine_mapping = alloc_bootmem_pages(
    3.40  				end_pfn * sizeof(unsigned long));
    3.41 -			memset(phys_to_machine_mapping, ~0,
    3.42 -			       end_pfn * sizeof(unsigned long));
    3.43  			memcpy(phys_to_machine_mapping,
    3.44  			       (unsigned long *)xen_start_info->mfn_list,
    3.45  			       p2m_pages * sizeof(unsigned long));
    3.46 +			memset(phys_to_machine_mapping + p2m_pages, ~0,
    3.47 +			       (end_pfn - p2m_pages) * sizeof(unsigned long));
    3.48  			free_bootmem(
    3.49  				__pa(xen_start_info->mfn_list),
    3.50  				PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
    3.51 @@ -823,13 +825,22 @@ void __init setup_arch(char **cmdline_p)
    3.52  			 * list of frames that make up the p2m table. Used by
    3.53                           * save/restore.
    3.54  			 */
    3.55 -			pfn_to_mfn_frame_list_list = alloc_bootmem_pages(PAGE_SIZE);
    3.56 +			fpp = PAGE_SIZE/sizeof(unsigned long);
    3.57 +			size = (max_pfn + fpp - 1) / fpp;
    3.58 +			size = (size + fpp - 1) / fpp;
    3.59 +			size *= sizeof(unsigned long);
    3.60 +			pfn_to_mfn_frame_list_list = alloc_bootmem_pages(size);
    3.61 +			if (size > PAGE_SIZE
    3.62 +			    && xen_create_contiguous_region((unsigned long)
    3.63 +							    pfn_to_mfn_frame_list_list,
    3.64 +							    get_order(size), 0))
    3.65 +				BUG();
    3.66 +			pfn_to_mfn_frame_list = alloc_bootmem(size);
    3.67  
    3.68 -			fpp = PAGE_SIZE/sizeof(unsigned long);
    3.69  			for (i=0, j=0, k=-1; i< end_pfn; i+=fpp, j++) {
    3.70  				if ((j % fpp) == 0) {
    3.71  					k++;
    3.72 -					BUG_ON(k>=fpp);
    3.73 +					BUG_ON(k * sizeof(unsigned long) >= size);
    3.74  					pfn_to_mfn_frame_list[k] =
    3.75  						alloc_bootmem_pages(PAGE_SIZE);
    3.76  					pfn_to_mfn_frame_list_list[k] =
     4.1 --- a/arch/x86_64/mm/init-xen.c	Fri Aug 08 14:22:52 2008 +0100
     4.2 +++ b/arch/x86_64/mm/init-xen.c	Fri Aug 08 14:24:33 2008 +0100
     4.3 @@ -610,6 +610,13 @@ static void __init extend_init_mapping(u
     4.4  	while (va < (__START_KERNEL_map
     4.5  		     + (start_pfn << PAGE_SHIFT)
     4.6  		     + tables_space)) {
     4.7 +		if (!pmd_index(va) && !pte_index(va)) {
     4.8 +			page = (unsigned long *)init_level4_pgt;
     4.9 +			addr = page[pgd_index(va)];
    4.10 +			addr_to_page(addr, page);
    4.11 +			addr = page[pud_index(va)];
    4.12 +			addr_to_page(addr, page);
    4.13 +		}
    4.14  		pmd = (pmd_t *)&page[pmd_index(va)];
    4.15  		if (pmd_none(*pmd)) {
    4.16  			pte_page = alloc_static_page(&phys);
     5.1 --- a/drivers/xen/core/machine_reboot.c	Fri Aug 08 14:22:52 2008 +0100
     5.2 +++ b/drivers/xen/core/machine_reboot.c	Fri Aug 08 14:24:33 2008 +0100
     5.3 @@ -74,7 +74,7 @@ static void post_suspend(int suspend_can
     5.4  	unsigned long shinfo_mfn;
     5.5  	extern unsigned long max_pfn;
     5.6  	extern unsigned long *pfn_to_mfn_frame_list_list;
     5.7 -	extern unsigned long *pfn_to_mfn_frame_list[];
     5.8 +	extern unsigned long **pfn_to_mfn_frame_list;
     5.9  
    5.10  	if (suspend_cancelled) {
    5.11  		xen_start_info->store_mfn =
     6.1 --- a/include/asm-x86_64/mach-xen/asm/pgtable.h	Fri Aug 08 14:22:52 2008 +0100
     6.2 +++ b/include/asm-x86_64/mach-xen/asm/pgtable.h	Fri Aug 08 14:24:33 2008 +0100
     6.3 @@ -135,11 +135,11 @@ static inline void pgd_clear (pgd_t * pg
     6.4  #define FIRST_USER_ADDRESS	0
     6.5  
     6.6  #ifndef __ASSEMBLY__
     6.7 -#define MAXMEM		 0x3fffffffffffUL
     6.8 +#define MAXMEM		 0xdfffffffffUL
     6.9  #define VMALLOC_START    0xffffc20000000000UL
    6.10  #define VMALLOC_END      0xffffe1ffffffffffUL
    6.11  #define MODULES_VADDR    0xffffffff88000000UL
    6.12 -#define MODULES_END      0xfffffffffff00000UL
    6.13 +#define MODULES_END      0xffffffffff000000UL
    6.14  #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
    6.15  
    6.16  #define _PAGE_BIT_PRESENT	0