x86_xpmap.c revision 1.1.2.1 1 1.1.2.1 bouyer /* $NetBSD: x86_xpmap.c,v 1.1.2.1 2007/10/21 15:41:03 bouyer Exp $ */
2 1.1.2.1 bouyer
3 1.1.2.1 bouyer /*
4 1.1.2.1 bouyer * Copyright (c) 2006 Manuel Bouyer.
5 1.1.2.1 bouyer *
6 1.1.2.1 bouyer * Redistribution and use in source and binary forms, with or without
7 1.1.2.1 bouyer * modification, are permitted provided that the following conditions
8 1.1.2.1 bouyer * are met:
9 1.1.2.1 bouyer * 1. Redistributions of source code must retain the above copyright
10 1.1.2.1 bouyer * notice, this list of conditions and the following disclaimer.
11 1.1.2.1 bouyer * 2. Redistributions in binary form must reproduce the above copyright
12 1.1.2.1 bouyer * notice, this list of conditions and the following disclaimer in the
13 1.1.2.1 bouyer * documentation and/or other materials provided with the distribution.
14 1.1.2.1 bouyer * 3. All advertising materials mentioning features or use of this software
15 1.1.2.1 bouyer * must display the following acknowledgement:
16 1.1.2.1 bouyer * This product includes software developed by Manuel Bouyer.
17 1.1.2.1 bouyer * 4. The name of the author may not be used to endorse or promote products
18 1.1.2.1 bouyer * derived from this software without specific prior written permission.
19 1.1.2.1 bouyer *
20 1.1.2.1 bouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 1.1.2.1 bouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 1.1.2.1 bouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 1.1.2.1 bouyer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 1.1.2.1 bouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 1.1.2.1 bouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 1.1.2.1 bouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 1.1.2.1 bouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 1.1.2.1 bouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 1.1.2.1 bouyer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 1.1.2.1 bouyer *
31 1.1.2.1 bouyer */
32 1.1.2.1 bouyer
33 1.1.2.1 bouyer /*
34 1.1.2.1 bouyer *
35 1.1.2.1 bouyer * Copyright (c) 2004 Christian Limpach.
36 1.1.2.1 bouyer * All rights reserved.
37 1.1.2.1 bouyer *
38 1.1.2.1 bouyer * Redistribution and use in source and binary forms, with or without
39 1.1.2.1 bouyer * modification, are permitted provided that the following conditions
40 1.1.2.1 bouyer * are met:
41 1.1.2.1 bouyer * 1. Redistributions of source code must retain the above copyright
42 1.1.2.1 bouyer * notice, this list of conditions and the following disclaimer.
43 1.1.2.1 bouyer * 2. Redistributions in binary form must reproduce the above copyright
44 1.1.2.1 bouyer * notice, this list of conditions and the following disclaimer in the
45 1.1.2.1 bouyer * documentation and/or other materials provided with the distribution.
46 1.1.2.1 bouyer * 3. All advertising materials mentioning features or use of this software
47 1.1.2.1 bouyer * must display the following acknowledgement:
48 1.1.2.1 bouyer * This product includes software developed by Christian Limpach.
49 1.1.2.1 bouyer * 4. The name of the author may not be used to endorse or promote products
50 1.1.2.1 bouyer * derived from this software without specific prior written permission.
51 1.1.2.1 bouyer *
52 1.1.2.1 bouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 1.1.2.1 bouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54 1.1.2.1 bouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55 1.1.2.1 bouyer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56 1.1.2.1 bouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57 1.1.2.1 bouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 1.1.2.1 bouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 1.1.2.1 bouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 1.1.2.1 bouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61 1.1.2.1 bouyer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 1.1.2.1 bouyer */
63 1.1.2.1 bouyer
64 1.1.2.1 bouyer
65 1.1.2.1 bouyer #include <sys/cdefs.h>
66 1.1.2.1 bouyer __KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.1.2.1 2007/10/21 15:41:03 bouyer Exp $");
67 1.1.2.1 bouyer
68 1.1.2.1 bouyer #include "opt_xen.h"
69 1.1.2.1 bouyer
70 1.1.2.1 bouyer #include <sys/param.h>
71 1.1.2.1 bouyer #include <sys/systm.h>
72 1.1.2.1 bouyer
73 1.1.2.1 bouyer #include <uvm/uvm.h>
74 1.1.2.1 bouyer
75 1.1.2.1 bouyer #include <machine/gdt.h>
76 1.1.2.1 bouyer #include <xen/xenfunc.h>
77 1.1.2.1 bouyer
78 1.1.2.1 bouyer #undef XENDEBUG
79 1.1.2.1 bouyer /* #define XENDEBUG_SYNC */
80 1.1.2.1 bouyer /* #define XENDEBUG_LOW */
81 1.1.2.1 bouyer
82 1.1.2.1 bouyer #ifdef XENDEBUG
83 1.1.2.1 bouyer #define XENPRINTF(x) printf x
84 1.1.2.1 bouyer #define XENPRINTK(x) printk x
85 1.1.2.1 bouyer #define XENPRINTK2(x) /* printk x */
86 1.1.2.1 bouyer
87 1.1.2.1 bouyer static char XBUF[256];
88 1.1.2.1 bouyer #else
89 1.1.2.1 bouyer #define XENPRINTF(x)
90 1.1.2.1 bouyer #define XENPRINTK(x)
91 1.1.2.1 bouyer #define XENPRINTK2(x)
92 1.1.2.1 bouyer #endif
93 1.1.2.1 bouyer #define PRINTF(x) printf x
94 1.1.2.1 bouyer #define PRINTK(x) printk x
95 1.1.2.1 bouyer
96 1.1.2.1 bouyer volatile shared_info_t *HYPERVISOR_shared_info;
97 1.1.2.1 bouyer union start_info_union start_info_union;
98 1.1.2.1 bouyer
99 1.1.2.1 bouyer void xen_failsafe_handler(void);
100 1.1.2.1 bouyer
101 1.1.2.1 bouyer #ifdef XEN3
102 1.1.2.1 bouyer #define HYPERVISOR_mmu_update_self(req, count, success_count) \
103 1.1.2.1 bouyer HYPERVISOR_mmu_update((req), (count), (success_count), DOMID_SELF)
104 1.1.2.1 bouyer #else
105 1.1.2.1 bouyer #define HYPERVISOR_mmu_update_self(req, count, success_count) \
106 1.1.2.1 bouyer HYPERVISOR_mmu_update((req), (count), (success_count))
107 1.1.2.1 bouyer #endif
108 1.1.2.1 bouyer
109 1.1.2.1 bouyer void
110 1.1.2.1 bouyer xen_failsafe_handler(void)
111 1.1.2.1 bouyer {
112 1.1.2.1 bouyer
113 1.1.2.1 bouyer panic("xen_failsafe_handler called!\n");
114 1.1.2.1 bouyer }
115 1.1.2.1 bouyer
116 1.1.2.1 bouyer
117 1.1.2.1 bouyer #ifndef __x86_64__
118 1.1.2.1 bouyer void
119 1.1.2.1 bouyer xen_update_descriptor(union descriptor *table, union descriptor *entry)
120 1.1.2.1 bouyer {
121 1.1.2.1 bouyer paddr_t pa;
122 1.1.2.1 bouyer pt_entry_t *ptp;
123 1.1.2.1 bouyer
124 1.1.2.1 bouyer ptp = kvtopte((vaddr_t)table);
125 1.1.2.1 bouyer pa = (*ptp & PG_FRAME) | ((vaddr_t)table & ~PG_FRAME);
126 1.1.2.1 bouyer if (HYPERVISOR_update_descriptor(pa, entry->raw[0], entry->raw[1]))
127 1.1.2.1 bouyer panic("HYPERVISOR_update_descriptor failed\n");
128 1.1.2.1 bouyer }
129 1.1.2.1 bouyer #endif
130 1.1.2.1 bouyer
131 1.1.2.1 bouyer void
132 1.1.2.1 bouyer xen_set_ldt(vaddr_t base, uint32_t entries)
133 1.1.2.1 bouyer {
134 1.1.2.1 bouyer vaddr_t va;
135 1.1.2.1 bouyer vaddr_t end;
136 1.1.2.1 bouyer pt_entry_t *ptp, *maptp;
137 1.1.2.1 bouyer int s;
138 1.1.2.1 bouyer
139 1.1.2.1 bouyer #ifdef __x86_64__
140 1.1.2.1 bouyer end = base + (entries << 3);
141 1.1.2.1 bouyer #else
142 1.1.2.1 bouyer end = base + entries * sizeof(union descriptor);
143 1.1.2.1 bouyer #endif
144 1.1.2.1 bouyer
145 1.1.2.1 bouyer for (va = base; va < end; va += PAGE_SIZE) {
146 1.1.2.1 bouyer KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
147 1.1.2.1 bouyer ptp = kvtopte(va);
148 1.1.2.1 bouyer maptp = (pt_entry_t *)vtomach((vaddr_t)ptp);
149 1.1.2.1 bouyer XENPRINTF(("xen_set_ldt %p %d %p %p\n", (void *)base,
150 1.1.2.1 bouyer entries, ptp, maptp));
151 1.1.2.1 bouyer PTE_CLEARBITS(ptp, maptp, PG_RW);
152 1.1.2.1 bouyer }
153 1.1.2.1 bouyer s = splvm();
154 1.1.2.1 bouyer PTE_UPDATES_FLUSH();
155 1.1.2.1 bouyer
156 1.1.2.1 bouyer xpq_queue_set_ldt(base, entries);
157 1.1.2.1 bouyer xpq_flush_queue();
158 1.1.2.1 bouyer splx(s);
159 1.1.2.1 bouyer }
160 1.1.2.1 bouyer
161 1.1.2.1 bouyer #ifdef XENDEBUG
162 1.1.2.1 bouyer void xpq_debug_dump(void);
163 1.1.2.1 bouyer #endif
164 1.1.2.1 bouyer
165 1.1.2.1 bouyer #define XPQUEUE_SIZE 2048
166 1.1.2.1 bouyer static mmu_update_t xpq_queue[XPQUEUE_SIZE];
167 1.1.2.1 bouyer static int xpq_idx = 0;
168 1.1.2.1 bouyer
169 1.1.2.1 bouyer void
170 1.1.2.1 bouyer xpq_flush_queue()
171 1.1.2.1 bouyer {
172 1.1.2.1 bouyer int i, ok;
173 1.1.2.1 bouyer
174 1.1.2.1 bouyer XENPRINTK2(("flush queue %p entries %d\n", xpq_queue, xpq_idx));
175 1.1.2.1 bouyer for (i = 0; i < xpq_idx; i++)
176 1.1.2.1 bouyer XENPRINTK2(("%d: %p %08x\n", i, (u_int)xpq_queue[i].ptr,
177 1.1.2.1 bouyer (u_int)xpq_queue[i].val));
178 1.1.2.1 bouyer if (xpq_idx != 0 &&
179 1.1.2.1 bouyer HYPERVISOR_mmu_update_self(xpq_queue, xpq_idx, &ok) < 0)
180 1.1.2.1 bouyer panic("HYPERVISOR_mmu_update failed\n");
181 1.1.2.1 bouyer xpq_idx = 0;
182 1.1.2.1 bouyer }
183 1.1.2.1 bouyer
184 1.1.2.1 bouyer static inline void
185 1.1.2.1 bouyer xpq_increment_idx(void)
186 1.1.2.1 bouyer {
187 1.1.2.1 bouyer
188 1.1.2.1 bouyer xpq_idx++;
189 1.1.2.1 bouyer if (__predict_false(xpq_idx == XPQUEUE_SIZE))
190 1.1.2.1 bouyer xpq_flush_queue();
191 1.1.2.1 bouyer }
192 1.1.2.1 bouyer
193 1.1.2.1 bouyer void
194 1.1.2.1 bouyer xpq_queue_machphys_update(paddr_t ma, paddr_t pa)
195 1.1.2.1 bouyer {
196 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_machphys_update ma=%p pa=%p\n", (void *)ma, (void *)pa));
197 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = ma | MMU_MACHPHYS_UPDATE;
198 1.1.2.1 bouyer xpq_queue[xpq_idx].val = (pa - XPMAP_OFFSET) >> PAGE_SHIFT;
199 1.1.2.1 bouyer xpq_increment_idx();
200 1.1.2.1 bouyer #ifdef XENDEBUG_SYNC
201 1.1.2.1 bouyer xpq_flush_queue();
202 1.1.2.1 bouyer #endif
203 1.1.2.1 bouyer }
204 1.1.2.1 bouyer
205 1.1.2.1 bouyer void
206 1.1.2.1 bouyer xpq_queue_pde_update(pd_entry_t *ptr, pd_entry_t val)
207 1.1.2.1 bouyer {
208 1.1.2.1 bouyer
209 1.1.2.1 bouyer KASSERT(((paddr_t)ptr & 3) == 0);
210 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = (paddr_t)ptr | MMU_NORMAL_PT_UPDATE;
211 1.1.2.1 bouyer xpq_queue[xpq_idx].val = val;
212 1.1.2.1 bouyer xpq_increment_idx();
213 1.1.2.1 bouyer #ifdef XENDEBUG_SYNC
214 1.1.2.1 bouyer xpq_flush_queue();
215 1.1.2.1 bouyer #endif
216 1.1.2.1 bouyer }
217 1.1.2.1 bouyer
218 1.1.2.1 bouyer void
219 1.1.2.1 bouyer xpq_queue_pte_update(pt_entry_t *ptr, pt_entry_t val)
220 1.1.2.1 bouyer {
221 1.1.2.1 bouyer
222 1.1.2.1 bouyer KASSERT(((paddr_t)ptr & 3) == 0);
223 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = (paddr_t)ptr | MMU_NORMAL_PT_UPDATE;
224 1.1.2.1 bouyer xpq_queue[xpq_idx].val = val;
225 1.1.2.1 bouyer xpq_increment_idx();
226 1.1.2.1 bouyer #ifdef XENDEBUG_SYNC
227 1.1.2.1 bouyer xpq_flush_queue();
228 1.1.2.1 bouyer #endif
229 1.1.2.1 bouyer }
230 1.1.2.1 bouyer
231 1.1.2.1 bouyer #ifdef XEN3
232 1.1.2.1 bouyer void
233 1.1.2.1 bouyer xpq_queue_pt_switch(paddr_t pa)
234 1.1.2.1 bouyer {
235 1.1.2.1 bouyer struct mmuext_op op;
236 1.1.2.1 bouyer xpq_flush_queue();
237 1.1.2.1 bouyer
238 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_pt_switch: %p %p\n", (void *)pa, (void *)pa));
239 1.1.2.1 bouyer op.cmd = MMUEXT_NEW_BASEPTR;
240 1.1.2.1 bouyer op.arg1.mfn = pa >> PAGE_SHIFT;
241 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
242 1.1.2.1 bouyer panic("xpq_queue_pt_switch");
243 1.1.2.1 bouyer }
244 1.1.2.1 bouyer
245 1.1.2.1 bouyer void
246 1.1.2.1 bouyer xpq_queue_pin_table(paddr_t pa)
247 1.1.2.1 bouyer {
248 1.1.2.1 bouyer struct mmuext_op op;
249 1.1.2.1 bouyer xpq_flush_queue();
250 1.1.2.1 bouyer
251 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_pin_table: %p %p\n", (void *)pa, (void *)pa));
252 1.1.2.1 bouyer op.arg1.mfn = pa >> PAGE_SHIFT;
253 1.1.2.1 bouyer
254 1.1.2.1 bouyer #ifdef __x86_64__
255 1.1.2.1 bouyer op.cmd = MMUEXT_PIN_L4_TABLE;
256 1.1.2.1 bouyer #else
257 1.1.2.1 bouyer op.cmd = MMUEXT_PIN_L2_TABLE;
258 1.1.2.1 bouyer #endif
259 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
260 1.1.2.1 bouyer panic("xpq_queue_pin_table");
261 1.1.2.1 bouyer }
262 1.1.2.1 bouyer
263 1.1.2.1 bouyer void
264 1.1.2.1 bouyer xpq_queue_unpin_table(paddr_t pa)
265 1.1.2.1 bouyer {
266 1.1.2.1 bouyer struct mmuext_op op;
267 1.1.2.1 bouyer xpq_flush_queue();
268 1.1.2.1 bouyer
269 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_unpin_table: %p %p\n", (void *)pa, (void *)pa));
270 1.1.2.1 bouyer op.arg1.mfn = pa >> PAGE_SHIFT;
271 1.1.2.1 bouyer op.cmd = MMUEXT_UNPIN_TABLE;
272 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
273 1.1.2.1 bouyer panic("xpq_queue_unpin_table");
274 1.1.2.1 bouyer }
275 1.1.2.1 bouyer
276 1.1.2.1 bouyer void
277 1.1.2.1 bouyer xpq_queue_set_ldt(vaddr_t va, uint32_t entries)
278 1.1.2.1 bouyer {
279 1.1.2.1 bouyer struct mmuext_op op;
280 1.1.2.1 bouyer xpq_flush_queue();
281 1.1.2.1 bouyer
282 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_set_ldt\n"));
283 1.1.2.1 bouyer KASSERT(va == (va & ~PAGE_MASK));
284 1.1.2.1 bouyer op.cmd = MMUEXT_SET_LDT;
285 1.1.2.1 bouyer op.arg1.linear_addr = va;
286 1.1.2.1 bouyer op.arg2.nr_ents = entries;
287 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
288 1.1.2.1 bouyer panic("xpq_queue_set_ldt");
289 1.1.2.1 bouyer }
290 1.1.2.1 bouyer
291 1.1.2.1 bouyer void
292 1.1.2.1 bouyer xpq_queue_tlb_flush()
293 1.1.2.1 bouyer {
294 1.1.2.1 bouyer struct mmuext_op op;
295 1.1.2.1 bouyer xpq_flush_queue();
296 1.1.2.1 bouyer
297 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_tlb_flush\n"));
298 1.1.2.1 bouyer op.cmd = MMUEXT_TLB_FLUSH_LOCAL;
299 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
300 1.1.2.1 bouyer panic("xpq_queue_tlb_flush");
301 1.1.2.1 bouyer }
302 1.1.2.1 bouyer
303 1.1.2.1 bouyer void
304 1.1.2.1 bouyer xpq_flush_cache()
305 1.1.2.1 bouyer {
306 1.1.2.1 bouyer struct mmuext_op op;
307 1.1.2.1 bouyer int s = splvm();
308 1.1.2.1 bouyer xpq_flush_queue();
309 1.1.2.1 bouyer
310 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_flush_cache\n"));
311 1.1.2.1 bouyer op.cmd = MMUEXT_FLUSH_CACHE;
312 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
313 1.1.2.1 bouyer panic("xpq_flush_cache");
314 1.1.2.1 bouyer splx(s);
315 1.1.2.1 bouyer }
316 1.1.2.1 bouyer
317 1.1.2.1 bouyer void
318 1.1.2.1 bouyer xpq_queue_invlpg(vaddr_t va)
319 1.1.2.1 bouyer {
320 1.1.2.1 bouyer struct mmuext_op op;
321 1.1.2.1 bouyer xpq_flush_queue();
322 1.1.2.1 bouyer
323 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_invlpg %p\n", (void *)va));
324 1.1.2.1 bouyer op.cmd = MMUEXT_INVLPG_LOCAL;
325 1.1.2.1 bouyer op.arg1.linear_addr = (va & ~PAGE_MASK);
326 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
327 1.1.2.1 bouyer panic("xpq_queue_invlpg");
328 1.1.2.1 bouyer }
329 1.1.2.1 bouyer
330 1.1.2.1 bouyer int
331 1.1.2.1 bouyer xpq_update_foreign(pt_entry_t *ptr, pt_entry_t val, int dom)
332 1.1.2.1 bouyer {
333 1.1.2.1 bouyer mmu_update_t op;
334 1.1.2.1 bouyer int ok;
335 1.1.2.1 bouyer xpq_flush_queue();
336 1.1.2.1 bouyer
337 1.1.2.1 bouyer op.ptr = (paddr_t)ptr;
338 1.1.2.1 bouyer op.val = val;
339 1.1.2.1 bouyer if (HYPERVISOR_mmu_update(&op, 1, &ok, dom) < 0)
340 1.1.2.1 bouyer return EFAULT;
341 1.1.2.1 bouyer return (0);
342 1.1.2.1 bouyer }
343 1.1.2.1 bouyer #else /* XEN3 */
344 1.1.2.1 bouyer void
345 1.1.2.1 bouyer xpq_queue_pt_switch(paddr_t pa)
346 1.1.2.1 bouyer {
347 1.1.2.1 bouyer
348 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_pt_switch: %p %p\n", (void *)pa, (void *)pa));
349 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = pa | MMU_EXTENDED_COMMAND;
350 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_NEW_BASEPTR;
351 1.1.2.1 bouyer xpq_increment_idx();
352 1.1.2.1 bouyer }
353 1.1.2.1 bouyer
354 1.1.2.1 bouyer void
355 1.1.2.1 bouyer xpq_queue_pin_table(paddr_t pa)
356 1.1.2.1 bouyer {
357 1.1.2.1 bouyer
358 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_pin_table: %p %p\n", (void *)pa, (void *)pa));
359 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = pa | MMU_EXTENDED_COMMAND;
360 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_PIN_L2_TABLE;
361 1.1.2.1 bouyer xpq_increment_idx();
362 1.1.2.1 bouyer }
363 1.1.2.1 bouyer
364 1.1.2.1 bouyer void
365 1.1.2.1 bouyer xpq_queue_unpin_table(paddr_t pa)
366 1.1.2.1 bouyer {
367 1.1.2.1 bouyer
368 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_unpin_table: %p %p\n", (void *)pa, (void *)pa));
369 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = pa | MMU_EXTENDED_COMMAND;
370 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_UNPIN_TABLE;
371 1.1.2.1 bouyer xpq_increment_idx();
372 1.1.2.1 bouyer }
373 1.1.2.1 bouyer
374 1.1.2.1 bouyer void
375 1.1.2.1 bouyer xpq_queue_set_ldt(vaddr_t va, uint32_t entries)
376 1.1.2.1 bouyer {
377 1.1.2.1 bouyer
378 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_set_ldt\n"));
379 1.1.2.1 bouyer KASSERT(va == (va & ~PAGE_MASK));
380 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = MMU_EXTENDED_COMMAND | va;
381 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_SET_LDT | (entries << MMUEXT_CMD_SHIFT);
382 1.1.2.1 bouyer xpq_increment_idx();
383 1.1.2.1 bouyer }
384 1.1.2.1 bouyer
385 1.1.2.1 bouyer void
386 1.1.2.1 bouyer xpq_queue_tlb_flush()
387 1.1.2.1 bouyer {
388 1.1.2.1 bouyer
389 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_tlb_flush\n"));
390 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = MMU_EXTENDED_COMMAND;
391 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_TLB_FLUSH;
392 1.1.2.1 bouyer xpq_increment_idx();
393 1.1.2.1 bouyer }
394 1.1.2.1 bouyer
395 1.1.2.1 bouyer void
396 1.1.2.1 bouyer xpq_flush_cache()
397 1.1.2.1 bouyer {
398 1.1.2.1 bouyer int s = splvm();
399 1.1.2.1 bouyer
400 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_flush_cache\n"));
401 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = MMU_EXTENDED_COMMAND;
402 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_FLUSH_CACHE;
403 1.1.2.1 bouyer xpq_increment_idx();
404 1.1.2.1 bouyer xpq_flush_queue();
405 1.1.2.1 bouyer splx(s);
406 1.1.2.1 bouyer }
407 1.1.2.1 bouyer
408 1.1.2.1 bouyer void
409 1.1.2.1 bouyer xpq_queue_invlpg(vaddr_t va)
410 1.1.2.1 bouyer {
411 1.1.2.1 bouyer
412 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_invlpg %p\n", (void *)va));
413 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = (va & ~PAGE_MASK) | MMU_EXTENDED_COMMAND;
414 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_INVLPG;
415 1.1.2.1 bouyer xpq_increment_idx();
416 1.1.2.1 bouyer }
417 1.1.2.1 bouyer
418 1.1.2.1 bouyer int
419 1.1.2.1 bouyer xpq_update_foreign(pt_entry_t *ptr, pt_entry_t val, int dom)
420 1.1.2.1 bouyer {
421 1.1.2.1 bouyer mmu_update_t xpq_up[3];
422 1.1.2.1 bouyer
423 1.1.2.1 bouyer xpq_up[0].ptr = MMU_EXTENDED_COMMAND;
424 1.1.2.1 bouyer xpq_up[0].val = MMUEXT_SET_FOREIGNDOM | (dom << 16);
425 1.1.2.1 bouyer xpq_up[1].ptr = (paddr_t)ptr;
426 1.1.2.1 bouyer xpq_up[1].val = val;
427 1.1.2.1 bouyer if (HYPERVISOR_mmu_update_self(xpq_up, 2, NULL) < 0)
428 1.1.2.1 bouyer return EFAULT;
429 1.1.2.1 bouyer return (0);
430 1.1.2.1 bouyer }
431 1.1.2.1 bouyer #endif /* XEN3 */
432 1.1.2.1 bouyer
433 1.1.2.1 bouyer #ifdef XENDEBUG
434 1.1.2.1 bouyer void
435 1.1.2.1 bouyer xpq_debug_dump()
436 1.1.2.1 bouyer {
437 1.1.2.1 bouyer int i;
438 1.1.2.1 bouyer
439 1.1.2.1 bouyer XENPRINTK2(("idx: %d\n", xpq_idx));
440 1.1.2.1 bouyer for (i = 0; i < xpq_idx; i++) {
441 1.1.2.1 bouyer sprintf(XBUF, "%x %08x ", (u_int)xpq_queue[i].ptr,
442 1.1.2.1 bouyer (u_int)xpq_queue[i].val);
443 1.1.2.1 bouyer if (++i < xpq_idx)
444 1.1.2.1 bouyer sprintf(XBUF + strlen(XBUF), "%x %08x ",
445 1.1.2.1 bouyer (u_int)xpq_queue[i].ptr, (u_int)xpq_queue[i].val);
446 1.1.2.1 bouyer if (++i < xpq_idx)
447 1.1.2.1 bouyer sprintf(XBUF + strlen(XBUF), "%x %08x ",
448 1.1.2.1 bouyer (u_int)xpq_queue[i].ptr, (u_int)xpq_queue[i].val);
449 1.1.2.1 bouyer if (++i < xpq_idx)
450 1.1.2.1 bouyer sprintf(XBUF + strlen(XBUF), "%x %08x ",
451 1.1.2.1 bouyer (u_int)xpq_queue[i].ptr, (u_int)xpq_queue[i].val);
452 1.1.2.1 bouyer XENPRINTK2(("%d: %s\n", xpq_idx, XBUF));
453 1.1.2.1 bouyer }
454 1.1.2.1 bouyer }
455 1.1.2.1 bouyer #endif
456