1 /** 2 * @file op_util.c 3 * Various utility functions 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author John Levon 9 * @author Philippe Elie 10 */ 11 12 #include <linux/vmalloc.h> 13 #include <linux/wrapper.h> 14 #include <linux/pagemap.h> 15 16 #include "compat.h" 17 18 #include "op_util.h" 19 20 /* Given PGD from the address space's page table, return the kernel 21 * virtual mapping of the physical memory mapped at ADR. 22 */ 23 static inline unsigned long uvirt_to_kva(pgd_t * pgd, unsigned long adr) 24 { 25 unsigned long ret = 0UL; 26 pmd_t * pmd; 27 pte_t * ptep, pte; 28 29 if (!pgd_none(*pgd)) { 30 pmd = pmd_offset(pgd, adr); 31 if (!pmd_none(*pmd)) { 32 ptep = pte_offset(pmd, adr); 33 pte = *ptep; 34 if (pte_present(pte)) { 35 ret = (unsigned long) pte_page_address(pte); 36 ret |= adr & (PAGE_SIZE - 1); 37 } 38 } 39 } 40 return ret; 41 } 42 43 /* Here we want the physical address of the memory. 44 * This is used when initializing the contents of the 45 * area and marking the pages as reserved. 46 */ 47 unsigned long kvirt_to_pa(unsigned long adr) 48 { 49 unsigned long va, kva, ret; 50 51 va = VMALLOC_VMADDR(adr); 52 kva = uvirt_to_kva(pgd_offset_k(va), va); 53 ret = __pa(kva); 54 return ret; 55 } 56 57 void * rvmalloc(signed long size) 58 { 59 void * mem; 60 unsigned long adr, page; 61 62 mem = VMALLOC_32(size); 63 if (!mem) 64 return NULL; 65 66 memset(mem, 0, size); 67 68 adr=(unsigned long) mem; 69 while (size > 0) { 70 page = kvirt_to_pa(adr); 71 mem_map_reserve(virt_to_page((unsigned long)__va(page))); 72 adr += PAGE_SIZE; 73 size -= PAGE_SIZE; 74 } 75 return mem; 76 } 77 78 void rvfree(void * mem, signed long size) 79 { 80 unsigned long adr, page; 81 82 if (!mem) 83 return; 84 85 adr=(unsigned long) mem; 86 while (size > 0) { 87 page = kvirt_to_pa(adr); 88 mem_map_unreserve(virt_to_page((unsigned long)__va(page))); 89 90 adr += PAGE_SIZE; 91 size -= PAGE_SIZE; 92 } 93 vfree(mem); 94 } 95 96 int check_range(int val, int l, int h, char const * msg) 97 { 98 if (val < l || val > h) { 99 printk(msg, val, l, h); 100 return -EINVAL; 101 } 102 return 0; 103 } 104