|
50 | 50 | #include <linux/irq_work.h> |
51 | 51 | #include <linux/workqueue.h> |
52 | 52 | #include <linux/sort.h> |
| 53 | +#include <linux/io.h> /* vmap_page_range() */ |
53 | 54 |
|
54 | 55 | #include <asm/setup.h> /* COMMAND_LINE_SIZE */ |
55 | 56 |
|
@@ -9796,29 +9797,27 @@ static int instance_mkdir(const char *name) |
9796 | 9797 | return ret; |
9797 | 9798 | } |
9798 | 9799 |
|
9799 | | -static u64 map_pages(u64 start, u64 size) |
| 9800 | +static u64 map_pages(unsigned long start, unsigned long size) |
9800 | 9801 | { |
9801 | | - struct page **pages; |
9802 | | - phys_addr_t page_start; |
9803 | | - unsigned int page_count; |
9804 | | - unsigned int i; |
9805 | | - void *vaddr; |
9806 | | - |
9807 | | - page_count = DIV_ROUND_UP(size, PAGE_SIZE); |
| 9802 | + unsigned long vmap_start, vmap_end; |
| 9803 | + struct vm_struct *area; |
| 9804 | + int ret; |
9808 | 9805 |
|
9809 | | - page_start = start; |
9810 | | - pages = kmalloc_array(page_count, sizeof(struct page *), GFP_KERNEL); |
9811 | | - if (!pages) |
| 9806 | + area = get_vm_area(size, VM_IOREMAP); |
| 9807 | + if (!area) |
9812 | 9808 | return 0; |
9813 | 9809 |
|
9814 | | - for (i = 0; i < page_count; i++) { |
9815 | | - phys_addr_t addr = page_start + i * PAGE_SIZE; |
9816 | | - pages[i] = pfn_to_page(addr >> PAGE_SHIFT); |
| 9810 | + vmap_start = (unsigned long) area->addr; |
| 9811 | + vmap_end = vmap_start + size; |
| 9812 | + |
| 9813 | + ret = vmap_page_range(vmap_start, vmap_end, |
| 9814 | + start, pgprot_nx(PAGE_KERNEL)); |
| 9815 | + if (ret < 0) { |
| 9816 | + free_vm_area(area); |
| 9817 | + return 0; |
9817 | 9818 | } |
9818 | | - vaddr = vmap(pages, page_count, VM_MAP, PAGE_KERNEL); |
9819 | | - kfree(pages); |
9820 | 9819 |
|
9821 | | - return (u64)(unsigned long)vaddr; |
| 9820 | + return (u64)vmap_start; |
9822 | 9821 | } |
9823 | 9822 |
|
9824 | 9823 | /** |
|
0 commit comments