1*8f18579dSriastradh /* $NetBSD: xenfunc.c,v 1.29 2022/08/20 23:48:51 riastradh Exp $ */
24e541343Sbouyer
34e541343Sbouyer /*
44e541343Sbouyer * Copyright (c) 2004 Christian Limpach.
54e541343Sbouyer * All rights reserved.
64e541343Sbouyer *
74e541343Sbouyer * Redistribution and use in source and binary forms, with or without
84e541343Sbouyer * modification, are permitted provided that the following conditions
94e541343Sbouyer * are met:
104e541343Sbouyer * 1. Redistributions of source code must retain the above copyright
114e541343Sbouyer * notice, this list of conditions and the following disclaimer.
124e541343Sbouyer * 2. Redistributions in binary form must reproduce the above copyright
134e541343Sbouyer * notice, this list of conditions and the following disclaimer in the
144e541343Sbouyer * documentation and/or other materials provided with the distribution.
154e541343Sbouyer *
164e541343Sbouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
174e541343Sbouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
184e541343Sbouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
194e541343Sbouyer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
204e541343Sbouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
214e541343Sbouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
224e541343Sbouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
234e541343Sbouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
244e541343Sbouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
254e541343Sbouyer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
264e541343Sbouyer */
274e541343Sbouyer
28a9cd1764Sbouyer #include <sys/cdefs.h>
29*8f18579dSriastradh __KERNEL_RCSID(0, "$NetBSD: xenfunc.c,v 1.29 2022/08/20 23:48:51 riastradh Exp $");
30a9cd1764Sbouyer
314e541343Sbouyer #include <sys/param.h>
324e541343Sbouyer
334e541343Sbouyer #include <uvm/uvm_extern.h>
344e541343Sbouyer
354e541343Sbouyer #include <machine/intr.h>
364e541343Sbouyer #include <machine/vmparam.h>
374e541343Sbouyer #include <machine/pmap.h>
38*8f18579dSriastradh #include <machine/pmap_private.h>
394e541343Sbouyer #include <xen/xen.h>
404e541343Sbouyer #include <xen/hypervisor.h>
414e541343Sbouyer //#include <xen/evtchn.h>
424e541343Sbouyer #include <xen/xenpmap.h>
434e541343Sbouyer #include <machine/pte.h>
444e541343Sbouyer
450e975399Scherry #define MAX_XEN_IDT 128
460e975399Scherry
474e541343Sbouyer void xen_set_ldt(vaddr_t, uint32_t);
484e541343Sbouyer
494e541343Sbouyer void
invlpg(vaddr_t addr)50afc14682Scherry invlpg(vaddr_t addr)
514e541343Sbouyer {
528c3f6558Sjdolecek int s = splvm(); /* XXXSMP */
534e541343Sbouyer xpq_queue_invlpg(addr);
544e541343Sbouyer splx(s);
554e541343Sbouyer }
564e541343Sbouyer
574e541343Sbouyer void
lidt(struct region_descriptor * rd)58afc14682Scherry lidt(struct region_descriptor *rd)
594281462fScherry {
604281462fScherry /*
614281462fScherry * We need to do this because we can't assume kmem_alloc(9)
624281462fScherry * will be available at the boot stage when this is called.
634281462fScherry */
644281462fScherry static char xen_idt_page[PAGE_SIZE] __attribute__((__aligned__ (PAGE_SIZE)));
65c24c993fSbouyer #if defined(__x86_64__)
66c24c993fSbouyer kpreempt_disable();
67c24c993fSbouyer #endif
680e975399Scherry memset(xen_idt_page, 0, PAGE_SIZE);
694281462fScherry
704281462fScherry struct trap_info *xen_idt = (void * )xen_idt_page;
714281462fScherry int xen_idt_idx = 0;
724281462fScherry
734281462fScherry struct trap_info * idd = (void *) rd->rd_base;
744281462fScherry const int nidt = rd->rd_limit / (sizeof *idd);
754281462fScherry
764281462fScherry int i;
774281462fScherry
784281462fScherry /*
794281462fScherry * Sweep in all initialised entries, consolidate them back to
804281462fScherry * back in the requestor array.
814281462fScherry */
824281462fScherry for (i = 0; i < nidt; i++) {
830e975399Scherry if (idd[i].address == 0) /* Skip gap */
844281462fScherry continue;
850e975399Scherry KASSERT(xen_idt_idx < MAX_XEN_IDT);
864281462fScherry /* Copy over entry */
874281462fScherry xen_idt[xen_idt_idx++] = idd[i];
884281462fScherry }
894281462fScherry
9000cd7c0dScherry #if defined(__x86_64__)
914281462fScherry /* page needs to be r/o */
924281462fScherry pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ);
9300cd7c0dScherry #endif /* __x86_64 */
944281462fScherry
954281462fScherry /* Hook it up in the hypervisor */
964281462fScherry if (HYPERVISOR_set_trap_table(xen_idt))
974281462fScherry panic("HYPERVISOR_set_trap_table() failed");
984281462fScherry
9900cd7c0dScherry #if defined(__x86_64__)
1004281462fScherry /* reset */
1014281462fScherry pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ|VM_PROT_WRITE);
102c24c993fSbouyer kpreempt_enable();
10300cd7c0dScherry #endif /* __x86_64 */
1044281462fScherry }
1054281462fScherry
1064281462fScherry void
lldt(u_short sel)107afc14682Scherry lldt(u_short sel)
1084e541343Sbouyer {
109d9474223Sjym #ifndef __x86_64__
110b698c03cSad struct cpu_info *ci;
1114e541343Sbouyer
112b698c03cSad ci = curcpu();
113b698c03cSad
114b698c03cSad if (ci->ci_curldt == sel)
115b698c03cSad return;
1164e541343Sbouyer if (sel == GSEL(GLDT_SEL, SEL_KPL))
1176c9d31edSmaxv xen_set_ldt((vaddr_t)ldtstore, NLDT);
1184e541343Sbouyer else
119b698c03cSad xen_set_ldt(ci->ci_gdt[IDXSELN(sel)].ld.ld_base,
120b698c03cSad ci->ci_gdt[IDXSELN(sel)].ld.ld_entries);
121b698c03cSad ci->ci_curldt = sel;
1224e541343Sbouyer #endif
123d9474223Sjym }
1244e541343Sbouyer
1254e541343Sbouyer void
ltr(u_short sel)126afc14682Scherry ltr(u_short sel)
1274e541343Sbouyer {
12892ccc4eaScherry panic("XXX ltr not supported\n");
1294e541343Sbouyer }
1304e541343Sbouyer
1314e541343Sbouyer void
lcr0(register_t val)1321554c1fbSmaxv lcr0(register_t val)
1334e541343Sbouyer {
13492ccc4eaScherry panic("XXX lcr0 not supported\n");
1354e541343Sbouyer }
1364e541343Sbouyer
1371554c1fbSmaxv register_t
rcr0(void)138afc14682Scherry rcr0(void)
1394e541343Sbouyer {
14092ccc4eaScherry /* XXX: handle X86_CR0_TS ? */
1414e541343Sbouyer return 0;
1424e541343Sbouyer }
1434e541343Sbouyer
1444e541343Sbouyer #ifndef __x86_64__
1454e541343Sbouyer void
lcr3(register_t val)14630031e47Skre lcr3(register_t val)
1474e541343Sbouyer {
1480eef747dSbouyer int s = splvm();
1494e541343Sbouyer xpq_queue_pt_switch(xpmap_ptom_masked(val));
1504e541343Sbouyer splx(s);
1514e541343Sbouyer }
1524e541343Sbouyer #endif
1534e541343Sbouyer
1544e541343Sbouyer void
tlbflush(void)155afc14682Scherry tlbflush(void)
1564e541343Sbouyer {
1570eef747dSbouyer int s = splvm();
1584e541343Sbouyer xpq_queue_tlb_flush();
1594e541343Sbouyer splx(s);
1604e541343Sbouyer }
1614e541343Sbouyer
1624e541343Sbouyer void
tlbflushg(void)163afc14682Scherry tlbflushg(void)
1644e541343Sbouyer {
1654e541343Sbouyer tlbflush();
1664e541343Sbouyer }
1674e541343Sbouyer
1689b94e002Skamil register_t
rdr0(void)169afc14682Scherry rdr0(void)
170266caf90Skamil {
171266caf90Skamil
172266caf90Skamil return HYPERVISOR_get_debugreg(0);
173266caf90Skamil }
174266caf90Skamil
175266caf90Skamil void
ldr0(register_t val)176afc14682Scherry ldr0(register_t val)
177266caf90Skamil {
178266caf90Skamil
179266caf90Skamil HYPERVISOR_set_debugreg(0, val);
180266caf90Skamil }
181266caf90Skamil
1829b94e002Skamil register_t
rdr1(void)183afc14682Scherry rdr1(void)
184266caf90Skamil {
185266caf90Skamil
186266caf90Skamil return HYPERVISOR_get_debugreg(1);
187266caf90Skamil }
188266caf90Skamil
189266caf90Skamil void
ldr1(register_t val)190afc14682Scherry ldr1(register_t val)
191266caf90Skamil {
192266caf90Skamil
193266caf90Skamil HYPERVISOR_set_debugreg(1, val);
194266caf90Skamil }
195266caf90Skamil
1969b94e002Skamil register_t
rdr2(void)197afc14682Scherry rdr2(void)
198266caf90Skamil {
199266caf90Skamil
200266caf90Skamil return HYPERVISOR_get_debugreg(2);
201266caf90Skamil }
202266caf90Skamil
203266caf90Skamil void
ldr2(register_t val)204afc14682Scherry ldr2(register_t val)
205266caf90Skamil {
206266caf90Skamil
207266caf90Skamil HYPERVISOR_set_debugreg(2, val);
208266caf90Skamil }
209266caf90Skamil
2109b94e002Skamil register_t
rdr3(void)211afc14682Scherry rdr3(void)
212266caf90Skamil {
213266caf90Skamil
214266caf90Skamil return HYPERVISOR_get_debugreg(3);
215266caf90Skamil }
216266caf90Skamil
217266caf90Skamil void
ldr3(register_t val)218afc14682Scherry ldr3(register_t val)
219266caf90Skamil {
220266caf90Skamil
221266caf90Skamil HYPERVISOR_set_debugreg(3, val);
222266caf90Skamil }
2239b94e002Skamil register_t
rdr6(void)224afc14682Scherry rdr6(void)
2254e541343Sbouyer {
2264e541343Sbouyer
227266caf90Skamil return HYPERVISOR_get_debugreg(6);
2284e541343Sbouyer }
2294e541343Sbouyer
2304e541343Sbouyer void
ldr6(register_t val)231afc14682Scherry ldr6(register_t val)
2324e541343Sbouyer {
2334e541343Sbouyer
2344e541343Sbouyer HYPERVISOR_set_debugreg(6, val);
2354e541343Sbouyer }
2364e541343Sbouyer
2379b94e002Skamil register_t
rdr7(void)238afc14682Scherry rdr7(void)
239266caf90Skamil {
240266caf90Skamil
241266caf90Skamil return HYPERVISOR_get_debugreg(7);
242266caf90Skamil }
243266caf90Skamil
244266caf90Skamil void
ldr7(register_t val)245afc14682Scherry ldr7(register_t val)
246266caf90Skamil {
247266caf90Skamil
248266caf90Skamil HYPERVISOR_set_debugreg(7, val);
249266caf90Skamil }
250266caf90Skamil
2514e541343Sbouyer void
wbinvd(void)252afc14682Scherry wbinvd(void)
2534e541343Sbouyer {
2544e541343Sbouyer
2554e541343Sbouyer xpq_flush_cache();
2564e541343Sbouyer }
2574e541343Sbouyer
2581554c1fbSmaxv register_t
rcr2(void)259afc14682Scherry rcr2(void)
2604e541343Sbouyer {
26120161b72Scegger return curcpu()->ci_vcpu->arch.cr2;
2624e541343Sbouyer }
263395f5383Smaxv
264c24c993fSbouyer void
lcr2(register_t v)265c24c993fSbouyer lcr2(register_t v)
266c24c993fSbouyer {
267c24c993fSbouyer curcpu()->ci_vcpu->arch.cr2 = v;
268c24c993fSbouyer }
269c24c993fSbouyer
270395f5383Smaxv #ifdef __x86_64__
271395f5383Smaxv void
setusergs(int gssel)272afc14682Scherry setusergs(int gssel)
273395f5383Smaxv {
274395f5383Smaxv HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, gssel);
275395f5383Smaxv }
276395f5383Smaxv #endif
277