|
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