ia64/xen-unstable

changeset 5079:377402d5f51f

bitkeeper revision 1.1507 (4290370dlUP0DcWpBdGnFEf6MXC7CQ)

Fix x86/64 Linux memory map initialisation.
Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun May 22 07:38:53 2005 +0000 (2005-05-22)
parents c10a5789d09e
children 580d5a4fff25
files linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c
line diff
     1.1 --- a/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c	Sat May 21 20:25:27 2005 +0000
     1.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c	Sun May 22 07:38:53 2005 +0000
     1.3 @@ -68,19 +68,19 @@ static void __make_page_readonly(unsigne
     1.4  {
     1.5          unsigned long addr;
     1.6          pte_t *pte;
     1.7 -        unsigned long *page = (unsigned long *) init_level4_pgt;
     1.8 +	unsigned long *page = (unsigned long *) init_level4_pgt;
     1.9  
    1.10 -        addr = (unsigned long) page[pgd_index(va)];
    1.11 -        addr_to_page(addr, page);
    1.12 +	addr = (unsigned long) page[pgd_index(va)];
    1.13 +	addr_to_page(addr, page);
    1.14  
    1.15 -        addr = page[pud_index(va)];
    1.16 -        addr_to_page(addr, page);
    1.17 +	addr = page[pud_index(va)];
    1.18 +	addr_to_page(addr, page);
    1.19  
    1.20 -        addr = page[pmd_index(va)];
    1.21 -        addr_to_page(addr, page);
    1.22 +	addr = page[pmd_index(va)];
    1.23 +	addr_to_page(addr, page);
    1.24  
    1.25 -        pte = (pte_t *) &page[pte_index(va)];
    1.26 -        xen_l1_entry_update(pte, (*(unsigned long*)pte) & ~_PAGE_RW);
    1.27 +	pte = (pte_t *) &page[pte_index(va)];
    1.28 +	xen_l1_entry_update(pte, (*(unsigned long*)pte) & ~_PAGE_RW);
    1.29  	__flush_tlb_one(addr);
    1.30  }
    1.31  
    1.32 @@ -106,7 +106,7 @@ static void __make_page_writable(unsigne
    1.33  
    1.34  
    1.35  /*
    1.36 - * Assume the tranlation is already established.
    1.37 + * Assume the translation is already established.
    1.38   */
    1.39  void make_page_readonly(void *va)
    1.40  {
    1.41 @@ -385,72 +385,9 @@ void __set_fixmap_user (enum fixed_addre
    1.42  	}
    1.43  
    1.44          set_pte_phys(address, phys, prot, SET_FIXMAP_USER); 
    1.45 -
    1.46 -#if 0
    1.47 -        page = (unsigned long *) user_level3_pgt;
    1.48 -        pud = page[pud_index(address)];
    1.49 -
    1.50 -        printk("pud = %p\n", pud);
    1.51 -
    1.52 -        pmd = (pmd_t *) spp_getpage(); 
    1.53 -        printk("alloc pmd = %p\n", pmd);
    1.54 -
    1.55 -        make_page_readonly((unsigned long)pmd);
    1.56 -
    1.57 -        xen_pmd_pin(__pa(pmd));
    1.58 -
    1.59 -        set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
    1.60 -
    1.61 -        printk("after set_pud\n");
    1.62 -
    1.63 -        pte = (pte_t *) spp_getpage();
    1.64 -        printk("pte = %p\n");
    1.65 -
    1.66 -        make_page_readonly((unsigned long)pte);
    1.67 -
    1.68 -        xen_pte_pin(__pa(pte));
    1.69 -
    1.70 -        page = (unsigned long *) pud;
    1.71 -        pud = page[pud_index(address)];
    1.72 -        
    1.73 -
    1.74 -        pmd = pmd_offset(pud, vaddr);
    1.75 -
    1.76 -        set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
    1.77 -#endif
    1.78 -
    1.79  }
    1.80  
    1.81 -unsigned long __initdata table_start, table_end, tables_reserved; 
    1.82 -
    1.83 -#if 0
    1.84 -/*
    1.85 - * Get the machine PFN given va
    1.86 - */
    1.87 -static unsigned long get_machine_pfn(unsigned long va)
    1.88 -{
    1.89 -        unsigned long addr;
    1.90 -        pte_t *pte;
    1.91 -
    1.92 -        unsigned long *page = (unsigned long *) init_level4_pgt;
    1.93 -
    1.94 -        addr = (unsigned long) page[pgd_index(va)];
    1.95 -        addr &= PHYSICAL_PAGE_MASK;
    1.96 -        page = (unsigned long *) ((unsigned long)(((mfn_to_pfn(addr >> PAGE_SHIFT)) << PAGE_SHIFT) + __START_KERNEL_map)); 
    1.97 -
    1.98 -        addr = page[pud_index(va)];
    1.99 -        addr &= PHYSICAL_PAGE_MASK;
   1.100 -        page = (unsigned long *) ((unsigned long)(((mfn_to_pfn(addr >> PAGE_SHIFT)) << PAGE_SHIFT) + __START_KERNEL_map));
   1.101 -
   1.102 -        addr = page[pmd_index(va)];
   1.103 -        addr &= PHYSICAL_PAGE_MASK; 
   1.104 -        page = (unsigned long *) ((unsigned long)(((mfn_to_pfn(addr >> PAGE_SHIFT)) << PAGE_SHIFT)+ __START_KERNEL_map));
   1.105 -
   1.106 -        pte = (pte_t *) &page[pte_index(va)];
   1.107 -
   1.108 -        return (unsigned long) (pte->pte >> PAGE_SHIFT);
   1.109 -}
   1.110 -#endif
   1.111 +unsigned long __initdata table_start, table_end, tables_space; 
   1.112  
   1.113  unsigned long get_machine_pfn(unsigned long addr)
   1.114  {
   1.115 @@ -461,17 +398,37 @@ unsigned long get_machine_pfn(unsigned l
   1.116          return (pte->pte >> PAGE_SHIFT);
   1.117  } 
   1.118  
   1.119 +#define ALIGN_TO_4K __attribute__((section(".data.page_aligned")))
   1.120 +#define MAX_LOW_PAGES	0x20
   1.121 +static unsigned long __init_pgt[MAX_LOW_PAGES][512]  ALIGN_TO_4K;
   1.122 +static int __init_pgt_index;
   1.123  
   1.124  /*
   1.125   * We start using from start_pfn
   1.126   */
   1.127 -static __init void *alloc_low_page(unsigned long *phys)
   1.128 +static __init void *alloc_static_page(unsigned long *phys)
   1.129 +{
   1.130 +	int i = __init_pgt_index++;
   1.131 +
   1.132 +	if (__init_pgt_index >= MAX_LOW_PAGES) {
   1.133 +		printk("Need to increase MAX_LOW_PAGES");
   1.134 +		BUG();
   1.135 +	}
   1.136 +		
   1.137 +	*phys = __pa(__init_pgt[i]);
   1.138 +
   1.139 +	return (void *) __init_pgt[i];
   1.140 +} 
   1.141 +
   1.142 +/*
   1.143 + * Get RO page
   1.144 + */
   1.145 +static void __init *alloc_low_page(unsigned long *phys)
   1.146  { 
   1.147          unsigned long pfn = table_end++;
   1.148      
   1.149          *phys = (pfn << PAGE_SHIFT);
   1.150          memset((void *) ((pfn << PAGE_SHIFT) + __START_KERNEL_map), 0, PAGE_SIZE);
   1.151 -
   1.152          return (void *)((pfn << PAGE_SHIFT) + __START_KERNEL_map);
   1.153  } 
   1.154  
   1.155 @@ -519,7 +476,7 @@ void __init phys_pud_init(pud_t *pud, un
   1.156                          pte_save = pte;
   1.157                          for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += PTE_SIZE) {
   1.158                                  if (paddr < (table_start << PAGE_SHIFT) 
   1.159 -                                    + tables_reserved)
   1.160 +                                    + tables_space)
   1.161                                  {
   1.162                                          __set_pte(pte, 
   1.163                                                  __pte(paddr | (_KERNPG_TABLE & ~_PAGE_RW)));
   1.164 @@ -549,12 +506,83 @@ static void __init find_early_table_spac
   1.165  	pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
   1.166          ptes = (end + PTE_SIZE - 1) >> PAGE_SHIFT;
   1.167  
   1.168 -        tables_reserved = round_up(puds*8, PAGE_SIZE) + round_up(pmds * 8, PAGE_SIZE) 
   1.169 -                + round_up(ptes * 8, PAGE_SIZE); 
   1.170 -	table_start = start_pfn;
   1.171 -	table_end = table_start;
   1.172 +        tables_space = round_up(puds * 8, PAGE_SIZE) + 
   1.173 +	    		  round_up(pmds * 8, PAGE_SIZE) + 
   1.174 +	    		  round_up(ptes * 8, PAGE_SIZE); 
   1.175  }
   1.176  
   1.177 +
   1.178 +/*
   1.179 + * Extend kernel mapping to access pages for page tables.  The initial
   1.180 + * mapping done by Xen is minimal (e.g. 8MB) and we need to extend the
   1.181 + * mapping for early initialization.
   1.182 + */
   1.183 +
   1.184 +#define MIN_INIT_SIZE	0x800000
   1.185 +static unsigned long current_size, extended_size;
   1.186 +
   1.187 +void __init extend_init_mapping(void) 
   1.188 +{
   1.189 +	unsigned long va = __START_KERNEL_map;
   1.190 +	unsigned long addr, *pte_page;
   1.191 +
   1.192 +	unsigned long phys;
   1.193 +        pmd_t *pmd;
   1.194 +	pte_t *pte, new_pte;
   1.195 +	unsigned long *page = (unsigned long *) init_level4_pgt;
   1.196 +	int i;
   1.197 +
   1.198 +	addr = (unsigned long) page[pgd_index(va)];
   1.199 +	addr_to_page(addr, page);
   1.200 +
   1.201 +	addr = page[pud_index(va)];
   1.202 +	addr_to_page(addr, page);
   1.203 +
   1.204 +	for (;;) {
   1.205 +		pmd = (pmd_t *) &page[pmd_index(va)];
   1.206 +		if (pmd_present(*pmd)) {
   1.207 +			/*
   1.208 +			 * if pmd is valid, check pte.
   1.209 +			 */
   1.210 +			addr = page[pmd_index(va)];
   1.211 +			addr_to_page(addr, pte_page);
   1.212 +			
   1.213 +			for (i = 0; i < PTRS_PER_PTE; i++) {
   1.214 +				pte = (pte_t *) &pte_page[pte_index(va)];
   1.215 +				
   1.216 +				if (pte_present(*pte)) {
   1.217 +					va += PAGE_SIZE;
   1.218 +					current_size += PAGE_SIZE;
   1.219 +				} else
   1.220 +				    break;
   1.221 +			}
   1.222 +
   1.223 +		} else
   1.224 +		    break;
   1.225 +	}
   1.226 +
   1.227 +	for (; va < __START_KERNEL_map + current_size + tables_space; ) {
   1.228 +		pmd = (pmd_t *) &page[pmd_index(va)];
   1.229 +
   1.230 +		if (pmd_none(*pmd)) {
   1.231 +			pte_page = (unsigned long *) alloc_static_page(&phys);
   1.232 +			make_page_readonly(pte_page);
   1.233 +			xen_pte_pin(phys);
   1.234 +			set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER));
   1.235 +
   1.236 +			for (i = 0; i < PTRS_PER_PTE; i++, va += PAGE_SIZE) {
   1.237 +				new_pte = pfn_pte((va -  __START_KERNEL_map) >> PAGE_SHIFT, 
   1.238 +						  __pgprot(_KERNPG_TABLE | _PAGE_USER));
   1.239 +
   1.240 +				pte = (pte_t *) &pte_page[pte_index(va)];
   1.241 +				xen_l1_entry_update(pte, new_pte.pte);
   1.242 +				extended_size += PAGE_SIZE;
   1.243 +			}
   1.244 +		} 
   1.245 +	}
   1.246 +}
   1.247 +
   1.248 +
   1.249  /* Setup the direct mapping of the physical memory at PAGE_OFFSET.
   1.250     This runs before bootmem is initialized and gets pages directly from the 
   1.251     physical memory. To access them they are temporarily mapped. */
   1.252 @@ -562,10 +590,14 @@ void __init init_memory_mapping(unsigned
   1.253  { 
   1.254  	unsigned long next; 
   1.255  
   1.256 -
   1.257  	Dprintk("init_memory_mapping\n");
   1.258  
   1.259  	find_early_table_space(end);
   1.260 +	extend_init_mapping();
   1.261 +	start_pfn = current_size >> PAGE_SHIFT;
   1.262 +
   1.263 +	table_start = start_pfn;
   1.264 +	table_end = table_start;
   1.265  
   1.266  	start = (unsigned long)__va(start);
   1.267  	end = (unsigned long)__va(end);
   1.268 @@ -582,16 +614,15 @@ void __init init_memory_mapping(unsigned
   1.269  		set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
   1.270  	} 
   1.271  
   1.272 -	early_printk("kernel direct mapping tables upto %lx @ %lx-%lx\n", end, 
   1.273 +	printk("kernel direct mapping tables upto %lx @ %lx-%lx\n", end, 
   1.274  	       table_start<<PAGE_SHIFT, 
   1.275  	       table_end<<PAGE_SHIFT);
   1.276  
   1.277 -//        start_pfn = table_end;
   1.278 +        start_pfn = ((current_size + extended_size) >> PAGE_SHIFT);
   1.279  
   1.280          /*
   1.281           * TBD: Need to calculate at runtime
   1.282           */
   1.283 -	start_pfn = (8*0x100000) >> PAGE_SHIFT;
   1.284  
   1.285  	__flush_tlb_all();
   1.286          init_mapping_done = 1;