CTC++ Coverage Report - Execution Profile    #81/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: arch/x86_64/mm/init.c
Instrumentation mode: function-decision-multicondition
TER: 47 % (116/247)

Start/ End/    
True False - Line Source

  1 /*
  2  *  linux/arch/x86_64/mm/init.c
  3  *
  4  *  Copyright (C) 1995  Linus Torvalds
  5  *  Copyright (C) 2000  Pavel Machek <pavel@suse.cz>
  6  *  Copyright (C) 2002,2003 Andi Kleen <ak@suse.de>
  7  */
  8 
  9 #include <linux/config.h>
  10 #include <linux/signal.h>
  11 #include <linux/sched.h>
  12 #include <linux/kernel.h>
  13 #include <linux/errno.h>
  14 #include <linux/string.h>
  15 #include <linux/types.h>
  16 #include <linux/ptrace.h>
  17 #include <linux/mman.h>
  18 #include <linux/mm.h>
  19 #include <linux/swap.h>
  20 #include <linux/smp.h>
  21 #include <linux/init.h>
  22 #include <linux/pagemap.h>
  23 #include <linux/bootmem.h>
  24 #include <linux/proc_fs.h>
  25 #include <linux/pci.h>
  26 #include <linux/dma-mapping.h>
  27 #include <linux/module.h>
  28 #include <linux/memory_hotplug.h>
  29 
  30 #include <asm/processor.h>
  31 #include <asm/system.h>
  32 #include <asm/uaccess.h>
  33 #include <asm/pgtable.h>
  34 #include <asm/pgalloc.h>
  35 #include <asm/dma.h>
  36 #include <asm/fixmap.h>
  37 #include <asm/e820.h>
  38 #include <asm/apic.h>
  39 #include <asm/tlb.h>
  40 #include <asm/mmu_context.h>
  41 #include <asm/proto.h>
  42 #include <asm/smp.h>
  43 #include <asm/sections.h>
  44 #include <asm/dma-mapping.h>
  45 #include <asm/swiotlb.h>
  46 
  47 #ifndef Dprintk
  48 #define Dprintk(x...)
  49 #endif
  50 
  51 struct dma_mapping_ops* dma_ops;
  52 EXPORT_SYMBOL(dma_ops);
  53 
  54 static unsigned long dma_reserve __initdata;
  55 
  56 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
  57 
  58 /*
  59  * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
  60  * physical space so we can cache the place of the first one and move
  61  * around without checking the pgd every time.
  62  */
  63 
 
