Home | History | Annotate | Download | only in module
      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