Thu Apr 16 17:47:37 2020 UTC ()
fail silently if hypervisor is not found.


(bouyer)
diff -r1.73.2.2 -r1.73.2.3 src/sys/arch/xen/xen/hypervisor.c

cvs diff -r1.73.2.2 -r1.73.2.3 src/sys/arch/xen/xen/hypervisor.c (switch to unified diff)

--- src/sys/arch/xen/xen/hypervisor.c 2020/04/11 21:21:16 1.73.2.2
+++ src/sys/arch/xen/xen/hypervisor.c 2020/04/16 17:47:37 1.73.2.3
@@ -1,694 +1,692 @@ @@ -1,694 +1,692 @@
1/* $NetBSD: hypervisor.c,v 1.73.2.2 2020/04/11 21:21:16 bouyer Exp $ */ 1/* $NetBSD: hypervisor.c,v 1.73.2.3 2020/04/16 17:47:37 bouyer Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Manuel Bouyer. 4 * Copyright (c) 2005 Manuel Bouyer.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 * 25 *
26 */ 26 */
27 27
28/* 28/*
29 * 29 *
30 * Copyright (c) 2004 Christian Limpach. 30 * Copyright (c) 2004 Christian Limpach.
31 * All rights reserved. 31 * All rights reserved.
32 * 32 *
33 * Redistribution and use in source and binary forms, with or without 33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions 34 * modification, are permitted provided that the following conditions
35 * are met: 35 * are met:
36 * 1. Redistributions of source code must retain the above copyright 36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer. 37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright 38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the 39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution. 40 * documentation and/or other materials provided with the distribution.
41 * 41 *
42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 44 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 45 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 50 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 */ 52 */
53 53
54 54
55#include <sys/cdefs.h> 55#include <sys/cdefs.h>
56__KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.73.2.2 2020/04/11 21:21:16 bouyer Exp $"); 56__KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.73.2.3 2020/04/16 17:47:37 bouyer Exp $");
57 57
58#include <sys/param.h> 58#include <sys/param.h>
59#include <sys/systm.h> 59#include <sys/systm.h>
60#include <sys/device.h> 60#include <sys/device.h>
61#include <sys/sysctl.h> 61#include <sys/sysctl.h>
62 62
63#include "xenbus.h" 63#include "xenbus.h"
64#include "xencons.h" 64#include "xencons.h"
65#include "isa.h" 65#include "isa.h"
66#include "pci.h" 66#include "pci.h"
67#include "acpica.h" 67#include "acpica.h"
68 68
69#include "opt_xen.h" 69#include "opt_xen.h"
70#include "opt_mpbios.h" 70#include "opt_mpbios.h"
71 71
72#include <xen/xen.h> 72#include <xen/xen.h>
73#include <xen/hypervisor.h> 73#include <xen/hypervisor.h>
74#include <xen/evtchn.h> 74#include <xen/evtchn.h>
75#include <xen/include/public/version.h> 75#include <xen/include/public/version.h>
76#include <x86//pio.h> 76#include <x86//pio.h>
77 77
78#include <sys/cpu.h> 78#include <sys/cpu.h>
79#include <sys/dirent.h> 79#include <sys/dirent.h>
80#include <sys/stat.h> 80#include <sys/stat.h>
81#include <sys/tree.h> 81#include <sys/tree.h>
82#include <sys/vnode.h> 82#include <sys/vnode.h>
83#include <miscfs/specfs/specdev.h> 83#include <miscfs/specfs/specdev.h>
84#include <miscfs/kernfs/kernfs.h> 84#include <miscfs/kernfs/kernfs.h>
85#include <xen/kernfs_machdep.h> 85#include <xen/kernfs_machdep.h>
86#include <dev/isa/isavar.h> 86#include <dev/isa/isavar.h>
87#include <xen/granttables.h> 87#include <xen/granttables.h>
88#include <xen/vcpuvar.h> 88#include <xen/vcpuvar.h>
89#if NPCI > 0 89#if NPCI > 0
90#include <dev/pci/pcivar.h> 90#include <dev/pci/pcivar.h>
91#if NACPICA > 0 91#if NACPICA > 0
92#include <dev/acpi/acpivar.h> 92#include <dev/acpi/acpivar.h>
93#include <machine/mpconfig.h> 93#include <machine/mpconfig.h>
94#include <xen/mpacpi.h> 94#include <xen/mpacpi.h>
95#endif 95#endif
96#ifdef MPBIOS 96#ifdef MPBIOS
97#include <machine/mpbiosvar.h> 97#include <machine/mpbiosvar.h>
98#endif 98#endif
99#endif /* NPCI */ 99#endif /* NPCI */
100 100
101#if NXENBUS > 0 101#if NXENBUS > 0
102#include <xen/xenbus.h> 102#include <xen/xenbus.h>
103#endif 103#endif
104 104
105#if NXENNET_HYPERVISOR > 0 105#if NXENNET_HYPERVISOR > 0
106#include <net/if.h> 106#include <net/if.h>
107#include <net/if_ether.h> 107#include <net/if_ether.h>
108#include <net/if_media.h> 108#include <net/if_media.h>
109#include <xen/if_xennetvar.h> 109#include <xen/if_xennetvar.h>
110#endif 110#endif
111 111
112#if NXBD_HYPERVISOR > 0 112#if NXBD_HYPERVISOR > 0
113#include <sys/buf.h> 113#include <sys/buf.h>
114#include <sys/disk.h> 114#include <sys/disk.h>
115#include <sys/bufq.h> 115#include <sys/bufq.h>
116#include <dev/dkvar.h> 116#include <dev/dkvar.h>
117#include <xen/xbdvar.h> 117#include <xen/xbdvar.h>
118#endif 118#endif
119 119
120int hypervisor_match(device_t, cfdata_t, void *); 120int hypervisor_match(device_t, cfdata_t, void *);
121void hypervisor_attach(device_t, device_t, void *); 121void hypervisor_attach(device_t, device_t, void *);
122 122
123CFATTACH_DECL_NEW(hypervisor, 0, 123CFATTACH_DECL_NEW(hypervisor, 0,
124 hypervisor_match, hypervisor_attach, NULL, NULL); 124 hypervisor_match, hypervisor_attach, NULL, NULL);
125 125
126static int hypervisor_print(void *, const char *); 126static int hypervisor_print(void *, const char *);
127 127
128union hypervisor_attach_cookie { 128union hypervisor_attach_cookie {
129 const char *hac_device; /* first elem of all */ 129 const char *hac_device; /* first elem of all */
130#if NXENCONS > 0 130#if NXENCONS > 0
131 struct xencons_attach_args hac_xencons; 131 struct xencons_attach_args hac_xencons;
132#endif 132#endif
133#if NXENBUS > 0 133#if NXENBUS > 0
134 struct xenbus_attach_args hac_xenbus; 134 struct xenbus_attach_args hac_xenbus;
135#endif 135#endif
136#if NXENNET_HYPERVISOR > 0 136#if NXENNET_HYPERVISOR > 0
137 struct xennet_attach_args hac_xennet; 137 struct xennet_attach_args hac_xennet;
138#endif 138#endif
139#if NXBD_HYPERVISOR > 0 139#if NXBD_HYPERVISOR > 0
140 struct xbd_attach_args hac_xbd; 140 struct xbd_attach_args hac_xbd;
141#endif 141#endif
142#if NPCI > 0 142#if NPCI > 0
143 struct pcibus_attach_args hac_pba; 143 struct pcibus_attach_args hac_pba;
144#if defined(DOM0OPS) && NISA > 0 144#if defined(DOM0OPS) && NISA > 0
145 struct isabus_attach_args hac_iba; 145 struct isabus_attach_args hac_iba;
146#endif 146#endif
147#if NACPICA > 0 147#if NACPICA > 0
148 struct acpibus_attach_args hac_acpi; 148 struct acpibus_attach_args hac_acpi;
149#endif 149#endif
150#endif /* NPCI */ 150#endif /* NPCI */
151 struct vcpu_attach_args hac_vcaa; 151 struct vcpu_attach_args hac_vcaa;
152}; 152};
153 153
154/* 154/*
155 * This is set when the ISA bus is attached. If it's not set by the 155 * This is set when the ISA bus is attached. If it's not set by the
156 * time it's checked below, then mainbus attempts to attach an ISA. 156 * time it's checked below, then mainbus attempts to attach an ISA.
157 */ 157 */
158#ifdef DOM0OPS 158#ifdef DOM0OPS
159int isa_has_been_seen; 159int isa_has_been_seen;
160#if NISA > 0 160#if NISA > 0
161struct x86_isa_chipset x86_isa_chipset; 161struct x86_isa_chipset x86_isa_chipset;
162#endif 162#endif
163#endif 163#endif
164 164
165#if defined(XENPVHVM) 165#if defined(XENPVHVM)
166#include <xen/include/public/arch-x86/cpuid.h> 166#include <xen/include/public/arch-x86/cpuid.h>
167#include <xen/include/public/hvm/hvm_op.h> 167#include <xen/include/public/hvm/hvm_op.h>
168#include <xen/include/public/hvm/params.h> 168#include <xen/include/public/hvm/params.h>
169#include <xen/include/public/vcpu.h> 169#include <xen/include/public/vcpu.h>
170 170
171#include <x86/bootinfo.h> 171#include <x86/bootinfo.h>
172 172
173#define IDTVEC(name) __CONCAT(X, name) 173#define IDTVEC(name) __CONCAT(X, name)
174typedef void (vector)(void); 174typedef void (vector)(void);
175extern vector IDTVEC(syscall); 175extern vector IDTVEC(syscall);
176extern vector IDTVEC(syscall32); 176extern vector IDTVEC(syscall32);
177extern vector IDTVEC(osyscall); 177extern vector IDTVEC(osyscall);
178extern vector *x86_exceptions[]; 178extern vector *x86_exceptions[];
179 179
180extern vector IDTVEC(hypervisor_pvhvm_callback); 180extern vector IDTVEC(hypervisor_pvhvm_callback);
181extern volatile struct xencons_interface *xencons_interface; /* XXX */ 181extern volatile struct xencons_interface *xencons_interface; /* XXX */
182extern struct xenstore_domain_interface *xenstore_interface; /* XXX */ 182extern struct xenstore_domain_interface *xenstore_interface; /* XXX */
183 183
184volatile shared_info_t *HYPERVISOR_shared_info __read_mostly; 184volatile shared_info_t *HYPERVISOR_shared_info __read_mostly;
185paddr_t HYPERVISOR_shared_info_pa; 185paddr_t HYPERVISOR_shared_info_pa;
186union start_info_union start_info_union __aligned(PAGE_SIZE); 186union start_info_union start_info_union __aligned(PAGE_SIZE);
187#endif 187#endif
188 188
189int xen_version; 189int xen_version;
190 190
191/* power management, for save/restore */ 191/* power management, for save/restore */
192static bool hypervisor_suspend(device_t, const pmf_qual_t *); 192static bool hypervisor_suspend(device_t, const pmf_qual_t *);
193static bool hypervisor_resume(device_t, const pmf_qual_t *); 193static bool hypervisor_resume(device_t, const pmf_qual_t *);
194 194
195/* from FreeBSD */ 195/* from FreeBSD */
196#define XEN_MAGIC_IOPORT 0x10 196#define XEN_MAGIC_IOPORT 0x10
197enum { 197enum {
198 XMI_MAGIC = 0x49d2, 198 XMI_MAGIC = 0x49d2,
199 XMI_UNPLUG_IDE_DISKS = 0x01, 199 XMI_UNPLUG_IDE_DISKS = 0x01,
200 XMI_UNPLUG_NICS = 0x02, 200 XMI_UNPLUG_NICS = 0x02,
201 XMI_UNPLUG_IDE_EXCEPT_PRI_MASTER = 0x04 201 XMI_UNPLUG_IDE_EXCEPT_PRI_MASTER = 0x04
202};  202};
203 203
204/* 204/*
205 * Probe for the hypervisor; always succeeds. 205 * Probe for the hypervisor; always succeeds.
206 */ 206 */
207int 207int
208hypervisor_match(device_t parent, cfdata_t match, void *aux) 208hypervisor_match(device_t parent, cfdata_t match, void *aux)
209{ 209{
210 struct hypervisor_attach_args *haa = aux; 210 struct hypervisor_attach_args *haa = aux;
211 211
212 /* Attach path sanity check */ 212 /* Attach path sanity check */
213 if (strncmp(haa->haa_busname, "hypervisor", sizeof("hypervisor")) != 0) 213 if (strncmp(haa->haa_busname, "hypervisor", sizeof("hypervisor")) != 0)
214 return 0; 214 return 0;
215 215
216#if defined(XENPVHVM) 216#if defined(XENPVHVM)
217 /* 217 /*
218 * The strategy here is to setup hypercall and all PVHVM 218 * The strategy here is to setup hypercall and all PVHVM
219 * interfaces on match, or fail to match. 219 * interfaces on match, or fail to match.
220 * Ideally this should happen under attach, but it's too late 220 * Ideally this should happen under attach, but it's too late
221 * then and there's no way to bailout. 221 * then and there's no way to bailout.
222 * 222 *
223 * If match fails, hypervisor does not attach, and the domain 223 * If match fails, hypervisor does not attach, and the domain
224 * can boot with the minimal PC AT ISA configuration just 224 * can boot with the minimal PC AT ISA configuration just
225 * enough to attach wd(4) and mount the rootfs. 225 * enough to attach wd(4) and mount the rootfs.
226 */ 226 */
227 int vec; 227 int vec;
228 extern vaddr_t hypercall_page; 228 extern vaddr_t hypercall_page;
229 229
230 if (vm_guest == VM_GUEST_XENHVM) { 230 if (vm_guest == VM_GUEST_XENHVM) {
231 aprint_normal("%s: Identified Guest XEN in HVM mode.\n", 231 aprint_normal("%s: Identified Guest XEN in HVM mode.\n",
232 haa->haa_busname); 232 haa->haa_busname);
233 233
234 u_int descs[4]; 234 u_int descs[4];
235 x86_cpuid(XEN_CPUID_LEAF(2), descs); 235 x86_cpuid(XEN_CPUID_LEAF(2), descs);
236 236
237 /*  237 /*
238 * Given 32 bytes per hypercall stub, and an optimistic number 238 * Given 32 bytes per hypercall stub, and an optimistic number
239 * of 100 hypercalls ( the current max is 55), there shouldn't 239 * of 100 hypercalls ( the current max is 55), there shouldn't
240 * be any reason to spill over the arbitrary number of 1 240 * be any reason to spill over the arbitrary number of 1
241 * hypercall page. This is what we allocate in locore.S 241 * hypercall page. This is what we allocate in locore.S
242 * anyway. Make sure the allocation matches the registration. 242 * anyway. Make sure the allocation matches the registration.
243 */ 243 */
244 244
245 KASSERT(descs[0] == 1); 245 KASSERT(descs[0] == 1);
246 246
247 /* XXX: vtophys(&hypercall_page) */ 247 /* XXX: vtophys(&hypercall_page) */
248 wrmsr(descs[1], (uintptr_t)&hypercall_page - KERNBASE); 248 wrmsr(descs[1], (uintptr_t)&hypercall_page - KERNBASE);
249 249
250 vm_guest = VM_GUEST_XENPVHVM; /* Be more specific */ 250 vm_guest = VM_GUEST_XENPVHVM; /* Be more specific */
251 251
252 } else { 252 } else {
253 aprint_normal("%s: Xen HVM mode not identified. Exiting.\n", 
254 haa->haa_busname); 
255 return 0; 253 return 0;
256 } 254 }
257 255
258 if (-1 != HYPERVISOR_xen_version(XENVER_version, NULL)) { 256 if (-1 != HYPERVISOR_xen_version(XENVER_version, NULL)) {
259 printf("%s: detected functional hypercall page.\n", 257 printf("%s: detected functional hypercall page.\n",
260 haa->haa_busname); 258 haa->haa_busname);
261 259
262 xen_init_features(); 260 xen_init_features();
263 } 261 }
264 262
265 /* Init various preset boot time data structures */ 263 /* Init various preset boot time data structures */
266 264
267 /* XEN xenstore shared page address, event channel */ 265 /* XEN xenstore shared page address, event channel */
268 struct xen_hvm_param xen_hvm_param; 266 struct xen_hvm_param xen_hvm_param;
269 267
270 xen_hvm_param.domid = DOMID_SELF; 268 xen_hvm_param.domid = DOMID_SELF;
271 xen_hvm_param.index = HVM_PARAM_STORE_PFN; 269 xen_hvm_param.index = HVM_PARAM_STORE_PFN;
272  270
273 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) { 271 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
274 aprint_error("%s: Unable to obtain xenstore page address\n", 272 aprint_error("%s: Unable to obtain xenstore page address\n",
275 haa->haa_busname); 273 haa->haa_busname);
276 return 0; 274 return 0;
277 } 275 }
278 276
279 /* Re-use PV field */ 277 /* Re-use PV field */
280 xen_start_info.store_mfn = xen_hvm_param.value; 278 xen_start_info.store_mfn = xen_hvm_param.value;
281 279
282 pmap_kenter_pa((vaddr_t) xenstore_interface, ptoa(xen_start_info.store_mfn), 280 pmap_kenter_pa((vaddr_t) xenstore_interface, ptoa(xen_start_info.store_mfn),
283 VM_PROT_READ|VM_PROT_WRITE, 0); 281 VM_PROT_READ|VM_PROT_WRITE, 0);
284 282
285 xen_hvm_param.domid = DOMID_SELF; 283 xen_hvm_param.domid = DOMID_SELF;
286 xen_hvm_param.index = HVM_PARAM_STORE_EVTCHN; 284 xen_hvm_param.index = HVM_PARAM_STORE_EVTCHN;
287 285
288 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) { 286 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
289 aprint_error("%s: Unable to obtain xenstore event channel\n", 287 aprint_error("%s: Unable to obtain xenstore event channel\n",
290 haa->haa_busname); 288 haa->haa_busname);
291 return 0; 289 return 0;
292 } 290 }
293 291
294 xen_start_info.store_evtchn = xen_hvm_param.value; 292 xen_start_info.store_evtchn = xen_hvm_param.value;
295 293
296 xen_hvm_param.domid = DOMID_SELF; 294 xen_hvm_param.domid = DOMID_SELF;
297 xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN; 295 xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN;
298  296
299 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) { 297 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
300 aprint_error("%s: Unable to obtain xencons page address\n", 298 aprint_error("%s: Unable to obtain xencons page address\n",
301 haa->haa_busname); 299 haa->haa_busname);
302 return 0; 300 return 0;
303 } 301 }
304 302
305 /* Re-use PV field */ 303 /* Re-use PV field */
306 xen_start_info.console.domU.mfn = xen_hvm_param.value; 304 xen_start_info.console.domU.mfn = xen_hvm_param.value;
307 305
308 pmap_kenter_pa((vaddr_t) xencons_interface, ptoa(xen_start_info.console.domU.mfn), 306 pmap_kenter_pa((vaddr_t) xencons_interface, ptoa(xen_start_info.console.domU.mfn),
309 VM_PROT_READ|VM_PROT_WRITE, 0); 307 VM_PROT_READ|VM_PROT_WRITE, 0);
310 308
311 xen_hvm_param.domid = DOMID_SELF; 309 xen_hvm_param.domid = DOMID_SELF;
312 xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN; 310 xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN;
313 311
314 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) { 312 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
315 aprint_error("%s: Unable to obtain xencons event channel\n", 313 aprint_error("%s: Unable to obtain xencons event channel\n",
316 haa->haa_busname); 314 haa->haa_busname);
317 return 0; 315 return 0;
318 } 316 }
319 317
320 xen_start_info.console.domU.evtchn = xen_hvm_param.value; 318 xen_start_info.console.domU.evtchn = xen_hvm_param.value;
321 319
322 /* HYPERVISOR_shared_info */ 320 /* HYPERVISOR_shared_info */
323 struct xen_add_to_physmap xmap = { 321 struct xen_add_to_physmap xmap = {
324 .domid = DOMID_SELF, 322 .domid = DOMID_SELF,
325 .space = XENMAPSPACE_shared_info, 323 .space = XENMAPSPACE_shared_info,
326 .idx = 0, /* Important - XEN checks for this */ 324 .idx = 0, /* Important - XEN checks for this */
327 .gpfn = atop(HYPERVISOR_shared_info_pa) 325 .gpfn = atop(HYPERVISOR_shared_info_pa)
328 }; 326 };
329 327
330 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xmap) < 0) { 328 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xmap) < 0) {
331 aprint_error("%s: Unable to register HYPERVISOR_shared_info\n", 329 aprint_error("%s: Unable to register HYPERVISOR_shared_info\n",
332 haa->haa_busname); 330 haa->haa_busname);
333 return 0; 331 return 0;
334 } 332 }
335 333
336 /* HYPERVISOR_shared_info va,pa has been allocated in pmap_bootstrap() */ 334 /* HYPERVISOR_shared_info va,pa has been allocated in pmap_bootstrap() */
337 pmap_kenter_pa((vaddr_t) HYPERVISOR_shared_info, 335 pmap_kenter_pa((vaddr_t) HYPERVISOR_shared_info,
338 HYPERVISOR_shared_info_pa, VM_PROT_READ|VM_PROT_WRITE, 0); 336 HYPERVISOR_shared_info_pa, VM_PROT_READ|VM_PROT_WRITE, 0);
339 337
340 cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0]; 338 cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0];
341 339
342 /* 340 /*
343 * First register callback: here's why 341 * First register callback: here's why
344 * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867 342 * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867
345 */ 343 */
346 344
347 /* 345 /*
348 * Check for XENFEAT_hvm_callback_vector. Can't proceed 346 * Check for XENFEAT_hvm_callback_vector. Can't proceed
349 * without it. 347 * without it.
350 */ 348 */
351 if (!xen_feature(XENFEAT_hvm_callback_vector)) { 349 if (!xen_feature(XENFEAT_hvm_callback_vector)) {
352 aprint_error("%s: XENFEAT_hvm_callback_vector" 350 aprint_error("%s: XENFEAT_hvm_callback_vector"
353 "not available, cannot proceed", haa->haa_busname); 351 "not available, cannot proceed", haa->haa_busname);
354  352
355 return 0; 353 return 0;
356 } 354 }
357 355
358 /* Register event callback handler. */ 356 /* Register event callback handler. */
359 357
360 /* We don't really care where it is, as long as it's free */ 358 /* We don't really care where it is, as long as it's free */
361 vec = idt_vec_alloc(129, 255); 359 vec = idt_vec_alloc(129, 255);
362 360
363 idt_vec_set(vec, &IDTVEC(hypervisor_pvhvm_callback)); 361 idt_vec_set(vec, &IDTVEC(hypervisor_pvhvm_callback));
364 362
365 cpu_init_idt(); /* XXX remove and use only native one below ? */ 363 cpu_init_idt(); /* XXX remove and use only native one below ? */
366 364
367 xen_hvm_param.domid = DOMID_SELF; 365 xen_hvm_param.domid = DOMID_SELF;
368 xen_hvm_param.index = HVM_PARAM_CALLBACK_IRQ; 366 xen_hvm_param.index = HVM_PARAM_CALLBACK_IRQ;
369 367
370 /* val[63:56] = 2, val[7:0] = vec */ 368 /* val[63:56] = 2, val[7:0] = vec */
371 xen_hvm_param.value = ((int64_t)0x2 << 56) | vec; 369 xen_hvm_param.value = ((int64_t)0x2 << 56) | vec;
372 370
373 if (HYPERVISOR_hvm_op(HVMOP_set_param, &xen_hvm_param) < 0) { 371 if (HYPERVISOR_hvm_op(HVMOP_set_param, &xen_hvm_param) < 0) {
374 aprint_error("%s: Unable to register event callback vector\n", 372 aprint_error("%s: Unable to register event callback vector\n",
375 haa->haa_busname); 373 haa->haa_busname);
376 return 0; 374 return 0;
377 } 375 }
378 376
379 /* Print out value. */ 377 /* Print out value. */
380 xen_hvm_param.domid = DOMID_SELF; 378 xen_hvm_param.domid = DOMID_SELF;
381 xen_hvm_param.index = HVM_PARAM_CALLBACK_IRQ; 379 xen_hvm_param.index = HVM_PARAM_CALLBACK_IRQ;
382 xen_hvm_param.value = 0; 380 xen_hvm_param.value = 0;
383 381
384 if (HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) { 382 if (HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
385 printf("%s: Unable to get event callback vector\n", 383 printf("%s: Unable to get event callback vector\n",
386 haa->haa_busname); 384 haa->haa_busname);
387 return 0; 385 return 0;
388 } 386 }
389 387
390 /* 388 /*
391 * Afterwards vector callback is done, register VCPU info 389 * Afterwards vector callback is done, register VCPU info
392 * page. Here's why: 390 * page. Here's why:
393 * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867 391 * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867
394 * XXX: Ideally this should happen at vcpu attach. 392 * XXX: Ideally this should happen at vcpu attach.
395 */ 393 */
396 struct vcpu_register_vcpu_info vrvi; 394 struct vcpu_register_vcpu_info vrvi;
397 395
398 paddr_t vcpu_info_pa = HYPERVISOR_shared_info_pa + 396 paddr_t vcpu_info_pa = HYPERVISOR_shared_info_pa +
399 offsetof(struct shared_info, vcpu_info); 397 offsetof(struct shared_info, vcpu_info);
400  398
401 vrvi.mfn = atop(vcpu_info_pa); 399 vrvi.mfn = atop(vcpu_info_pa);
402 vrvi.offset = vcpu_info_pa - trunc_page(vcpu_info_pa); 400 vrvi.offset = vcpu_info_pa - trunc_page(vcpu_info_pa);
403 401
404 if (HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, curcpu()->ci_cpuid /* VCPU0 */, 402 if (HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, curcpu()->ci_cpuid /* VCPU0 */,
405 &vrvi) < 0) { 403 &vrvi) < 0) {
406 aprint_error("%s: Unable to register vcpu info page\n", 404 aprint_error("%s: Unable to register vcpu info page\n",
407 haa->haa_busname); 405 haa->haa_busname);
408 return 0; 406 return 0;
409 } 407 }
410 408
411 /* 409 /*
412 * Set the boot device to xbd0a. 410 * Set the boot device to xbd0a.
413 * We claim this is a reasonable default which is picked up 411 * We claim this is a reasonable default which is picked up
414 * later as the rootfs device. 412 * later as the rootfs device.
415 * 413 *
416 * We need to do this because the HVM domain loader uses the 414 * We need to do this because the HVM domain loader uses the
417 * regular BIOS based native boot(8) procedure, which sets the 415 * regular BIOS based native boot(8) procedure, which sets the
418 * boot device to the native driver/partition of whatever was 416 * boot device to the native driver/partition of whatever was
419 * detected by the native bootloader. 417 * detected by the native bootloader.
420 */ 418 */
421 419
422 struct btinfo_rootdevice bi; 420 struct btinfo_rootdevice bi;
423 snprintf(bi.devname, 6, "xbd0a"); 421 snprintf(bi.devname, 6, "xbd0a");
424 bi.common.type = BTINFO_ROOTDEVICE; 422 bi.common.type = BTINFO_ROOTDEVICE;
425 bi.common.len = sizeof(struct btinfo_rootdevice); 423 bi.common.len = sizeof(struct btinfo_rootdevice);
426 424
427 /* From i386/multiboot.c */ 425 /* From i386/multiboot.c */
428 /* $NetBSD: hypervisor.c,v 1.73.2.2 2020/04/11 21:21:16 bouyer Exp $ */ 426 /* $NetBSD: hypervisor.c,v 1.73.2.3 2020/04/16 17:47:37 bouyer Exp $ */
429 int i, len; 427 int i, len;
430 vaddr_t data; 428 vaddr_t data;
431 extern struct bootinfo bootinfo; 429 extern struct bootinfo bootinfo;
432 struct bootinfo *bip = (struct bootinfo *)&bootinfo; 430 struct bootinfo *bip = (struct bootinfo *)&bootinfo;
433 len = bi.common.len; 431 len = bi.common.len;
434 432
435 data = (vaddr_t)&bip->bi_data; 433 data = (vaddr_t)&bip->bi_data;
436 for (i = 0; i < bip->bi_nentries; i++) { 434 for (i = 0; i < bip->bi_nentries; i++) {
437 struct btinfo_common *tmp; 435 struct btinfo_common *tmp;
438 436
439 tmp = (struct btinfo_common *)data; 437 tmp = (struct btinfo_common *)data;
440 data += tmp->len; 438 data += tmp->len;
441 } 439 }
442 if (data + len < (vaddr_t)&bip->bi_data + sizeof(bip->bi_data)) { 440 if (data + len < (vaddr_t)&bip->bi_data + sizeof(bip->bi_data)) {
443 memcpy((void *)data, &bi, len); 441 memcpy((void *)data, &bi, len);
444 bip->bi_nentries++; 442 bip->bi_nentries++;
445 } 443 }
446 444
447 /* disable emulated devices */ 445 /* disable emulated devices */
448 if (inw(XEN_MAGIC_IOPORT) == XMI_MAGIC) { 446 if (inw(XEN_MAGIC_IOPORT) == XMI_MAGIC) {
449 outw(XEN_MAGIC_IOPORT, XMI_UNPLUG_IDE_DISKS | XMI_UNPLUG_NICS); 447 outw(XEN_MAGIC_IOPORT, XMI_UNPLUG_IDE_DISKS | XMI_UNPLUG_NICS);
450 } else { 448 } else {
451 aprint_error("%s: Unable to disable emulated devices\n", 449 aprint_error("%s: Unable to disable emulated devices\n",
452 haa->haa_busname); 450 haa->haa_busname);
453 } 451 }
454#endif /* XENPVHVM */ 452#endif /* XENPVHVM */
455 453
456 /* If we got here, it must mean we matched */ 454 /* If we got here, it must mean we matched */
457 return 1; 455 return 1;
458} 456}
459 457
460#ifdef MULTIPROCESSOR 458#ifdef MULTIPROCESSOR
461static int 459static int
462hypervisor_vcpu_print(void *aux, const char *parent) 460hypervisor_vcpu_print(void *aux, const char *parent)
463{ 461{
464 /* Unconfigured cpus are ignored quietly. */ 462 /* Unconfigured cpus are ignored quietly. */
465 return (QUIET); 463 return (QUIET);
466} 464}
467#endif /* MULTIPROCESSOR */ 465#endif /* MULTIPROCESSOR */
468 466
469/* 467/*
470 * Attach the hypervisor. 468 * Attach the hypervisor.
471 */ 469 */
472void 470void
473hypervisor_attach(device_t parent, device_t self, void *aux) 471hypervisor_attach(device_t parent, device_t self, void *aux)
474{ 472{
475 473
476#if NPCI >0 474#if NPCI >0
477#ifdef PCI_BUS_FIXUP 475#ifdef PCI_BUS_FIXUP
478 int pci_maxbus = 0; 476 int pci_maxbus = 0;
479#endif 477#endif
480#endif /* NPCI */ 478#endif /* NPCI */
481 union hypervisor_attach_cookie hac; 479 union hypervisor_attach_cookie hac;
482 char xen_extra_version[XEN_EXTRAVERSION_LEN]; 480 char xen_extra_version[XEN_EXTRAVERSION_LEN];
483 static char xen_version_string[20]; 481 static char xen_version_string[20];
484 int rc; 482 int rc;
485 const struct sysctlnode *node = NULL; 483 const struct sysctlnode *node = NULL;
486 484
487 xenkernfs_init(); 485 xenkernfs_init();
488 486
489 xen_version = HYPERVISOR_xen_version(XENVER_version, NULL); 487 xen_version = HYPERVISOR_xen_version(XENVER_version, NULL);
490 memset(xen_extra_version, 0, sizeof(xen_extra_version)); 488 memset(xen_extra_version, 0, sizeof(xen_extra_version));
491 HYPERVISOR_xen_version(XENVER_extraversion, xen_extra_version); 489 HYPERVISOR_xen_version(XENVER_extraversion, xen_extra_version);
492 rc = snprintf(xen_version_string, 20, "%d.%d%s", XEN_MAJOR(xen_version), 490 rc = snprintf(xen_version_string, 20, "%d.%d%s", XEN_MAJOR(xen_version),
493 XEN_MINOR(xen_version), xen_extra_version); 491 XEN_MINOR(xen_version), xen_extra_version);
494 aprint_normal(": Xen version %s\n", xen_version_string); 492 aprint_normal(": Xen version %s\n", xen_version_string);
495 if (rc >= 20) 493 if (rc >= 20)
496 aprint_debug(": xen_version_string truncated\n"); 494 aprint_debug(": xen_version_string truncated\n");
497 495
498 sysctl_createv(NULL, 0, NULL, &node, 0, 496 sysctl_createv(NULL, 0, NULL, &node, 0,
499 CTLTYPE_NODE, "xen", 497 CTLTYPE_NODE, "xen",
500 SYSCTL_DESCR("Xen top level node"), 498 SYSCTL_DESCR("Xen top level node"),
501 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); 499 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
502 500
503 if (node != NULL) { 501 if (node != NULL) {
504 sysctl_createv(NULL, 0, &node, NULL, CTLFLAG_READONLY, 502 sysctl_createv(NULL, 0, &node, NULL, CTLFLAG_READONLY,
505 CTLTYPE_STRING, "version", 503 CTLTYPE_STRING, "version",
506 SYSCTL_DESCR("Xen hypervisor version"), 504 SYSCTL_DESCR("Xen hypervisor version"),
507 NULL, 0, xen_version_string, 0, CTL_CREATE, CTL_EOL); 505 NULL, 0, xen_version_string, 0, CTL_CREATE, CTL_EOL);
508 } 506 }
509 507
510 aprint_verbose_dev(self, "features: "); 508 aprint_verbose_dev(self, "features: ");
511#define XEN_TST_F(n) \ 509#define XEN_TST_F(n) \
512 if (xen_feature(XENFEAT_##n)) \ 510 if (xen_feature(XENFEAT_##n)) \
513 aprint_verbose(" %s", #n); 511 aprint_verbose(" %s", #n);
514 512
515 XEN_TST_F(writable_page_tables); 513 XEN_TST_F(writable_page_tables);
516 XEN_TST_F(writable_descriptor_tables); 514 XEN_TST_F(writable_descriptor_tables);
517 XEN_TST_F(auto_translated_physmap); 515 XEN_TST_F(auto_translated_physmap);
518 XEN_TST_F(supervisor_mode_kernel); 516 XEN_TST_F(supervisor_mode_kernel);
519 XEN_TST_F(pae_pgdir_above_4gb); 517 XEN_TST_F(pae_pgdir_above_4gb);
520 XEN_TST_F(mmu_pt_update_preserve_ad); 518 XEN_TST_F(mmu_pt_update_preserve_ad);
521 XEN_TST_F(highmem_assist); 519 XEN_TST_F(highmem_assist);
522 XEN_TST_F(gnttab_map_avail_bits); 520 XEN_TST_F(gnttab_map_avail_bits);
523 XEN_TST_F(hvm_callback_vector); 521 XEN_TST_F(hvm_callback_vector);
524 XEN_TST_F(hvm_safe_pvclock); 522 XEN_TST_F(hvm_safe_pvclock);
525 XEN_TST_F(hvm_pirqs); 523 XEN_TST_F(hvm_pirqs);
526#undef XEN_TST_F 524#undef XEN_TST_F
527 aprint_verbose("\n"); 525 aprint_verbose("\n");
528 526
529 xengnt_init(); 527 xengnt_init();
530 events_init(); 528 events_init();
531 529
532 memset(&hac, 0, sizeof(hac)); 530 memset(&hac, 0, sizeof(hac));
533 hac.hac_vcaa.vcaa_name = "vcpu"; 531 hac.hac_vcaa.vcaa_name = "vcpu";
534 hac.hac_vcaa.vcaa_caa.cpu_number = 0; 532 hac.hac_vcaa.vcaa_caa.cpu_number = 0;
535 hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_BP; 533 hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_BP;
536 hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */ 534 hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */
537 config_found_ia(self, "xendevbus", &hac.hac_vcaa, hypervisor_print); 535 config_found_ia(self, "xendevbus", &hac.hac_vcaa, hypervisor_print);
538 536
539#ifdef MULTIPROCESSOR 537#ifdef MULTIPROCESSOR
540 538
541 /* 539 /*
542 * The xenstore contains the configured number of vcpus. 540 * The xenstore contains the configured number of vcpus.
543 * The xenstore however, is not accessible until much later in 541 * The xenstore however, is not accessible until much later in
544 * the boot sequence. We therefore bruteforce check for 542 * the boot sequence. We therefore bruteforce check for
545 * allocated vcpus (See: cpu.c:vcpu_match()) by iterating 543 * allocated vcpus (See: cpu.c:vcpu_match()) by iterating
546 * through the maximum supported by NetBSD MP. 544 * through the maximum supported by NetBSD MP.
547 */ 545 */
548 cpuid_t vcpuid; 546 cpuid_t vcpuid;
549 547
550 for (vcpuid = 1; vcpuid < maxcpus; vcpuid++) { 548 for (vcpuid = 1; vcpuid < maxcpus; vcpuid++) {
551 memset(&hac, 0, sizeof(hac)); 549 memset(&hac, 0, sizeof(hac));
552 hac.hac_vcaa.vcaa_name = "vcpu"; 550 hac.hac_vcaa.vcaa_name = "vcpu";
553 hac.hac_vcaa.vcaa_caa.cpu_number = vcpuid; 551 hac.hac_vcaa.vcaa_caa.cpu_number = vcpuid;
554 hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_AP; 552 hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_AP;
555 hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */ 553 hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */
556 if (NULL == config_found_ia(self, "xendevbus", &hac.hac_vcaa, 554 if (NULL == config_found_ia(self, "xendevbus", &hac.hac_vcaa,
557 hypervisor_vcpu_print)) { 555 hypervisor_vcpu_print)) {
558 break; 556 break;
559 } 557 }
560 } 558 }
561 559
562#endif /* MULTIPROCESSOR */ 560#endif /* MULTIPROCESSOR */
563 561
564#if NXENBUS > 0 562#if NXENBUS > 0
565 memset(&hac, 0, sizeof(hac)); 563 memset(&hac, 0, sizeof(hac));
566 hac.hac_xenbus.xa_device = "xenbus"; 564 hac.hac_xenbus.xa_device = "xenbus";
567 config_found_ia(self, "xendevbus", &hac.hac_xenbus, hypervisor_print); 565 config_found_ia(self, "xendevbus", &hac.hac_xenbus, hypervisor_print);
568#endif 566#endif
569#if NXENCONS > 0 567#if NXENCONS > 0
570 memset(&hac, 0, sizeof(hac)); 568 memset(&hac, 0, sizeof(hac));
571 hac.hac_xencons.xa_device = "xencons"; 569 hac.hac_xencons.xa_device = "xencons";
572 config_found_ia(self, "xendevbus", &hac.hac_xencons, hypervisor_print); 570 config_found_ia(self, "xendevbus", &hac.hac_xencons, hypervisor_print);
573#endif 571#endif
574#ifdef DOM0OPS 572#ifdef DOM0OPS
575#if NPCI > 0 573#if NPCI > 0
576#if NACPICA > 0 574#if NACPICA > 0
577 if (acpi_present) { 575 if (acpi_present) {
578 memset(&hac, 0, sizeof(hac)); 576 memset(&hac, 0, sizeof(hac));
579 hac.hac_acpi.aa_iot = x86_bus_space_io; 577 hac.hac_acpi.aa_iot = x86_bus_space_io;
580 hac.hac_acpi.aa_memt = x86_bus_space_mem; 578 hac.hac_acpi.aa_memt = x86_bus_space_mem;
581 hac.hac_acpi.aa_pc = NULL; 579 hac.hac_acpi.aa_pc = NULL;
582 hac.hac_acpi.aa_pciflags = 580 hac.hac_acpi.aa_pciflags =
583 PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | 581 PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY |
584 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | 582 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY |
585 PCI_FLAGS_MWI_OKAY; 583 PCI_FLAGS_MWI_OKAY;
586 hac.hac_acpi.aa_ic = &x86_isa_chipset; 584 hac.hac_acpi.aa_ic = &x86_isa_chipset;
587 hac.hac_acpi.aa_dmat = &pci_bus_dma_tag; 585 hac.hac_acpi.aa_dmat = &pci_bus_dma_tag;
588#ifdef _LP64 586#ifdef _LP64
589 hac.hac_acpi.aa_dmat64 = &pci_bus_dma64_tag; 587 hac.hac_acpi.aa_dmat64 = &pci_bus_dma64_tag;
590#else 588#else
591 hac.hac_acpi.aa_dmat64 = NULL; 589 hac.hac_acpi.aa_dmat64 = NULL;
592#endif /* _LP64 */ 590#endif /* _LP64 */
593 config_found_ia(self, "acpibus", &hac.hac_acpi, 0); 591 config_found_ia(self, "acpibus", &hac.hac_acpi, 0);
594 } 592 }
595#endif /* NACPICA */ 593#endif /* NACPICA */
596 memset(&hac, 0, sizeof(hac)); 594 memset(&hac, 0, sizeof(hac));
597 hac.hac_pba.pba_iot = x86_bus_space_io; 595 hac.hac_pba.pba_iot = x86_bus_space_io;
598 hac.hac_pba.pba_memt = x86_bus_space_mem; 596 hac.hac_pba.pba_memt = x86_bus_space_mem;
599 hac.hac_pba.pba_dmat = &pci_bus_dma_tag; 597 hac.hac_pba.pba_dmat = &pci_bus_dma_tag;
600#ifdef _LP64 598#ifdef _LP64
601 hac.hac_pba.pba_dmat64 = &pci_bus_dma64_tag; 599 hac.hac_pba.pba_dmat64 = &pci_bus_dma64_tag;
602#else 600#else
603 hac.hac_pba.pba_dmat64 = NULL; 601 hac.hac_pba.pba_dmat64 = NULL;
604#endif /* _LP64 */ 602#endif /* _LP64 */
605 hac.hac_pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY; 603 hac.hac_pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY;
606 hac.hac_pba.pba_bridgetag = NULL; 604 hac.hac_pba.pba_bridgetag = NULL;
607 hac.hac_pba.pba_bus = 0; 605 hac.hac_pba.pba_bus = 0;
608#if NACPICA > 0 && defined(ACPI_SCANPCI) 606#if NACPICA > 0 && defined(ACPI_SCANPCI)
609 if (mpacpi_active) 607 if (mpacpi_active)
610 mp_pci_scan(self, &hac.hac_pba, pcibusprint); 608 mp_pci_scan(self, &hac.hac_pba, pcibusprint);
611 else 609 else
612#endif 610#endif
613#if defined(MPBIOS) && defined(MPBIOS_SCANPCI) 611#if defined(MPBIOS) && defined(MPBIOS_SCANPCI)
614 if (mpbios_scanned != 0) 612 if (mpbios_scanned != 0)
615 mp_pci_scan(self, &hac.hac_pba, pcibusprint); 613 mp_pci_scan(self, &hac.hac_pba, pcibusprint);
616 else 614 else
617#endif 615#endif
618 config_found_ia(self, "pcibus", &hac.hac_pba, pcibusprint); 616 config_found_ia(self, "pcibus", &hac.hac_pba, pcibusprint);
619#if NACPICA > 0 617#if NACPICA > 0
620 if (mp_verbose) 618 if (mp_verbose)
621 acpi_pci_link_state(); 619 acpi_pci_link_state();
622#endif 620#endif
623#if NISA > 0 621#if NISA > 0
624 if (isa_has_been_seen == 0) { 622 if (isa_has_been_seen == 0) {
625 memset(&hac, 0, sizeof(hac)); 623 memset(&hac, 0, sizeof(hac));
626 hac.hac_iba._iba_busname = "isa"; 624 hac.hac_iba._iba_busname = "isa";
627 hac.hac_iba.iba_iot = x86_bus_space_io; 625 hac.hac_iba.iba_iot = x86_bus_space_io;
628 hac.hac_iba.iba_memt = x86_bus_space_mem; 626 hac.hac_iba.iba_memt = x86_bus_space_mem;
629 hac.hac_iba.iba_dmat = &isa_bus_dma_tag; 627 hac.hac_iba.iba_dmat = &isa_bus_dma_tag;
630 hac.hac_iba.iba_ic = NULL; /* No isa DMA yet */ 628 hac.hac_iba.iba_ic = NULL; /* No isa DMA yet */
631 config_found_ia(self, "isabus", &hac.hac_iba, isabusprint); 629 config_found_ia(self, "isabus", &hac.hac_iba, isabusprint);
632 } 630 }
633#endif /* NISA */ 631#endif /* NISA */
634#endif /* NPCI */ 632#endif /* NPCI */
635 633
636 if (xendomain_is_privileged()) { 634 if (xendomain_is_privileged()) {
637 xenprivcmd_init(); 635 xenprivcmd_init();
638 xen_shm_init(); 636 xen_shm_init();
639 } 637 }
640#endif /* DOM0OPS */ 638#endif /* DOM0OPS */
641 639
642 hypervisor_machdep_attach(); 640 hypervisor_machdep_attach();
643 641
644 if (!pmf_device_register(self, hypervisor_suspend, hypervisor_resume)) 642 if (!pmf_device_register(self, hypervisor_suspend, hypervisor_resume))
645 aprint_error_dev(self, "couldn't establish power handler\n"); 643 aprint_error_dev(self, "couldn't establish power handler\n");
646 644
647} 645}
648 646
649static bool 647static bool
650hypervisor_suspend(device_t dev, const pmf_qual_t *qual) 648hypervisor_suspend(device_t dev, const pmf_qual_t *qual)
651{ 649{
652#ifdef XENPV 650#ifdef XENPV
653 events_suspend(); 651 events_suspend();
654 xengnt_suspend(); 652 xengnt_suspend();
655#endif 653#endif
656 return true; 654 return true;
657} 655}
658 656
659static bool 657static bool
660hypervisor_resume(device_t dev, const pmf_qual_t *qual) 658hypervisor_resume(device_t dev, const pmf_qual_t *qual)
661{ 659{
662#ifdef XENPV 660#ifdef XENPV
663 hypervisor_machdep_resume(); 661 hypervisor_machdep_resume();
664 662
665 xengnt_resume(); 663 xengnt_resume();
666 events_resume(); 664 events_resume();
667#endif 665#endif
668 return true; 666 return true;
669} 667}
670 668
671static int 669static int
672hypervisor_print(void *aux, const char *parent) 670hypervisor_print(void *aux, const char *parent)
673{ 671{
674 union hypervisor_attach_cookie *hac = aux; 672 union hypervisor_attach_cookie *hac = aux;
675 673
676 if (parent) 674 if (parent)
677 aprint_normal("%s at %s", hac->hac_device, parent); 675 aprint_normal("%s at %s", hac->hac_device, parent);
678 return (UNCONF); 676 return (UNCONF);
679} 677}
680 678
681#define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 679#define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
682 680
683kernfs_parentdir_t *kernxen_pkt; 681kernfs_parentdir_t *kernxen_pkt;
684 682
685void 683void
686xenkernfs_init(void) 684xenkernfs_init(void)
687{ 685{
688 kernfs_entry_t *dkt; 686 kernfs_entry_t *dkt;
689 687
690 KERNFS_ALLOCENTRY(dkt, KM_SLEEP); 688 KERNFS_ALLOCENTRY(dkt, KM_SLEEP);
691 KERNFS_INITENTRY(dkt, DT_DIR, "xen", NULL, KFSsubdir, VDIR, DIR_MODE); 689 KERNFS_INITENTRY(dkt, DT_DIR, "xen", NULL, KFSsubdir, VDIR, DIR_MODE);
692 kernfs_addentry(NULL, dkt); 690 kernfs_addentry(NULL, dkt);
693 kernxen_pkt = KERNFS_ENTOPARENTDIR(dkt); 691 kernxen_pkt = KERNFS_ENTOPARENTDIR(dkt);
694} 692}