Home | History | Annotate | Line # | Download | only in x86
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