Home | History | Annotate | Line # | Download | only in x86
      1  1.29  riastrad /*	$NetBSD: xenfunc.c,v 1.29 2022/08/20 23:48:51 riastradh 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.29  riastrad __KERNEL_RCSID(0, "$NetBSD: xenfunc.c,v 1.29 2022/08/20 23:48:51 riastradh 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.29  riastrad #include <machine/pmap_private.h>
     39   1.2    bouyer #include <xen/xen.h>
     40   1.2    bouyer #include <xen/hypervisor.h>
     41   1.2    bouyer //#include <xen/evtchn.h>
     42   1.2    bouyer #include <xen/xenpmap.h>
     43   1.2    bouyer #include <machine/pte.h>
     44   1.2    bouyer 
     45  1.22    cherry #define MAX_XEN_IDT 128
     46  1.22    cherry 
     47   1.2    bouyer void xen_set_ldt(vaddr_t, uint32_t);
     48   1.2    bouyer 
     49   1.2    bouyer void
     50  1.24    cherry invlpg(vaddr_t addr)
     51   1.2    bouyer {
     52  1.18  jdolecek 	int s = splvm(); /* XXXSMP */
     53   1.2    bouyer 	xpq_queue_invlpg(addr);
     54   1.2    bouyer 	splx(s);
     55   1.2    bouyer }
     56   1.2    bouyer 
     57   1.2    bouyer void
     58  1.24    cherry lidt(struct region_descriptor *rd)
     59  1.20    cherry {
     60  1.20    cherry 	/*
     61  1.20    cherry 	 * We need to do this because we can't assume kmem_alloc(9)
     62  1.20    cherry 	 * will be available at the boot stage when this is called.
     63  1.20    cherry 	 */
     64  1.20    cherry 	static char xen_idt_page[PAGE_SIZE] __attribute__((__aligned__ (PAGE_SIZE)));
     65  1.27    bouyer #if defined(__x86_64__)
     66  1.27    bouyer 	kpreempt_disable();
     67  1.27    bouyer #endif
     68  1.22    cherry 	memset(xen_idt_page, 0, PAGE_SIZE);
     69  1.22    cherry 
     70  1.20    cherry 	struct trap_info *xen_idt = (void * )xen_idt_page;
     71  1.20    cherry 	int xen_idt_idx = 0;
     72  1.20    cherry 
     73  1.20    cherry 	struct trap_info * idd = (void *) rd->rd_base;
     74  1.20    cherry 	const int nidt = rd->rd_limit / (sizeof *idd);
     75  1.20    cherry 
     76  1.20    cherry 	int i;
     77  1.20    cherry 
     78  1.20    cherry 	/*
     79  1.20    cherry 	 * Sweep in all initialised entries, consolidate them back to
     80  1.20    cherry 	 * back in the requestor array.
     81  1.20    cherry 	 */
     82  1.20    cherry 	for (i = 0; i < nidt; i++) {
     83  1.22    cherry 		if (idd[i].address == 0) /* Skip gap */
     84  1.20    cherry 			continue;
     85  1.22    cherry 		KASSERT(xen_idt_idx < MAX_XEN_IDT);
     86  1.20    cherry 		/* Copy over entry */
     87  1.20    cherry 		xen_idt[xen_idt_idx++] = idd[i];
     88  1.20    cherry 	}
     89  1.20    cherry 
     90  1.21    cherry #if defined(__x86_64__)
     91  1.20    cherry 	/* page needs to be r/o */
     92  1.20    cherry 	pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ);
     93  1.21    cherry #endif /* __x86_64 */
     94  1.20    cherry 
     95  1.20    cherry 	/* Hook it up in the hypervisor */
     96  1.20    cherry 	if (HYPERVISOR_set_trap_table(xen_idt))
     97  1.20    cherry 		panic("HYPERVISOR_set_trap_table() failed");
     98  1.20    cherry 
     99  1.21    cherry #if defined(__x86_64__)
    100  1.20    cherry 	/* reset */
    101  1.20    cherry 	pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ|VM_PROT_WRITE);
    102  1.27    bouyer 	kpreempt_enable();
    103  1.21    cherry #endif /* __x86_64 */
    104  1.20    cherry }
    105  1.20    cherry 
    106  1.20    cherry void
    107  1.24    cherry lldt(u_short sel)
    108   1.2    bouyer {
    109  1.11       jym #ifndef __x86_64__
    110   1.7        ad 	struct cpu_info *ci;
    111   1.2    bouyer 
    112   1.7        ad 	ci = curcpu();
    113   1.7        ad 
    114   1.7        ad 	if (ci->ci_curldt == sel)
    115   1.7        ad 		return;
    116   1.2    bouyer 	if (sel == GSEL(GLDT_SEL, SEL_KPL))
    117  1.16      maxv 		xen_set_ldt((vaddr_t)ldtstore, NLDT);
    118   1.2    bouyer 	else
    119   1.7        ad 		xen_set_ldt(ci->ci_gdt[IDXSELN(sel)].ld.ld_base,
    120   1.7        ad 		    ci->ci_gdt[IDXSELN(sel)].ld.ld_entries);
    121   1.7        ad 	ci->ci_curldt = sel;
    122  1.11       jym #endif
    123   1.2    bouyer }
    124   1.2    bouyer 
    125   1.2    bouyer void
    126  1.24    cherry ltr(u_short sel)
    127   1.2    bouyer {
    128  1.12    cherry 	panic("XXX ltr not supported\n");
    129   1.2    bouyer }
    130   1.2    bouyer 
    131   1.2    bouyer void
    132  1.25      maxv lcr0(register_t val)
    133   1.2    bouyer {
    134  1.12    cherry 	panic("XXX lcr0 not supported\n");
    135   1.2    bouyer }
    136   1.2    bouyer 
    137  1.25      maxv register_t
    138  1.24    cherry rcr0(void)
    139   1.2    bouyer {
    140  1.12    cherry 	/* XXX: handle X86_CR0_TS ? */
    141   1.2    bouyer 	return 0;
    142   1.2    bouyer }
    143   1.2    bouyer 
    144   1.2    bouyer #ifndef __x86_64__
    145   1.2    bouyer void
    146  1.26       kre lcr3(register_t val)
    147   1.2    bouyer {
    148  1.28    bouyer 	int s = splvm();
    149   1.2    bouyer 	xpq_queue_pt_switch(xpmap_ptom_masked(val));
    150   1.2    bouyer 	splx(s);
    151   1.2    bouyer }
    152   1.2    bouyer #endif
    153   1.2    bouyer 
    154   1.2    bouyer void
    155  1.24    cherry tlbflush(void)
    156   1.2    bouyer {
    157  1.28    bouyer 	int s = splvm();
    158   1.2    bouyer 	xpq_queue_tlb_flush();
    159   1.2    bouyer 	splx(s);
    160   1.2    bouyer }
    161   1.2    bouyer 
    162   1.2    bouyer void
    163  1.24    cherry tlbflushg(void)
    164   1.2    bouyer {
    165   1.2    bouyer 	tlbflush();
    166   1.2    bouyer }
    167   1.2    bouyer 
    168  1.15     kamil register_t
    169  1.24    cherry rdr0(void)
    170  1.14     kamil {
    171  1.14     kamil 
    172  1.14     kamil 	return HYPERVISOR_get_debugreg(0);
    173  1.14     kamil }
    174  1.14     kamil 
    175  1.14     kamil void
    176  1.24    cherry ldr0(register_t val)
    177  1.14     kamil {
    178  1.14     kamil 
    179  1.14     kamil 	HYPERVISOR_set_debugreg(0, val);
    180  1.14     kamil }
    181  1.14     kamil 
    182  1.15     kamil register_t
    183  1.24    cherry rdr1(void)
    184  1.14     kamil {
    185  1.14     kamil 
    186  1.14     kamil 	return HYPERVISOR_get_debugreg(1);
    187  1.14     kamil }
    188  1.14     kamil 
    189  1.14     kamil void
    190  1.24    cherry ldr1(register_t val)
    191  1.14     kamil {
    192  1.14     kamil 
    193  1.14     kamil 	HYPERVISOR_set_debugreg(1, val);
    194  1.14     kamil }
    195  1.14     kamil 
    196  1.15     kamil register_t
    197  1.24    cherry rdr2(void)
    198  1.14     kamil {
    199  1.14     kamil 
    200  1.14     kamil 	return HYPERVISOR_get_debugreg(2);
    201  1.14     kamil }
    202  1.14     kamil 
    203  1.14     kamil void
    204  1.24    cherry ldr2(register_t val)
    205  1.14     kamil {
    206  1.14     kamil 
    207  1.14     kamil 	HYPERVISOR_set_debugreg(2, val);
    208  1.14     kamil }
    209  1.14     kamil 
    210  1.15     kamil register_t
    211  1.24    cherry rdr3(void)
    212  1.14     kamil {
    213  1.14     kamil 
    214  1.14     kamil 	return HYPERVISOR_get_debugreg(3);
    215  1.14     kamil }
    216  1.14     kamil 
    217  1.14     kamil void
    218  1.24    cherry ldr3(register_t val)
    219  1.14     kamil {
    220  1.14     kamil 
    221  1.14     kamil 	HYPERVISOR_set_debugreg(3, val);
    222  1.14     kamil }
    223  1.15     kamil register_t
    224  1.24    cherry rdr6(void)
    225   1.2    bouyer {
    226   1.2    bouyer 
    227  1.14     kamil 	return HYPERVISOR_get_debugreg(6);
    228   1.2    bouyer }
    229   1.2    bouyer 
    230   1.2    bouyer void
    231  1.24    cherry ldr6(register_t val)
    232   1.2    bouyer {
    233   1.2    bouyer 
    234   1.2    bouyer 	HYPERVISOR_set_debugreg(6, val);
    235   1.2    bouyer }
    236   1.2    bouyer 
    237  1.15     kamil register_t
    238  1.24    cherry rdr7(void)
    239  1.14     kamil {
    240  1.14     kamil 
    241  1.14     kamil 	return HYPERVISOR_get_debugreg(7);
    242  1.14     kamil }
    243  1.14     kamil 
    244  1.14     kamil void
    245  1.24    cherry ldr7(register_t val)
    246  1.14     kamil {
    247  1.14     kamil 
    248  1.14     kamil 	HYPERVISOR_set_debugreg(7, val);
    249  1.14     kamil }
    250  1.14     kamil 
    251   1.2    bouyer void
    252  1.24    cherry wbinvd(void)
    253   1.2    bouyer {
    254   1.2    bouyer 
    255   1.2    bouyer 	xpq_flush_cache();
    256   1.2    bouyer }
    257   1.2    bouyer 
    258  1.25      maxv register_t
    259  1.24    cherry rcr2(void)
    260   1.2    bouyer {
    261   1.5    cegger 	return curcpu()->ci_vcpu->arch.cr2;
    262   1.2    bouyer }
    263  1.17      maxv 
    264  1.27    bouyer void
    265  1.27    bouyer lcr2(register_t v)
    266  1.27    bouyer {
    267  1.27    bouyer 	curcpu()->ci_vcpu->arch.cr2 = v;
    268  1.27    bouyer }
    269  1.27    bouyer 
    270  1.17      maxv #ifdef __x86_64__
    271  1.17      maxv void
    272  1.24    cherry setusergs(int gssel)
    273  1.17      maxv {
    274  1.17      maxv 	HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, gssel);
    275  1.17      maxv }
    276  1.17      maxv #endif
    277