/** * @file op_util.c * Various utility functions * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author John Levon * @author Philippe Elie */ #include <linux/vmalloc.h> #include <linux/wrapper.h> #include <linux/pagemap.h> #include "compat.h" #include "op_util.h" /* Given PGD from the address space's page table, return the kernel * virtual mapping of the physical memory mapped at ADR. */ static inline unsigned long uvirt_to_kva(pgd_t * pgd, unsigned long adr) { unsigned long ret = 0UL; pmd_t * pmd; pte_t * ptep, pte; if (!pgd_none(*pgd)) { pmd = pmd_offset(pgd, adr); if (!pmd_none(*pmd)) { ptep = pte_offset(pmd, adr); pte = *ptep; if (pte_present(pte)) { ret = (unsigned long) pte_page_address(pte); ret |= adr & (PAGE_SIZE - 1); } } } return ret; } /* Here we want the physical address of the memory. * This is used when initializing the contents of the * area and marking the pages as reserved. */ unsigned long kvirt_to_pa(unsigned long adr) { unsigned long va, kva, ret; va = VMALLOC_VMADDR(adr); kva = uvirt_to_kva(pgd_offset_k(va), va); ret = __pa(kva); return ret; } void * rvmalloc(signed long size) { void * mem; unsigned long adr, page; mem = VMALLOC_32(size); if (!mem) return NULL; memset(mem, 0, size); adr=(unsigned long) mem; while (size > 0) { page = kvirt_to_pa(adr); mem_map_reserve(virt_to_page((unsigned long)__va(page))); adr += PAGE_SIZE; size -= PAGE_SIZE; } return mem; } void rvfree(void * mem, signed long size) { unsigned long adr, page; if (!mem) return; adr=(unsigned long) mem; while (size > 0) { page = kvirt_to_pa(adr); mem_map_unreserve(virt_to_page((unsigned long)__va(page))); adr += PAGE_SIZE; size -= PAGE_SIZE; } vfree(mem); } int check_range(int val, int l, int h, char const * msg) { if (val < l || val > h) { printk(msg, val, l, h); return -EINVAL; } return 0; }