Home | History | Annotate | Line # | Download | only in x86
xenfunc.c revision 1.22
      1  1.22    cherry /*	$NetBSD: xenfunc.c,v 1.22 2018/10/18 04:17:18 cherry Exp $	*/
      2   1.2    bouyer 
      3   1.2    bouyer /*
      4   1.2    bouyer  * Copyright (c) 2004 Christian Limpach.
      5   1.2    bouyer  * All rights reserved.
      6   1.2    bouyer  *
      7   1.2    bouyer  * Redistribution and use in source and binary forms, with or without
      8   1.2    bouyer  * modification, are permitted provided that the following conditions
      9   1.2    bouyer  * are met:
     10   1.2    bouyer  * 1. Redistributions of source code must retain the above copyright
     11   1.2    bouyer  *    notice, this list of conditions and the following disclaimer.
     12   1.2    bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.2    bouyer  *    notice, this list of conditions and the following disclaimer in the
     14   1.2    bouyer  *    documentation and/or other materials provided with the distribution.
     15   1.2    bouyer  *
     16   1.2    bouyer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17   1.2    bouyer  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18   1.2    bouyer  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19   1.2    bouyer  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20   1.2    bouyer  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21   1.2    bouyer  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22   1.2    bouyer  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23   1.2    bouyer  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24   1.2    bouyer  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25   1.2    bouyer  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26   1.2    bouyer  */
     27   1.2    bouyer 
     28   1.4    bouyer #include <sys/cdefs.h>
     29  1.22    cherry __KERNEL_RCSID(0, "$NetBSD: xenfunc.c,v 1.22 2018/10/18 04:17:18 cherry Exp $");
     30   1.4    bouyer 
     31   1.2    bouyer #include <sys/param.h>
     32   1.2    bouyer 
     33   1.2    bouyer #include <uvm/uvm_extern.h>
     34   1.2    bouyer 
     35   1.2    bouyer #include <machine/intr.h>
     36   1.2    bouyer #include <machine/vmparam.h>
     37   1.2    bouyer #include <machine/pmap.h>
     38   1.2    bouyer #include <xen/xen.h>
     39   1.2    bouyer #include <xen/hypervisor.h>
     40   1.2    bouyer //#include <xen/evtchn.h>
     41   1.2    bouyer #include <xen/xenpmap.h>
     42   1.2    bouyer #include <machine/pte.h>
     43   1.2    bouyer 
     44  1.22    cherry #define MAX_XEN_IDT 128
     45  1.22    cherry 
     46   1.2    bouyer void xen_set_ldt(vaddr_t, uint32_t);
     47   1.2    bouyer 
     48   1.2    bouyer void
     49   1.2    bouyer invlpg(vaddr_t addr)
     50   1.2    bouyer {
     51  1.18  jdolecek 	int s = splvm(); /* XXXSMP */
     52   1.2    bouyer 	xpq_queue_invlpg(addr);
     53   1.2    bouyer 	splx(s);
     54   1.2    bouyer }
     55   1.2    bouyer 
     56   1.2    bouyer void
     57  1.20    cherry lidt(struct region_descriptor *rd)
     58  1.20    cherry {
     59  1.20    cherry 	/*
     60  1.20    cherry 	 * We need to do this because we can't assume kmem_alloc(9)
     61  1.20    cherry 	 * will be available at the boot stage when this is called.
     62  1.20    cherry 	 */
     63  1.20    cherry 	static char xen_idt_page[PAGE_SIZE] __attribute__((__aligned__ (PAGE_SIZE)));
     64  1.22    cherry 	memset(xen_idt_page, 0, PAGE_SIZE);
     65  1.22    cherry 
     66  1.20    cherry 	struct trap_info *xen_idt = (void * )xen_idt_page;
     67  1.20    cherry 	int xen_idt_idx = 0;
     68  1.20    cherry 
     69  1.20    cherry 	struct trap_info * idd = (void *) rd->rd_base;
     70  1.20    cherry 	const int nidt = rd->rd_limit / (sizeof *idd);
     71  1.20    cherry 
     72  1.20    cherry 	int i;
     73  1.20    cherry 
     74  1.20    cherry 	/*
     75  1.20    cherry 	 * Sweep in all initialised entries, consolidate them back to
     76  1.20    cherry 	 * back in the requestor array.
     77  1.20    cherry 	 */
     78  1.20    cherry 	for (i = 0; i < nidt; i++) {
     79  1.22    cherry 		if (idd[i].address == 0) /* Skip gap */
     80  1.20    cherry 			continue;
     81  1.22    cherry 		KASSERT(xen_idt_idx < MAX_XEN_IDT);
     82  1.20    cherry 		/* Copy over entry */
     83  1.20    cherry 		xen_idt[xen_idt_idx++] = idd[i];
     84  1.20    cherry 	}
     85  1.20    cherry 
     86  1.21    cherry #if defined(__x86_64__)
     87  1.20    cherry 	/* page needs to be r/o */
     88  1.20    cherry 	pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ);
     89  1.21    cherry #endif /* __x86_64 */
     90  1.20    cherry 
     91  1.20    cherry 	/* Hook it up in the hypervisor */
     92  1.20    cherry 	if (HYPERVISOR_set_trap_table(xen_idt))
     93  1.20    cherry 		panic("HYPERVISOR_set_trap_table() failed");
     94  1.20    cherry 
     95  1.21    cherry #if defined(__x86_64__)
     96  1.20    cherry 	/* reset */
     97  1.20    cherry 	pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ|VM_PROT_WRITE);
     98  1.21    cherry #endif /* __x86_64 */
     99  1.20    cherry }
    100  1.20    cherry 
    101  1.20    cherry void
    102   1.2    bouyer lldt(u_short sel)
    103   1.2    bouyer {
    104  1.11       jym #ifndef __x86_64__
    105   1.7        ad 	struct cpu_info *ci;
    106   1.2    bouyer 
    107   1.7        ad 	ci = curcpu();
    108   1.7        ad 
    109   1.7        ad 	if (ci->ci_curldt == sel)
    110   1.7        ad 		return;
    111   1.2    bouyer 	if (sel == GSEL(GLDT_SEL, SEL_KPL))
    112  1.16      maxv 		xen_set_ldt((vaddr_t)ldtstore, NLDT);
    113   1.2    bouyer 	else
    114   1.7        ad 		xen_set_ldt(ci->ci_gdt[IDXSELN(sel)].ld.ld_base,
    115   1.7        ad 		    ci->ci_gdt[IDXSELN(sel)].ld.ld_entries);
    116   1.7        ad 	ci->ci_curldt = sel;
    117  1.11       jym #endif
    118   1.2    bouyer }
    119   1.2    bouyer 
    120   1.2    bouyer void
    121   1.2    bouyer ltr(u_short sel)
    122   1.2    bouyer {
    123  1.12    cherry 	panic("XXX ltr not supported\n");
    124   1.2    bouyer }
    125   1.2    bouyer 
    126   1.2    bouyer void
    127   1.6    cegger lcr0(u_long val)
    128   1.2    bouyer {
    129  1.12    cherry 	panic("XXX lcr0 not supported\n");
    130   1.2    bouyer }
    131   1.2    bouyer 
    132   1.6    cegger u_long
    133   1.2    bouyer rcr0(void)
    134   1.2    bouyer {
    135  1.12    cherry 	/* XXX: handle X86_CR0_TS ? */
    136   1.2    bouyer 	return 0;
    137   1.2    bouyer }
    138   1.2    bouyer 
    139   1.2    bouyer #ifndef __x86_64__
    140   1.2    bouyer void
    141   1.2    bouyer lcr3(vaddr_t val)
    142   1.2    bouyer {
    143  1.18  jdolecek 	int s = splvm(); /* XXXSMP */
    144   1.2    bouyer 	xpq_queue_pt_switch(xpmap_ptom_masked(val));
    145   1.2    bouyer 	splx(s);
    146   1.2    bouyer }
    147   1.2    bouyer #endif
    148   1.2    bouyer 
    149   1.2    bouyer void
    150   1.2    bouyer tlbflush(void)
    151   1.2    bouyer {
    152  1.18  jdolecek 	int s = splvm(); /* XXXSMP */
    153   1.2    bouyer 	xpq_queue_tlb_flush();
    154   1.2    bouyer 	splx(s);
    155   1.2    bouyer }
    156   1.2    bouyer 
    157   1.2    bouyer void
    158   1.2    bouyer tlbflushg(void)
    159   1.2    bouyer {
    160   1.2    bouyer 	tlbflush();
    161   1.2    bouyer }
    162   1.2    bouyer 
    163  1.15     kamil register_t
    164  1.14     kamil rdr0(void)
    165  1.14     kamil {
    166  1.14     kamil 
    167  1.14     kamil 	return HYPERVISOR_get_debugreg(0);
    168  1.14     kamil }
    169  1.14     kamil 
    170  1.14     kamil void
    171  1.15     kamil ldr0(register_t val)
    172  1.14     kamil {
    173  1.14     kamil 
    174  1.14     kamil 	HYPERVISOR_set_debugreg(0, val);
    175  1.14     kamil }
    176  1.14     kamil 
    177  1.15     kamil register_t
    178  1.14     kamil rdr1(void)
    179  1.14     kamil {
    180  1.14     kamil 
    181  1.14     kamil 	return HYPERVISOR_get_debugreg(1);
    182  1.14     kamil }
    183  1.14     kamil 
    184  1.14     kamil void
    185  1.15     kamil ldr1(register_t val)
    186  1.14     kamil {
    187  1.14     kamil 
    188  1.14     kamil 	HYPERVISOR_set_debugreg(1, val);
    189  1.14     kamil }
    190  1.14     kamil 
    191  1.15     kamil register_t
    192  1.14     kamil rdr2(void)
    193  1.14     kamil {
    194  1.14     kamil 
    195  1.14     kamil 	return HYPERVISOR_get_debugreg(2);
    196  1.14     kamil }
    197  1.14     kamil 
    198  1.14     kamil void
    199  1.15     kamil ldr2(register_t val)
    200  1.14     kamil {
    201  1.14     kamil 
    202  1.14     kamil 	HYPERVISOR_set_debugreg(2, val);
    203  1.14     kamil }
    204  1.14     kamil 
    205  1.15     kamil register_t
    206  1.14     kamil rdr3(void)
    207  1.14     kamil {
    208  1.14     kamil 
    209  1.14     kamil 	return HYPERVISOR_get_debugreg(3);
    210  1.14     kamil }
    211  1.14     kamil 
    212  1.14     kamil void
    213  1.15     kamil ldr3(register_t val)
    214  1.14     kamil {
    215  1.14     kamil 
    216  1.14     kamil 	HYPERVISOR_set_debugreg(3, val);
    217  1.14     kamil }
    218  1.15     kamil register_t
    219   1.2    bouyer rdr6(void)
    220   1.2    bouyer {
    221   1.2    bouyer 
    222  1.14     kamil 	return HYPERVISOR_get_debugreg(6);
    223   1.2    bouyer }
    224   1.2    bouyer 
    225   1.2    bouyer void
    226  1.15     kamil ldr6(register_t val)
    227   1.2    bouyer {
    228   1.2    bouyer 
    229   1.2    bouyer 	HYPERVISOR_set_debugreg(6, val);
    230   1.2    bouyer }
    231   1.2    bouyer 
    232  1.15     kamil register_t
    233  1.14     kamil rdr7(void)
    234  1.14     kamil {
    235  1.14     kamil 
    236  1.14     kamil 	return HYPERVISOR_get_debugreg(7);
    237  1.14     kamil }
    238  1.14     kamil 
    239  1.14     kamil void
    240  1.15     kamil ldr7(register_t val)
    241  1.14     kamil {
    242  1.14     kamil 
    243  1.14     kamil 	HYPERVISOR_set_debugreg(7, val);
    244  1.14     kamil }
    245  1.14     kamil 
    246   1.2    bouyer void
    247   1.2    bouyer wbinvd(void)
    248   1.2    bouyer {
    249   1.2    bouyer 
    250   1.2    bouyer 	xpq_flush_cache();
    251   1.2    bouyer }
    252   1.2    bouyer 
    253   1.2    bouyer vaddr_t
    254   1.2    bouyer rcr2(void)
    255   1.2    bouyer {
    256   1.5    cegger 	return curcpu()->ci_vcpu->arch.cr2;
    257   1.2    bouyer }
    258  1.17      maxv 
    259  1.17      maxv #ifdef __x86_64__
    260  1.17      maxv void
    261  1.17      maxv setusergs(int gssel)
    262  1.17      maxv {
    263  1.17      maxv 	HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, gssel);
    264  1.17      maxv }
    265  1.17      maxv #endif
    266