• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
uvirt_to_kva(pgd_t * pgd,unsigned long adr)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  */
kvirt_to_pa(unsigned long adr)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 
rvmalloc(signed long size)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 
rvfree(void * mem,signed long size)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 
check_range(int val,int l,int h,char const * msg)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