1 | /****************************************************************************** |
---|
2 | * arch/ia64/xen/util.c |
---|
3 | * This file is the ia64 counterpart of drivers/xen/util.c |
---|
4 | * |
---|
5 | * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp> |
---|
6 | * VA Linux Systems Japan K.K. |
---|
7 | * |
---|
8 | * This program is free software; you can redistribute it and/or modify |
---|
9 | * it under the terms of the GNU General Public License as published by |
---|
10 | * the Free Software Foundation; either version 2 of the License, or |
---|
11 | * (at your option) any later version. |
---|
12 | * |
---|
13 | * This program is distributed in the hope that it will be useful, |
---|
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
16 | * GNU General Public License for more details. |
---|
17 | * |
---|
18 | * You should have received a copy of the GNU General Public License |
---|
19 | * along with this program; if not, write to the Free Software |
---|
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
21 | * |
---|
22 | */ |
---|
23 | |
---|
24 | #include <linux/mm.h> |
---|
25 | #include <linux/module.h> |
---|
26 | #include <linux/slab.h> |
---|
27 | #include <linux/vmalloc.h> |
---|
28 | #include <asm/uaccess.h> |
---|
29 | #include <xen/driver_util.h> |
---|
30 | #include <xen/interface/memory.h> |
---|
31 | #include <asm/hypercall.h> |
---|
32 | |
---|
33 | struct vm_struct *alloc_vm_area(unsigned long size) |
---|
34 | { |
---|
35 | int order; |
---|
36 | unsigned long virt; |
---|
37 | unsigned long nr_pages; |
---|
38 | struct vm_struct* area; |
---|
39 | |
---|
40 | order = get_order(size); |
---|
41 | virt = __get_free_pages(GFP_KERNEL, order); |
---|
42 | if (virt == 0) { |
---|
43 | goto err0; |
---|
44 | } |
---|
45 | nr_pages = 1 << order; |
---|
46 | scrub_pages(virt, nr_pages); |
---|
47 | |
---|
48 | area = kmalloc(sizeof(*area), GFP_KERNEL); |
---|
49 | if (area == NULL) { |
---|
50 | goto err1; |
---|
51 | } |
---|
52 | |
---|
53 | area->flags = VM_IOREMAP;//XXX |
---|
54 | area->addr = (void*)virt; |
---|
55 | area->size = size; |
---|
56 | area->pages = NULL; //XXX |
---|
57 | area->nr_pages = nr_pages; |
---|
58 | area->phys_addr = 0; /* xenbus_map_ring_valloc uses this field! */ |
---|
59 | |
---|
60 | return area; |
---|
61 | |
---|
62 | err1: |
---|
63 | free_pages(virt, order); |
---|
64 | err0: |
---|
65 | return NULL; |
---|
66 | |
---|
67 | } |
---|
68 | EXPORT_SYMBOL_GPL(alloc_vm_area); |
---|
69 | |
---|
70 | void free_vm_area(struct vm_struct *area) |
---|
71 | { |
---|
72 | unsigned int order = get_order(area->size); |
---|
73 | unsigned long i; |
---|
74 | unsigned long phys_addr = __pa(area->addr); |
---|
75 | |
---|
76 | // This area is used for foreign page mappping. |
---|
77 | // So underlying machine page may not be assigned. |
---|
78 | for (i = 0; i < (1 << order); i++) { |
---|
79 | unsigned long ret; |
---|
80 | unsigned long gpfn = (phys_addr >> PAGE_SHIFT) + i; |
---|
81 | struct xen_memory_reservation reservation = { |
---|
82 | .nr_extents = 1, |
---|
83 | .address_bits = 0, |
---|
84 | .extent_order = 0, |
---|
85 | .domid = DOMID_SELF |
---|
86 | }; |
---|
87 | set_xen_guest_handle(reservation.extent_start, &gpfn); |
---|
88 | ret = HYPERVISOR_memory_op(XENMEM_populate_physmap, |
---|
89 | &reservation); |
---|
90 | BUG_ON(ret != 1); |
---|
91 | } |
---|
92 | free_pages((unsigned long)area->addr, order); |
---|
93 | kfree(area); |
---|
94 | } |
---|
95 | EXPORT_SYMBOL_GPL(free_vm_area); |
---|
96 | |
---|
97 | /* |
---|
98 | * Local variables: |
---|
99 | * c-file-style: "linux" |
---|
100 | * indent-tabs-mode: t |
---|
101 | * c-indent-level: 8 |
---|
102 | * c-basic-offset: 8 |
---|
103 | * tab-width: 8 |
---|
104 | * End: |
---|
105 | */ |
---|