10 10   64 void show_mem(void)
  65 {
  66    long i, total = 0, reserved = 0;
  67    long shared = 0, cached = 0;
  68    pg_data_t *pgdat;
  69    struct page *page;
  70 
  71    printk(KERN_INFO "Mem-info:\n");
  72    show_free_areas();
  73    printk(KERN_INFO "Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
  74 
10 10   75    for_each_pgdat(pgdat) {
1308E3 10   76                for (i = 0; i < pgdat->node_spanned_pages; ++i) {
  77          page = pfn_to_page(pgdat->node_start_pfn + i);
  78          total++;
91820 1216E3   79          if (PageReserved(page))
1308E3 - 79     ternary-?: __builtin_constant_p ( 10 )
  80             reserved++;
60 1216E3   81          else if (PageSwapCache(page))
1216E3 - 81     ternary-?: __builtin_constant_p ( 15 )
  82             cached++;
1202E3 13294   83          else if (page_count(page))
  84             shared += page_count(page) - 1;
  85                }
  86    }
  87    printk(KERN_INFO "%lu pages of RAM\n", total);
  88    printk(KERN_INFO "%lu reserved pages\n",reserved);
  89    printk(KERN_INFO "%lu pages shared\n",shared);
  90    printk(KERN_INFO "%lu pages swap cached\n",cached);
  91 }
  92 
  93 /* References to section boundaries */
  94 
  95 int after_bootmem;
  96 
 
18   97 static void *spp_getpage(void)
  98 
  99    void *ptr;
12   100    if (after_bootmem)
  101       ptr = (void *) get_zeroed_page(GFP_ATOMIC); 
    102    else
    103       ptr = alloc_bootmem_pages(PAGE_SIZE);
12 - 103   ternary-?: ( ( unsigned long ) ( ( ( unsigne..
18 - 104    if (!ptr || ((unsigned long)ptr & ~PAGE_MASK))
 - 104   T || (_)
 - 104   F || (T)
 18   104   F || (F)
    105       panic("set_pte_phys: cannot allocate page data %s\n", after_bootmem?"after bootmem":"");
- 105   ternary-?: after_bootmem
  106 
  107    Dprintk("spp_getpage %p\n", ptr);
18    108    return ptr;
  109 
  110 
 
30 30   111 static void set_pte_phys(unsigned long vaddr,
  112           unsigned long phys, pgprot_t prot)
  113 {
  114    pgd_t *pgd;
  115    pud_t *pud;
  116    pmd_t *pmd;
  117    pte_t *pte, new_pte;
  118 
  119    Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
  120 
  121    pgd = pgd_offset_k(vaddr);
30 - 122    if (pgd_none(*pgd)) {
  123       printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
 - 124       return;
  125    }
  126    pud = pud_offset(pgd, vaddr);
24   127    if (pud_none(*pud)) {
  128       pmd = (pmd_t *) spp_getpage(); 
  129       set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
- 130       if (pmd != pmd_offset(pud, 0)) {
  131          printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
 - 132          return;
  133       }
  134    }
  135    pmd = pmd_offset(pud, vaddr);
12 18   136    if (pmd_none(*pmd)) {
  137       pte = (pte_t *) spp_getpage();
  138       set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
12 - 139       if (pte != pte_offset_kernel(pmd, 0)) {
  140          printk("PAGETABLE BUG #02!\n");
 - 141          return;
  142       }
  143    }
  144    new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
  145 
  146    pte = pte_offset_kernel(pmd, vaddr);
  147    if (!pte_none(*pte) &&
30 - 148        pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
 - 148   !(!(T)) && T
 12   148   !(!(T)) && F
 18   148   !(!(F)) && _
  149       pte_ERROR(*pte);
  150    set_pte(pte, new_pte);
  151 
  152    /*
  153     * It's enough to flush this one mapping.
  154     * (PGE mappings get flushed as well)
  155     */
  156    __flush_tlb_one(vaddr);
  157 }
  158 
  159 /* NOTE: this is meant to be run only at boot */
 
30 30   160 void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
  161 {
  162    unsigned long address = __fix_to_virt(idx);
  163 
30 - 164    if (idx >= __end_of_fixed_addresses) {
  165       printk("Invalid __set_fixmap\n");
 - 166       return;
  167    }
  168    set_pte_phys(address, phys, prot);
  169 }
  170 
  171 unsigned long __initdata table_start, table_end; 
  172 
  173 extern pmd_t temp_boot_pmds[]; 
  174 
  175 static  struct temp_map { 
  176    pmd_t *pmd;
  177    void  *address; 
  178    int    allocated; 
  179 } temp_mappings[] __initdata = { 
  180    { &temp_boot_pmds[0], (void *)(40UL * 1024 * 1024) },
  181    { &temp_boot_pmds[1], (void *)(42UL * 1024 * 1024) }, 
  182    {}
  183 }; 
  184 
 
18   185 static __meminit void *alloc_low_page(int *index, unsigned long *phys)
  186 
  187    struct temp_map *ti;
  188    int i; 
  189    unsigned long pfn = table_end++, paddr; 
  190    void *adr;
  191 
18 - 192    if (after_bootmem) {
  193       adr = (void *)get_zeroed_page(GFP_ATOMIC);
    194       *phys = __pa(adr);
- 194   ternary-?: ( ( unsigned long ) ( adr ) >= 0x..
 - 195       return adr;
  196    }
  197 
18 - 198    if (pfn >= end_pfn) 
  199       panic("alloc_low_page: ran out of memory"); 
12 18   200    for (i = 0; temp_mappings[i].allocated; i++) {
12 - 201       if (!temp_mappings[i].pmd) 
  202          panic("alloc_low_page: ran out of temp mappings"); 
  203    } 
  204    ti = &temp_mappings[i];
  205    paddr = (pfn << PAGE_SHIFT) & PMD_MASK; 
  206    set_pmd(ti->pmd, __pmd(paddr | _KERNPG_TABLE | _PAGE_PSE)); 
  207    ti->allocated = 1; 
    208    __flush_tlb();           
18 - 208 do-while (0)
  209    adr = ti->address + ((pfn << PAGE_SHIFT) & ~PMD_MASK); 
  210    memset(adr, 0, PAGE_SIZE);
  211    *index = i; 
  212    *phys  = pfn * PAGE_SIZE;  
18    213    return adr; 
  214 
  215 
 
18 18   216 static __meminit void unmap_low_page(int i)
  217 
  218    struct temp_map *ti;
  219 
18 - 220    if (after_bootmem)
 - 221       return;
  222 
  223    ti = &temp_mappings[i];
  224    set_pmd(ti->pmd, __pmd(0));
  225    ti->allocated = 0; 
  226 
  227 
  228 static void __meminit
 
12 12   229 phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end)
  230 {
  231    int i;
  232 
6144 12   233    for (i = 0; i < PTRS_PER_PMD; pmd++, i++, address += PMD_SIZE) {
  234       unsigned long entry;
  235 
6144 - 236       if (address > end) {
- 237          for (; i < PTRS_PER_PMD; i++, pmd++)
  238             set_pmd(pmd, __pmd(0));
 - 239          break;
  240       }
  241       entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address;
  242       entry &= __supported_pte_mask;
  243       set_pmd(pmd, __pmd(entry));
  244    }
  245 }
  246 
  247 static void __meminit
 
- 248 phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end)
  249 {
  250    pmd_t *pmd = pmd_offset(pud, (unsigned long)__va(address));
  251 
- 252    if (pmd_none(*pmd)) {
    253       spin_lock(&init_mm.page_table_lock);
    253     do
- 253     do-while (0)
- 253   do-while (0)
  254       phys_pmd_init(pmd, address, end);
    255       spin_unlock(&init_mm.page_table_lock);
    255     do
- 255     do-while (0)
- 255   do-while (0)
    256       __flush_tlb_all();
- 256   do-while (0)
  257    }
  258 }
  259 
 
  260 static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
  261 
  262    long i = pud_index(address);
  263 
  264    pud = pud + i;
  265 
- 266    if (after_bootmem && pud_val(*pud)) {
 - 266   T && (T)
 - 266   T && (F)
   266   F && (_)
  267       phys_pmd_update(pud, address, end);
 - 268       return;
  269    }
  270 
30 - 271    for (; i < PTRS_PER_PUD; pud++, i++) {
  272       int map; 
  273       unsigned long paddr, pmd_phys;
  274       pmd_t *pmd;
  275 
  276       paddr = (address & PGDIR_MASK) + i*PUD_SIZE;
24   277       if (paddr >= end)
   278          break;
  279 
12 12   280       if (!after_bootmem && !e820_mapped(paddr, paddr+PUD_SIZE, 0)) {
12    280     T && T
 12   280     T && F
 - 280     F && _
  281          set_pud(pud, __pud(0)); 
12    282          continue;
  283       } 
  284 
  285       pmd = alloc_low_page(&map, &pmd_phys);
    286       spin_lock(&init_mm.page_table_lock);
    286     do
12 - 286     do-while (0)
12 - 286   do-while (0)
  287       set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
  288       phys_pmd_init(pmd, paddr, end);
    289       spin_unlock(&init_mm.page_table_lock);
    289     do
12 - 289     do-while (0)
12 - 289   do-while (0)
  290       unmap_low_page(map);
  291    }
    292    __flush_tlb();
- 292 do-while (0)
  293 
  294 
 
  295 static void __init find_early_table_space(unsigned long end)
  296 {
  297    unsigned long puds, pmds, tables, start;
  298 
  299    puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
  300    pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
  301    tables = round_up(puds * sizeof(pud_t), PAGE_SIZE) +
  302        round_up(pmds * sizeof(pmd_t), PAGE_SIZE);
  303 
  304     /* RED-PEN putting page tables only on node 0 could
  305        cause a hotspot and fill up ZONE_DMA. The page tables
  306        need roughly 0.5KB per GB. */
  307     start = 0x8000;
  308     table_start = find_e820_area(start, end, tables);
- 309    if (table_start == -1UL)
  310       panic("Cannot find space for the kernel page tables");
  311 
  312    table_start >>= PAGE_SHIFT;
  313    table_end = table_start;
  314 
  315    early_printk("kernel direct mapping tables up to %lx @ %lx-%lx\n",
  316       end, table_start << PAGE_SHIFT, table_end << PAGE_SHIFT);
  317 }
  318 
  319 /* Setup the direct mapping of the physical memory at PAGE_OFFSET.
  320    This runs before bootmem is initialized and gets pages directly from the 
  321    physical memory. To access them they are temporarily mapped. */
 
  322 void __meminit init_memory_mapping(unsigned long start, unsigned long end)
  323 
  324    unsigned long next; 
  325 
  326    Dprintk("init_memory_mapping\n");
  327 
  328    /* 
  329     * Find space for the kernel direct mapping tables.
  330     * Later we should allocate these tables in the local node of the memory
  331     * mapped.  Unfortunately this is done currently before the nodes are 
  332     * discovered.
  333     */
- 334    if (!after_bootmem)
  335       find_early_table_space(end);
  336 
  337    start = (unsigned long)__va(start);
  338    end = (unsigned long)__va(end);
  339 
  340    for (; start < end; start = next) {
  341       int map;
  342       unsigned long pud_phys; 
  343       pgd_t *pgd = pgd_offset_k(start);
  344       pud_t *pud;
  345 
- 346       if (after_bootmem)
  347          pud = pud_offset_k(pgd, __PAGE_OFFSET);
    348       else
  349          pud = alloc_low_page(&map, &pud_phys);
  350 
  351       next = start + PGDIR_SIZE;
- 352       if (next > end) 
  353          next = end; 
    354       phys_pud_init(pud, __pa(start), __pa(next));
- 354   ternary-?: ( ( unsigned long ) ( start ) >= ..
- 354   ternary-?: ( ( unsigned long ) ( next ) >= 0..
- 355       if (!after_bootmem)
  356          set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
  357       unmap_low_page(map);   
  358    } 
  359 
- 360    if (!after_bootmem)
  361       asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features));
    362    __flush_tlb_all();
- 362 do-while (0)
  363 }
  364 
 
  365 void __cpuinit zap_low_mappings(int cpu)
  366 {
- 367    if (cpu == 0) {
  368       pgd_t *pgd = pgd_offset_k(0UL);
  369       pgd_clear(pgd);
    370    } else {
  371       /*
  372        * For AP's, zap the low identity mappings by changing the cr3
  373        * to init_level4_pgt and doing local flush tlb all
  374        */
  375       asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
  376    }
    377    __flush_tlb_all();
- 377 do-while (0)
  378 }
  379 
  380 /* Compute zone sizes for the DMA and DMA32 zones in a node. */
  381 __init void
 
  382 size_zones(unsigned long *z, unsigned long *h,
  383       unsigned long start_pfn, unsigned long end_pfn)
  384 {
  385     int i;
  386     unsigned long w;
  387 
24   388     for (i = 0; i < MAX_NR_ZONES; i++)
  389        z[i] = 0;
  390 
- 391     if (start_pfn < MAX_DMA_PFN)
  392        z[ZONE_DMA] = MAX_DMA_PFN - start_pfn;
- 393     if (start_pfn < MAX_DMA32_PFN) {
  394        unsigned long dma32_pfn = MAX_DMA32_PFN;
- 395        if (dma32_pfn > end_pfn)
  396           dma32_pfn = end_pfn;
  397        z[ZONE_DMA32] = dma32_pfn - start_pfn;
  398     }
  399     z[ZONE_NORMAL] = end_pfn - start_pfn;
  400 
  401     /* Remove lower zones from higher ones. */
  402     w = 0;
24   403     for (i = 0; i < MAX_NR_ZONES; i++) {
18   404        if (z[i])
  405           z[i] -= w;
  406             w += z[i];
  407    }
  408 
  409    /* Compute holes */
  410    w = start_pfn;
24   411    for (i = 0; i < MAX_NR_ZONES; i++) {
  412       unsigned long s = w;
  413       w += z[i];
  414       h[i] = e820_hole_size(s, w);
  415    }
  416 
  417    /* Add the space pace needed for mem_map to the holes too. */
24   418    for (i = 0; i < MAX_NR_ZONES; i++)
  419       h[i] += (z[i] * sizeof(struct page)) / PAGE_SIZE;
  420 
  421    /* The 16MB DMA zone has the kernel and other misc mappings.
  422        Account them too */
- 423    if (h[ZONE_DMA]) {
  424       h[ZONE_DMA] += dma_reserve;
- 425       if (h[ZONE_DMA] >= z[ZONE_DMA]) {
  426          printk(KERN_WARNING
  427             "Kernel too large and filling up ZONE_DMA?\n");
  428          h[ZONE_DMA] = z[ZONE_DMA];
  429       }
  430    }
  431 }
  432 
  433 #ifndef CONFIG_NUMA
 
  434 void __init paging_init(void)
  435 {
  436    unsigned long zones[MAX_NR_ZONES], holes[MAX_NR_ZONES];
  437 
  438    memory_present(0, 0, end_pfn);
    439    sparse_init();
- 439 do-while (0)
  440    size_zones(zones, holes, 0, end_pfn);
  441    free_area_init_node(0, NODE_DATA(0), zones,
    442              __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
- 442 ternary-?: ( ( unsigned long ) ( ( ( unsigned ..
  443 }
  444 #endif
  445 
  446 /* Unmap a kernel mapping if it exists. This is useful to avoid prefetches
  447    from the CPU leading to inconsistent cache lines. address and size
  448    must be aligned to 2MB boundaries. 
  449    Does nothing when the mapping doesn't exist. */
 
- 450 void __init clear_kernel_mapping(unsigned long address, unsigned long size) 
  451 {
  452    unsigned long end = address + size;
  453 
    454    BUG_ON(address & ~LARGE_PAGE_MASK);
- 454   if (__builtin_expect ( ! ! ( ( address & ~ (..
- 454 do-while (0)
    455    BUG_ON(size & ~LARGE_PAGE_MASK); 
- 455   if (__builtin_expect ( ! ! ( ( size & ~ ( ~ ..
- 455 do-while (0)
  456    
- 457    for (; address < end; address += LARGE_PAGE_SIZE) { 
  458       pgd_t *pgd = pgd_offset_k(address);
  459       pud_t *pud;
  460       pmd_t *pmd;
- 461       if (pgd_none(*pgd))
 - 462          continue;
  463       pud = pud_offset(pgd, address);
- 464       if (pud_none(*pud))
 - 465          continue; 
  466       pmd = pmd_offset(pud, address);
- 467       if (!pmd || pmd_none(*pmd))
 - 467     T || (!(_))
 - 467     F || (!(F))
 - 467     F || (!(T))
 - 468          continue; 
- 469       if (0 == (pmd_val(*pmd) & _PAGE_PSE)) { 
  470          /* Could handle this, but it should not happen currently. */
  471          printk(KERN_ERR 
  472           "clear_kernel_mapping: mapping has been split. will leak memory\n"); 
  473          pmd_ERROR(*pmd); 
  474       }
  475       set_pmd(pmd, __pmd(0));       
  476    }
    477    __flush_tlb_all();
- 477 do-while (0)
  478 
  479 
  480 /*
  481  * Memory hotplug specific functions
  482  * These are only for non-NUMA machines right now.
  483  */
  484 #ifdef CONFIG_MEMORY_HOTPLUG
  485 
  486 void online_page(struct page *page)
  487 {
  488    ClearPageReserved(page);
  489    set_page_count(page, 1);
  490    __free_page(page);
  491    totalram_pages++;
  492    num_physpages++;
  493 }
  494 
  495 int add_memory(u64 start, u64 size)
  496 {
  497