Here is an example of the modifications required to vmalloc to enable
uncached spaces to be allocated. In fact, it allows any pgprot to be
specified for the vmalloc'd area. I think that the names of the new
functions follow Linus' naming scheme - __vmalloc() is more generic
and does `less' than vmalloc().
Note that this is just an example; it seems to compile (on 2.2.5),
but I have not tested it at all.
--- vmalloc.c.rmk Thu Aug 26 10:52:39 1999
+++ vmalloc.c Thu Aug 26 10:53:58 1999
@@ -82,7 +82,7 @@
flush_tlb_all();
}
-static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned long size)
+static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned long size, pgprot_t prot)
{
unsigned long end;
@@ -97,14 +97,14 @@
page = __get_free_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
- set_pte(pte, mk_pte(page, PAGE_KERNEL));
+ set_pte(pte, mk_pte(page, prot));
address += PAGE_SIZE;
pte++;
}
return 0;
}
-static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size)
+static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, pgprot_t prot)
{
unsigned long end;
@@ -116,7 +116,7 @@
pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
- if (alloc_area_pte(pte, address, end - address))
+ if (alloc_area_pte(pte, address, end - address, prot))
return -ENOMEM;
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
@@ -124,7 +124,7 @@
return 0;
}
-int vmalloc_area_pages(unsigned long address, unsigned long size)
+inline int __vmalloc_area_pages(unsigned long address, unsigned long size, pgprot_t prot)
{
pgd_t * dir;
unsigned long end = address + size;
@@ -138,7 +138,7 @@
pmd = pmd_alloc_kernel(dir, address);
if (!pmd)
return -ENOMEM;
- if (alloc_area_pmd(pmd, address, end - address))
+ if (alloc_area_pmd(pmd, address, end - address, prot))
return -ENOMEM;
if (pgd_val(olddir) != pgd_val(*dir))
set_pgdir(address, *dir);
@@ -149,6 +149,11 @@
return 0;
}
+int vmalloc_area_pages(unsigned long address, unsigned long size)
+{
+ return __vmalloc_area_pages(address, size, PAGE_KERNEL);
+}
+
struct vm_struct * get_vm_area(unsigned long size)
{
unsigned long addr;
@@ -195,7 +200,7 @@
printk("Trying to vfree() nonexistent vm area (%p)\n", addr);
}
-void * vmalloc(unsigned long size)
+inline void * __vmalloc(unsigned long size, pgprot_t prot)
{
void * addr;
struct vm_struct *area;
@@ -207,11 +212,16 @@
if (!area)
return NULL;
addr = area->addr;
- if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size)) {
+ if (__vmalloc_area_pages(VMALLOC_VMADDR(addr), size, prot)) {
vfree(addr);
return NULL;
}
return addr;
+}
+
+void * vmalloc(unsigned long size)
+{
+ return __vmalloc(size, PAGE_KERNEL);
}
long vread(char *buf, char *addr, unsigned long count)
_____
|_____| ------------------------------------------------- ---+---+-
| | Russell King rmk@arm.linux.org.uk --- ---
| | | | http://www.arm.linux.org.uk/~rmk/aboutme.html / / |
| +-+-+ --- -+-
/ | THE developer of ARM Linux |+| /|\
/ | | | --- |
+-+-+ ------------------------------------------------- /\\\ |
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/