x86_xpmap.c revision 1.1.2.2 1 1.1.2.2 bouyer /* $NetBSD: x86_xpmap.c,v 1.1.2.2 2007/10/25 23:59:24 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.2 bouyer __KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.1.2.2 2007/10/25 23:59:24 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.2 bouyer printf("xen_set_ldt %p %d %p %p\n", (void *)base,
152 1.1.2.2 bouyer entries, ptp, maptp);
153 1.1.2.1 bouyer PTE_CLEARBITS(ptp, maptp, PG_RW);
154 1.1.2.1 bouyer }
155 1.1.2.1 bouyer s = splvm();
156 1.1.2.1 bouyer PTE_UPDATES_FLUSH();
157 1.1.2.1 bouyer
158 1.1.2.1 bouyer xpq_queue_set_ldt(base, entries);
159 1.1.2.1 bouyer xpq_flush_queue();
160 1.1.2.1 bouyer splx(s);
161 1.1.2.1 bouyer }
162 1.1.2.1 bouyer
163 1.1.2.1 bouyer #ifdef XENDEBUG
164 1.1.2.1 bouyer void xpq_debug_dump(void);
165 1.1.2.1 bouyer #endif
166 1.1.2.1 bouyer
167 1.1.2.1 bouyer #define XPQUEUE_SIZE 2048
168 1.1.2.1 bouyer static mmu_update_t xpq_queue[XPQUEUE_SIZE];
169 1.1.2.1 bouyer static int xpq_idx = 0;
170 1.1.2.1 bouyer
171 1.1.2.1 bouyer void
172 1.1.2.1 bouyer xpq_flush_queue()
173 1.1.2.1 bouyer {
174 1.1.2.1 bouyer int i, ok;
175 1.1.2.1 bouyer
176 1.1.2.1 bouyer XENPRINTK2(("flush queue %p entries %d\n", xpq_queue, xpq_idx));
177 1.1.2.1 bouyer for (i = 0; i < xpq_idx; i++)
178 1.1.2.1 bouyer XENPRINTK2(("%d: %p %08x\n", i, (u_int)xpq_queue[i].ptr,
179 1.1.2.1 bouyer (u_int)xpq_queue[i].val));
180 1.1.2.1 bouyer if (xpq_idx != 0 &&
181 1.1.2.1 bouyer HYPERVISOR_mmu_update_self(xpq_queue, xpq_idx, &ok) < 0)
182 1.1.2.1 bouyer panic("HYPERVISOR_mmu_update failed\n");
183 1.1.2.1 bouyer xpq_idx = 0;
184 1.1.2.1 bouyer }
185 1.1.2.1 bouyer
186 1.1.2.1 bouyer static inline void
187 1.1.2.1 bouyer xpq_increment_idx(void)
188 1.1.2.1 bouyer {
189 1.1.2.1 bouyer
190 1.1.2.1 bouyer xpq_idx++;
191 1.1.2.1 bouyer if (__predict_false(xpq_idx == XPQUEUE_SIZE))
192 1.1.2.1 bouyer xpq_flush_queue();
193 1.1.2.1 bouyer }
194 1.1.2.1 bouyer
195 1.1.2.1 bouyer void
196 1.1.2.1 bouyer xpq_queue_machphys_update(paddr_t ma, paddr_t pa)
197 1.1.2.1 bouyer {
198 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_machphys_update ma=%p pa=%p\n", (void *)ma, (void *)pa));
199 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = ma | MMU_MACHPHYS_UPDATE;
200 1.1.2.1 bouyer xpq_queue[xpq_idx].val = (pa - XPMAP_OFFSET) >> PAGE_SHIFT;
201 1.1.2.1 bouyer xpq_increment_idx();
202 1.1.2.1 bouyer #ifdef XENDEBUG_SYNC
203 1.1.2.1 bouyer xpq_flush_queue();
204 1.1.2.1 bouyer #endif
205 1.1.2.1 bouyer }
206 1.1.2.1 bouyer
207 1.1.2.1 bouyer void
208 1.1.2.1 bouyer xpq_queue_pde_update(pd_entry_t *ptr, pd_entry_t val)
209 1.1.2.1 bouyer {
210 1.1.2.1 bouyer
211 1.1.2.1 bouyer KASSERT(((paddr_t)ptr & 3) == 0);
212 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = (paddr_t)ptr | MMU_NORMAL_PT_UPDATE;
213 1.1.2.1 bouyer xpq_queue[xpq_idx].val = val;
214 1.1.2.1 bouyer xpq_increment_idx();
215 1.1.2.1 bouyer #ifdef XENDEBUG_SYNC
216 1.1.2.1 bouyer xpq_flush_queue();
217 1.1.2.1 bouyer #endif
218 1.1.2.1 bouyer }
219 1.1.2.1 bouyer
220 1.1.2.1 bouyer void
221 1.1.2.1 bouyer xpq_queue_pte_update(pt_entry_t *ptr, pt_entry_t val)
222 1.1.2.1 bouyer {
223 1.1.2.1 bouyer
224 1.1.2.1 bouyer KASSERT(((paddr_t)ptr & 3) == 0);
225 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = (paddr_t)ptr | MMU_NORMAL_PT_UPDATE;
226 1.1.2.1 bouyer xpq_queue[xpq_idx].val = val;
227 1.1.2.1 bouyer xpq_increment_idx();
228 1.1.2.1 bouyer #ifdef XENDEBUG_SYNC
229 1.1.2.1 bouyer xpq_flush_queue();
230 1.1.2.1 bouyer #endif
231 1.1.2.1 bouyer }
232 1.1.2.1 bouyer
233 1.1.2.1 bouyer #ifdef XEN3
234 1.1.2.1 bouyer void
235 1.1.2.1 bouyer xpq_queue_pt_switch(paddr_t pa)
236 1.1.2.1 bouyer {
237 1.1.2.1 bouyer struct mmuext_op op;
238 1.1.2.1 bouyer xpq_flush_queue();
239 1.1.2.1 bouyer
240 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_pt_switch: %p %p\n", (void *)pa, (void *)pa));
241 1.1.2.1 bouyer op.cmd = MMUEXT_NEW_BASEPTR;
242 1.1.2.1 bouyer op.arg1.mfn = pa >> PAGE_SHIFT;
243 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
244 1.1.2.1 bouyer panic("xpq_queue_pt_switch");
245 1.1.2.1 bouyer }
246 1.1.2.1 bouyer
247 1.1.2.1 bouyer void
248 1.1.2.1 bouyer xpq_queue_pin_table(paddr_t pa)
249 1.1.2.1 bouyer {
250 1.1.2.1 bouyer struct mmuext_op op;
251 1.1.2.1 bouyer xpq_flush_queue();
252 1.1.2.1 bouyer
253 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_pin_table: %p %p\n", (void *)pa, (void *)pa));
254 1.1.2.1 bouyer op.arg1.mfn = pa >> PAGE_SHIFT;
255 1.1.2.1 bouyer
256 1.1.2.1 bouyer #ifdef __x86_64__
257 1.1.2.1 bouyer op.cmd = MMUEXT_PIN_L4_TABLE;
258 1.1.2.1 bouyer #else
259 1.1.2.1 bouyer op.cmd = MMUEXT_PIN_L2_TABLE;
260 1.1.2.1 bouyer #endif
261 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
262 1.1.2.1 bouyer panic("xpq_queue_pin_table");
263 1.1.2.1 bouyer }
264 1.1.2.1 bouyer
265 1.1.2.1 bouyer void
266 1.1.2.1 bouyer xpq_queue_unpin_table(paddr_t pa)
267 1.1.2.1 bouyer {
268 1.1.2.1 bouyer struct mmuext_op op;
269 1.1.2.1 bouyer xpq_flush_queue();
270 1.1.2.1 bouyer
271 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_unpin_table: %p %p\n", (void *)pa, (void *)pa));
272 1.1.2.1 bouyer op.arg1.mfn = pa >> PAGE_SHIFT;
273 1.1.2.1 bouyer op.cmd = MMUEXT_UNPIN_TABLE;
274 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
275 1.1.2.1 bouyer panic("xpq_queue_unpin_table");
276 1.1.2.1 bouyer }
277 1.1.2.1 bouyer
278 1.1.2.1 bouyer void
279 1.1.2.1 bouyer xpq_queue_set_ldt(vaddr_t va, uint32_t entries)
280 1.1.2.1 bouyer {
281 1.1.2.1 bouyer struct mmuext_op op;
282 1.1.2.1 bouyer xpq_flush_queue();
283 1.1.2.1 bouyer
284 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_set_ldt\n"));
285 1.1.2.1 bouyer KASSERT(va == (va & ~PAGE_MASK));
286 1.1.2.1 bouyer op.cmd = MMUEXT_SET_LDT;
287 1.1.2.1 bouyer op.arg1.linear_addr = va;
288 1.1.2.1 bouyer op.arg2.nr_ents = entries;
289 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
290 1.1.2.1 bouyer panic("xpq_queue_set_ldt");
291 1.1.2.1 bouyer }
292 1.1.2.1 bouyer
293 1.1.2.1 bouyer void
294 1.1.2.1 bouyer xpq_queue_tlb_flush()
295 1.1.2.1 bouyer {
296 1.1.2.1 bouyer struct mmuext_op op;
297 1.1.2.1 bouyer xpq_flush_queue();
298 1.1.2.1 bouyer
299 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_tlb_flush\n"));
300 1.1.2.1 bouyer op.cmd = MMUEXT_TLB_FLUSH_LOCAL;
301 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
302 1.1.2.1 bouyer panic("xpq_queue_tlb_flush");
303 1.1.2.1 bouyer }
304 1.1.2.1 bouyer
305 1.1.2.1 bouyer void
306 1.1.2.1 bouyer xpq_flush_cache()
307 1.1.2.1 bouyer {
308 1.1.2.1 bouyer struct mmuext_op op;
309 1.1.2.1 bouyer int s = splvm();
310 1.1.2.1 bouyer xpq_flush_queue();
311 1.1.2.1 bouyer
312 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_flush_cache\n"));
313 1.1.2.1 bouyer op.cmd = MMUEXT_FLUSH_CACHE;
314 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
315 1.1.2.1 bouyer panic("xpq_flush_cache");
316 1.1.2.1 bouyer splx(s);
317 1.1.2.1 bouyer }
318 1.1.2.1 bouyer
319 1.1.2.1 bouyer void
320 1.1.2.1 bouyer xpq_queue_invlpg(vaddr_t va)
321 1.1.2.1 bouyer {
322 1.1.2.1 bouyer struct mmuext_op op;
323 1.1.2.1 bouyer xpq_flush_queue();
324 1.1.2.1 bouyer
325 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_invlpg %p\n", (void *)va));
326 1.1.2.1 bouyer op.cmd = MMUEXT_INVLPG_LOCAL;
327 1.1.2.1 bouyer op.arg1.linear_addr = (va & ~PAGE_MASK);
328 1.1.2.1 bouyer if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
329 1.1.2.1 bouyer panic("xpq_queue_invlpg");
330 1.1.2.1 bouyer }
331 1.1.2.1 bouyer
332 1.1.2.1 bouyer int
333 1.1.2.1 bouyer xpq_update_foreign(pt_entry_t *ptr, pt_entry_t val, int dom)
334 1.1.2.1 bouyer {
335 1.1.2.1 bouyer mmu_update_t op;
336 1.1.2.1 bouyer int ok;
337 1.1.2.1 bouyer xpq_flush_queue();
338 1.1.2.1 bouyer
339 1.1.2.1 bouyer op.ptr = (paddr_t)ptr;
340 1.1.2.1 bouyer op.val = val;
341 1.1.2.1 bouyer if (HYPERVISOR_mmu_update(&op, 1, &ok, dom) < 0)
342 1.1.2.1 bouyer return EFAULT;
343 1.1.2.1 bouyer return (0);
344 1.1.2.1 bouyer }
345 1.1.2.1 bouyer #else /* XEN3 */
346 1.1.2.1 bouyer void
347 1.1.2.1 bouyer xpq_queue_pt_switch(paddr_t pa)
348 1.1.2.1 bouyer {
349 1.1.2.1 bouyer
350 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_pt_switch: %p %p\n", (void *)pa, (void *)pa));
351 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = pa | MMU_EXTENDED_COMMAND;
352 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_NEW_BASEPTR;
353 1.1.2.1 bouyer xpq_increment_idx();
354 1.1.2.1 bouyer }
355 1.1.2.1 bouyer
356 1.1.2.1 bouyer void
357 1.1.2.1 bouyer xpq_queue_pin_table(paddr_t pa)
358 1.1.2.1 bouyer {
359 1.1.2.1 bouyer
360 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_pin_table: %p %p\n", (void *)pa, (void *)pa));
361 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = pa | MMU_EXTENDED_COMMAND;
362 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_PIN_L2_TABLE;
363 1.1.2.1 bouyer xpq_increment_idx();
364 1.1.2.1 bouyer }
365 1.1.2.1 bouyer
366 1.1.2.1 bouyer void
367 1.1.2.1 bouyer xpq_queue_unpin_table(paddr_t pa)
368 1.1.2.1 bouyer {
369 1.1.2.1 bouyer
370 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_unpin_table: %p %p\n", (void *)pa, (void *)pa));
371 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = pa | MMU_EXTENDED_COMMAND;
372 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_UNPIN_TABLE;
373 1.1.2.1 bouyer xpq_increment_idx();
374 1.1.2.1 bouyer }
375 1.1.2.1 bouyer
376 1.1.2.1 bouyer void
377 1.1.2.1 bouyer xpq_queue_set_ldt(vaddr_t va, uint32_t entries)
378 1.1.2.1 bouyer {
379 1.1.2.1 bouyer
380 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_set_ldt\n"));
381 1.1.2.1 bouyer KASSERT(va == (va & ~PAGE_MASK));
382 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = MMU_EXTENDED_COMMAND | va;
383 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_SET_LDT | (entries << MMUEXT_CMD_SHIFT);
384 1.1.2.1 bouyer xpq_increment_idx();
385 1.1.2.1 bouyer }
386 1.1.2.1 bouyer
387 1.1.2.1 bouyer void
388 1.1.2.1 bouyer xpq_queue_tlb_flush()
389 1.1.2.1 bouyer {
390 1.1.2.1 bouyer
391 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_tlb_flush\n"));
392 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = MMU_EXTENDED_COMMAND;
393 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_TLB_FLUSH;
394 1.1.2.1 bouyer xpq_increment_idx();
395 1.1.2.1 bouyer }
396 1.1.2.1 bouyer
397 1.1.2.1 bouyer void
398 1.1.2.1 bouyer xpq_flush_cache()
399 1.1.2.1 bouyer {
400 1.1.2.1 bouyer int s = splvm();
401 1.1.2.1 bouyer
402 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_flush_cache\n"));
403 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = MMU_EXTENDED_COMMAND;
404 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_FLUSH_CACHE;
405 1.1.2.1 bouyer xpq_increment_idx();
406 1.1.2.1 bouyer xpq_flush_queue();
407 1.1.2.1 bouyer splx(s);
408 1.1.2.1 bouyer }
409 1.1.2.1 bouyer
410 1.1.2.1 bouyer void
411 1.1.2.1 bouyer xpq_queue_invlpg(vaddr_t va)
412 1.1.2.1 bouyer {
413 1.1.2.1 bouyer
414 1.1.2.1 bouyer XENPRINTK2(("xpq_queue_invlpg %p\n", (void *)va));
415 1.1.2.1 bouyer xpq_queue[xpq_idx].ptr = (va & ~PAGE_MASK) | MMU_EXTENDED_COMMAND;
416 1.1.2.1 bouyer xpq_queue[xpq_idx].val = MMUEXT_INVLPG;
417 1.1.2.1 bouyer xpq_increment_idx();
418 1.1.2.1 bouyer }
419 1.1.2.1 bouyer
420 1.1.2.1 bouyer int
421 1.1.2.1 bouyer xpq_update_foreign(pt_entry_t *ptr, pt_entry_t val, int dom)
422 1.1.2.1 bouyer {
423 1.1.2.1 bouyer mmu_update_t xpq_up[3];
424 1.1.2.1 bouyer
425 1.1.2.1 bouyer xpq_up[0].ptr = MMU_EXTENDED_COMMAND;
426 1.1.2.1 bouyer xpq_up[0].val = MMUEXT_SET_FOREIGNDOM | (dom << 16);
427 1.1.2.1 bouyer xpq_up[1].ptr = (paddr_t)ptr;
428 1.1.2.1 bouyer xpq_up[1].val = val;
429 1.1.2.1 bouyer if (HYPERVISOR_mmu_update_self(xpq_up, 2, NULL) < 0)
430 1.1.2.1 bouyer return EFAULT;
431 1.1.2.1 bouyer return (0);
432 1.1.2.1 bouyer }
433 1.1.2.1 bouyer #endif /* XEN3 */
434 1.1.2.1 bouyer
435 1.1.2.1 bouyer #ifdef XENDEBUG
436 1.1.2.1 bouyer void
437 1.1.2.1 bouyer xpq_debug_dump()
438 1.1.2.1 bouyer {
439 1.1.2.1 bouyer int i;
440 1.1.2.1 bouyer
441 1.1.2.1 bouyer XENPRINTK2(("idx: %d\n", xpq_idx));
442 1.1.2.1 bouyer for (i = 0; i < xpq_idx; i++) {
443 1.1.2.1 bouyer sprintf(XBUF, "%x %08x ", (u_int)xpq_queue[i].ptr,
444 1.1.2.1 bouyer (u_int)xpq_queue[i].val);
445 1.1.2.1 bouyer if (++i < xpq_idx)
446 1.1.2.1 bouyer sprintf(XBUF + strlen(XBUF), "%x %08x ",
447 1.1.2.1 bouyer (u_int)xpq_queue[i].ptr, (u_int)xpq_queue[i].val);
448 1.1.2.1 bouyer if (++i < xpq_idx)
449 1.1.2.1 bouyer sprintf(XBUF + strlen(XBUF), "%x %08x ",
450 1.1.2.1 bouyer (u_int)xpq_queue[i].ptr, (u_int)xpq_queue[i].val);
451 1.1.2.1 bouyer if (++i < xpq_idx)
452 1.1.2.1 bouyer sprintf(XBUF + strlen(XBUF), "%x %08x ",
453 1.1.2.1 bouyer (u_int)xpq_queue[i].ptr, (u_int)xpq_queue[i].val);
454 1.1.2.1 bouyer XENPRINTK2(("%d: %s\n", xpq_idx, XBUF));
455 1.1.2.1 bouyer }
456 1.1.2.1 bouyer }
457 1.1.2.1 bouyer #endif
458