LCOV - code coverage report
Current view: top level - arch/arm/mm - highmem.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 20 34 58.8 %
Date: 2014-04-16 Functions: 4 6 66.7 %
Branches: 13 16 81.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * arch/arm/mm/highmem.c -- ARM highmem support
       3                 :            :  *
       4                 :            :  * Author:      Nicolas Pitre
       5                 :            :  * Created:     september 8, 2008
       6                 :            :  * Copyright:   Marvell Semiconductors Inc.
       7                 :            :  *
       8                 :            :  * This program is free software; you can redistribute it and/or modify
       9                 :            :  * it under the terms of the GNU General Public License version 2 as
      10                 :            :  * published by the Free Software Foundation.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include <linux/module.h>
      14                 :            : #include <linux/highmem.h>
      15                 :            : #include <linux/interrupt.h>
      16                 :            : #include <asm/fixmap.h>
      17                 :            : #include <asm/cacheflush.h>
      18                 :            : #include <asm/tlbflush.h>
      19                 :            : #include "mm.h"
      20                 :            : 
      21                 :          0 : void *kmap(struct page *page)
      22                 :            : {
      23                 :            :         might_sleep();
      24         [ +  + ]:    2049429 :         if (!PageHighMem(page))
      25                 :     731201 :                 return page_address(page);
      26                 :    1318228 :         return kmap_high(page);
      27                 :            : }
      28                 :            : EXPORT_SYMBOL(kmap);
      29                 :            : 
      30                 :          0 : void kunmap(struct page *page)
      31                 :            : {
      32         [ -  + ]:    2049428 :         BUG_ON(in_interrupt());
      33         [ +  + ]:    2049428 :         if (!PageHighMem(page))
      34                 :          1 :                 return;
      35                 :    1318229 :         kunmap_high(page);
      36                 :            : }
      37                 :            : EXPORT_SYMBOL(kunmap);
      38                 :            : 
      39                 :          0 : void *kmap_atomic(struct page *page)
      40                 :            : {
      41                 :            :         unsigned int idx;
      42                 :            :         unsigned long vaddr;
      43                 :            :         void *kmap;
      44                 :            :         int type;
      45                 :            : 
      46                 :            :         pagefault_disable();
      47         [ +  + ]:  220554872 :         if (!PageHighMem(page))
      48                 :   76441568 :                 return page_address(page);
      49                 :            : 
      50                 :            : #ifdef CONFIG_DEBUG_HIGHMEM
      51                 :            :         /*
      52                 :            :          * There is no cache coherency issue when non VIVT, so force the
      53                 :            :          * dedicated kmap usage for better debugging purposes in that case.
      54                 :            :          */
      55                 :            :         if (!cache_is_vivt())
      56                 :            :                 kmap = NULL;
      57                 :            :         else
      58                 :            : #endif
      59                 :  144113304 :                 kmap = kmap_high_get(page);
      60         [ +  + ]:  144212996 :         if (kmap)
      61                 :            :                 return kmap;
      62                 :            : 
      63                 :            :         type = kmap_atomic_idx_push();
      64                 :            : 
      65                 :  141519098 :         idx = type + KM_TYPE_NR * smp_processor_id();
      66                 :  141519098 :         vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
      67                 :            : #ifdef CONFIG_DEBUG_HIGHMEM
      68                 :            :         /*
      69                 :            :          * With debugging enabled, kunmap_atomic forces that entry to 0.
      70                 :            :          * Make sure it was indeed properly unmapped.
      71                 :            :          */
      72                 :            :         BUG_ON(!pte_none(get_top_pte(vaddr)));
      73                 :            : #endif
      74                 :            :         /*
      75                 :            :          * When debugging is off, kunmap_atomic leaves the previous mapping
      76                 :            :          * in place, so the contained TLB flush ensures the TLB is updated
      77                 :            :          * with the new mapping.
      78                 :            :          */
      79                 :  141519098 :         set_top_pte(vaddr, mk_pte(page, kmap_prot));
      80                 :            : 
      81                 :  141518940 :         return (void *)vaddr;
      82                 :            : }
      83                 :            : EXPORT_SYMBOL(kmap_atomic);
      84                 :            : 
      85                 :          0 : void __kunmap_atomic(void *kvaddr)
      86                 :            : {
      87                 :  220560739 :         unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
      88                 :            :         int idx, type;
      89                 :            : 
      90         [ +  + ]:  220560739 :         if (kvaddr >= (void *)FIXADDR_START) {
      91                 :            :                 type = kmap_atomic_idx();
      92                 :            :                 idx = type + KM_TYPE_NR * smp_processor_id();
      93                 :            : 
      94                 :            :                 if (cache_is_vivt())
      95                 :            :                         __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
      96                 :            : #ifdef CONFIG_DEBUG_HIGHMEM
      97                 :            :                 BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
      98                 :            :                 set_top_pte(vaddr, __pte(0));
      99                 :            : #else
     100                 :            :                 (void) idx;  /* to kill a warning */
     101                 :            : #endif
     102                 :            :                 kmap_atomic_idx_pop();
     103         [ +  + ]:   79132129 :         } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
     104                 :            :                 /* this address was obtained through kmap_high_get() */
     105                 :    2694301 :                 kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
     106                 :            :         }
     107                 :            :         pagefault_enable();
     108                 :  220533900 : }
     109                 :            : EXPORT_SYMBOL(__kunmap_atomic);
     110                 :            : 
     111                 :          0 : void *kmap_atomic_pfn(unsigned long pfn)
     112                 :            : {
     113                 :            :         unsigned long vaddr;
     114                 :            :         int idx, type;
     115                 :            : 
     116                 :            :         pagefault_disable();
     117                 :            : 
     118                 :            :         type = kmap_atomic_idx_push();
     119                 :          0 :         idx = type + KM_TYPE_NR * smp_processor_id();
     120                 :          0 :         vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
     121                 :            : #ifdef CONFIG_DEBUG_HIGHMEM
     122                 :            :         BUG_ON(!pte_none(get_top_pte(vaddr)));
     123                 :            : #endif
     124                 :          0 :         set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
     125                 :            : 
     126                 :          0 :         return (void *)vaddr;
     127                 :            : }
     128                 :            : 
     129                 :          0 : struct page *kmap_atomic_to_page(const void *ptr)
     130                 :            : {
     131                 :          0 :         unsigned long vaddr = (unsigned long)ptr;
     132                 :            : 
     133         [ #  # ]:          0 :         if (vaddr < FIXADDR_START)
     134                 :          0 :                 return virt_to_page(ptr);
     135                 :            : 
     136                 :          0 :         return pte_page(get_top_pte(vaddr));
     137                 :            : }

Generated by: LCOV version 1.9