ia64/xen-unstable

view linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c @ 9762:a3cc276f2e87

[IA64] dma paravirtualization

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@localhost
date Tue Apr 25 16:53:27 2006 -0600 (2006-04-25)
parents
children e502007031f4
line source
1 /******************************************************************************
2 * include/asm-ia64/shadow.h
3 *
4 * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
5 * VA Linux Systems Japan K.K.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
23 //#include <linux/kernel.h>
24 #include <linux/spinlock.h>
25 #include <linux/bootmem.h>
26 #include <asm/page.h>
27 #include <asm/hypervisor.h>
28 #include <asm/hypercall.h>
30 #define XEN_IA64_BALLOON_IS_NOT_YET
31 #ifndef XEN_IA64_BALLOON_IS_NOT_YET
32 #include <xen/balloon.h>
33 #else
34 #define balloon_lock(flags) ((void)flags)
35 #define balloon_unlock(flags) ((void)flags)
36 #endif
39 //XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear()
40 // move those to lib/contiguous_bitmap?
41 //XXX discontigmem/sparsemem
43 /*
44 * Bitmap is indexed by page number. If bit is set, the page is part of a
45 * xen_create_contiguous_region() area of memory.
46 */
47 unsigned long *contiguous_bitmap;
49 void
50 contiguous_bitmap_init(unsigned long end_pfn)
51 {
52 unsigned long size = (end_pfn + 2 * BITS_PER_LONG) >> 3;
53 contiguous_bitmap = alloc_bootmem_low_pages(size);
54 BUG_ON(!contiguous_bitmap);
55 memset(contiguous_bitmap, 0, size);
56 }
58 #if 0
59 int
60 contiguous_bitmap_test(void* p)
61 {
62 return test_bit(__pa(p) >> PAGE_SHIFT, contiguous_bitmap);
63 }
64 #endif
66 static void contiguous_bitmap_set(
67 unsigned long first_page, unsigned long nr_pages)
68 {
69 unsigned long start_off, end_off, curr_idx, end_idx;
71 curr_idx = first_page / BITS_PER_LONG;
72 start_off = first_page & (BITS_PER_LONG-1);
73 end_idx = (first_page + nr_pages) / BITS_PER_LONG;
74 end_off = (first_page + nr_pages) & (BITS_PER_LONG-1);
76 if (curr_idx == end_idx) {
77 contiguous_bitmap[curr_idx] |=
78 ((1UL<<end_off)-1) & -(1UL<<start_off);
79 } else {
80 contiguous_bitmap[curr_idx] |= -(1UL<<start_off);
81 while ( ++curr_idx < end_idx )
82 contiguous_bitmap[curr_idx] = ~0UL;
83 contiguous_bitmap[curr_idx] |= (1UL<<end_off)-1;
84 }
85 }
87 static void contiguous_bitmap_clear(
88 unsigned long first_page, unsigned long nr_pages)
89 {
90 unsigned long start_off, end_off, curr_idx, end_idx;
92 curr_idx = first_page / BITS_PER_LONG;
93 start_off = first_page & (BITS_PER_LONG-1);
94 end_idx = (first_page + nr_pages) / BITS_PER_LONG;
95 end_off = (first_page + nr_pages) & (BITS_PER_LONG-1);
97 if (curr_idx == end_idx) {
98 contiguous_bitmap[curr_idx] &=
99 -(1UL<<end_off) | ((1UL<<start_off)-1);
100 } else {
101 contiguous_bitmap[curr_idx] &= (1UL<<start_off)-1;
102 while ( ++curr_idx != end_idx )
103 contiguous_bitmap[curr_idx] = 0;
104 contiguous_bitmap[curr_idx] &= -(1UL<<end_off);
105 }
106 }
108 /* Ensure multi-page extents are contiguous in machine memory. */
109 int
110 __xen_create_contiguous_region(unsigned long vstart,
111 unsigned int order, unsigned int address_bits)
112 {
113 unsigned long error = 0;
114 unsigned long gphys = __pa(vstart);
115 unsigned long start_gpfn = gphys >> PAGE_SHIFT;
116 unsigned long num_pfn = 1 << order;
117 unsigned long i;
118 unsigned long flags;
120 scrub_pages(vstart, 1 << order);
122 balloon_lock(flags);
124 //XXX order
125 for (i = 0; i < num_pfn; i++) {
126 error = HYPERVISOR_zap_physmap(start_gpfn + i, 0);
127 if (error) {
128 goto out;
129 }
130 }
132 error = HYPERVISOR_populate_physmap(start_gpfn, order, address_bits);
133 contiguous_bitmap_set(start_gpfn, 1UL << order);
134 #if 0
135 {
136 unsigned long mfn;
137 unsigned long mfn_prev = ~0UL;
138 for (i = 0; i < 1 << order; i++) {
139 mfn = pfn_to_mfn_for_dma(start_gpfn + i);
140 if (mfn_prev != ~0UL && mfn != mfn_prev + 1) {
141 xprintk("\n");
142 xprintk("%s:%d order %d "
143 "start 0x%lx bus 0x%lx machine 0x%lx\n",
144 __func__, __LINE__, order,
145 vstart, virt_to_bus((void*)vstart),
146 phys_to_machine_for_dma(gphys));
147 xprintk("mfn: ");
148 for (i = 0; i < 1 << order; i++) {
149 mfn = pfn_to_mfn_for_dma(start_gpfn + i);
150 xprintk("0x%lx ", mfn);
151 }
152 xprintk("\n");
153 goto out;
154 }
155 mfn_prev = mfn;
156 }
157 }
158 #endif
159 out:
160 balloon_unlock(flags);
161 return error;
162 }
164 void
165 __xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
166 {
167 unsigned long error = 0;
168 unsigned long gphys = __pa(vstart);
169 unsigned long start_gpfn = gphys >> PAGE_SHIFT;
170 unsigned long num_pfn = 1 << order;
171 unsigned long i;
172 unsigned long flags;
174 scrub_pages(vstart, 1 << order);
176 balloon_lock(flags);
178 contiguous_bitmap_clear(start_gpfn, 1UL << order);
180 //XXX order
181 for (i = 0; i < num_pfn; i++) {
182 error = HYPERVISOR_zap_physmap(start_gpfn + i, 0);
183 if (error) {
184 goto out;
185 }
186 }
188 for (i = 0; i < num_pfn; i++) {
189 error = HYPERVISOR_populate_physmap(start_gpfn + i, 0, 0);
190 if (error) {
191 goto out;
192 }
193 }
195 out:
196 balloon_unlock(flags);
197 if (error) {
198 //XXX
199 }
200 }
203 ///////////////////////////////////////////////////////////////////////////
204 //XXX taken from balloon.c
205 // temporal hack until balloon driver support.
206 #include <linux/module.h>
208 struct page *balloon_alloc_empty_page_range(unsigned long nr_pages)
209 {
210 unsigned long vstart;
211 unsigned int order = get_order(nr_pages * PAGE_SIZE);
213 vstart = __get_free_pages(GFP_KERNEL, order);
214 if (vstart == 0)
215 return NULL;
217 return virt_to_page(vstart);
218 }
220 void balloon_dealloc_empty_page_range(
221 struct page *page, unsigned long nr_pages)
222 {
223 __free_pages(page, get_order(nr_pages * PAGE_SIZE));
224 }
226 void balloon_update_driver_allowance(long delta)
227 {
228 }
230 EXPORT_SYMBOL(balloon_alloc_empty_page_range);
231 EXPORT_SYMBOL(balloon_dealloc_empty_page_range);
232 EXPORT_SYMBOL(balloon_update_driver_allowance);