Wed Apr 22 20:49:08 2020 UTC ()
Don't try to attach vcpu on !XENPV
remove debug printf and other misc cosmetic changes


(bouyer)
diff -r1.73.2.8 -r1.73.2.9 src/sys/arch/xen/xen/hypervisor.c

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

--- src/sys/arch/xen/xen/hypervisor.c 2020/04/20 11:29:01 1.73.2.8
+++ src/sys/arch/xen/xen/hypervisor.c 2020/04/22 20:49:08 1.73.2.9
@@ -1,757 +1,757 @@ @@ -1,757 +1,757 @@
1/* $NetBSD: hypervisor.c,v 1.73.2.8 2020/04/20 11:29:01 bouyer Exp $ */ 1/* $NetBSD: hypervisor.c,v 1.73.2.9 2020/04/22 20:49:08 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.8 2020/04/20 11:29:01 bouyer Exp $"); 56__KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.73.2.9 2020/04/22 20:49:08 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#include <x86/machdep.h> 77#include <x86/machdep.h>
78 78
79#include <sys/cpu.h> 79#include <sys/cpu.h>
80#include <sys/dirent.h> 80#include <sys/dirent.h>
81#include <sys/stat.h> 81#include <sys/stat.h>
82#include <sys/tree.h> 82#include <sys/tree.h>
83#include <sys/vnode.h> 83#include <sys/vnode.h>
84#include <miscfs/specfs/specdev.h> 84#include <miscfs/specfs/specdev.h>
85#include <miscfs/kernfs/kernfs.h> 85#include <miscfs/kernfs/kernfs.h>
86#include <xen/kernfs_machdep.h> 86#include <xen/kernfs_machdep.h>
87#include <dev/isa/isavar.h> 87#include <dev/isa/isavar.h>
88#include <xen/granttables.h> 88#include <xen/granttables.h>
89#include <xen/vcpuvar.h> 89#include <xen/vcpuvar.h>
90#if NPCI > 0 90#if NPCI > 0
91#include <dev/pci/pcivar.h> 91#include <dev/pci/pcivar.h>
92#if NACPICA > 0 92#if NACPICA > 0
93#include <dev/acpi/acpivar.h> 93#include <dev/acpi/acpivar.h>
94#include <machine/mpconfig.h> 94#include <machine/mpconfig.h>
95#include <xen/mpacpi.h> 95#include <xen/mpacpi.h>
96#endif 96#endif
97#ifdef MPBIOS 97#ifdef MPBIOS
98#include <machine/mpbiosvar.h> 98#include <machine/mpbiosvar.h>
99#endif 99#endif
100#endif /* NPCI */ 100#endif /* NPCI */
101 101
102#if NXENBUS > 0 102#if NXENBUS > 0
103#include <xen/xenbus.h> 103#include <xen/xenbus.h>
104#endif 104#endif
105 105
106#if NXENNET_HYPERVISOR > 0 106#if NXENNET_HYPERVISOR > 0
107#include <net/if.h> 107#include <net/if.h>
108#include <net/if_ether.h> 108#include <net/if_ether.h>
109#include <net/if_media.h> 109#include <net/if_media.h>
110#include <xen/if_xennetvar.h> 110#include <xen/if_xennetvar.h>
111#endif 111#endif
112 112
113#if NXBD_HYPERVISOR > 0 113#if NXBD_HYPERVISOR > 0
114#include <sys/buf.h> 114#include <sys/buf.h>
115#include <sys/disk.h> 115#include <sys/disk.h>
116#include <sys/bufq.h> 116#include <sys/bufq.h>
117#include <dev/dkvar.h> 117#include <dev/dkvar.h>
118#include <xen/xbdvar.h> 118#include <xen/xbdvar.h>
119#endif 119#endif
120 120
121int hypervisor_match(device_t, cfdata_t, void *); 121int hypervisor_match(device_t, cfdata_t, void *);
122void hypervisor_attach(device_t, device_t, void *); 122void hypervisor_attach(device_t, device_t, void *);
123 123
124CFATTACH_DECL_NEW(hypervisor, 0, 124CFATTACH_DECL_NEW(hypervisor, 0,
125 hypervisor_match, hypervisor_attach, NULL, NULL); 125 hypervisor_match, hypervisor_attach, NULL, NULL);
126 126
127static int hypervisor_print(void *, const char *); 127static int hypervisor_print(void *, const char *);
128 128
129union hypervisor_attach_cookie { 129union hypervisor_attach_cookie {
130 const char *hac_device; /* first elem of all */ 130 const char *hac_device; /* first elem of all */
131#if NXENCONS > 0 131#if NXENCONS > 0
132 struct xencons_attach_args hac_xencons; 132 struct xencons_attach_args hac_xencons;
133#endif 133#endif
134#if NXENBUS > 0 134#if NXENBUS > 0
135 struct xenbus_attach_args hac_xenbus; 135 struct xenbus_attach_args hac_xenbus;
136#endif 136#endif
137#if NXENNET_HYPERVISOR > 0 137#if NXENNET_HYPERVISOR > 0
138 struct xennet_attach_args hac_xennet; 138 struct xennet_attach_args hac_xennet;
139#endif 139#endif
140#if NXBD_HYPERVISOR > 0 140#if NXBD_HYPERVISOR > 0
141 struct xbd_attach_args hac_xbd; 141 struct xbd_attach_args hac_xbd;
142#endif 142#endif
143#if NPCI > 0 143#if NPCI > 0
144 struct pcibus_attach_args hac_pba; 144 struct pcibus_attach_args hac_pba;
145#if defined(DOM0OPS) && NISA > 0 145#if defined(DOM0OPS) && NISA > 0
146 struct isabus_attach_args hac_iba; 146 struct isabus_attach_args hac_iba;
147#endif 147#endif
148#if NACPICA > 0 148#if NACPICA > 0
149 struct acpibus_attach_args hac_acpi; 149 struct acpibus_attach_args hac_acpi;
150#endif 150#endif
151#endif /* NPCI */ 151#endif /* NPCI */
152 struct vcpu_attach_args hac_vcaa; 152 struct vcpu_attach_args hac_vcaa;
153}; 153};
154 154
155/* 155/*
156 * This is set when the ISA bus is attached. If it's not set by the 156 * This is set when the ISA bus is attached. If it's not set by the
157 * time it's checked below, then mainbus attempts to attach an ISA. 157 * time it's checked below, then mainbus attempts to attach an ISA.
158 */ 158 */
159#ifdef DOM0OPS 159#ifdef DOM0OPS
160int isa_has_been_seen; 160int isa_has_been_seen;
161#if NISA > 0 161#if NISA > 0
162struct x86_isa_chipset x86_isa_chipset; 162struct x86_isa_chipset x86_isa_chipset;
163#endif 163#endif
164#endif 164#endif
165 165
166#if defined(XENPVHVM) 166#if defined(XENPVHVM)
167#include <xen/include/public/arch-x86/cpuid.h> 167#include <xen/include/public/arch-x86/cpuid.h>
168#include <xen/include/public/hvm/hvm_op.h> 168#include <xen/include/public/hvm/hvm_op.h>
169#include <xen/include/public/hvm/params.h> 169#include <xen/include/public/hvm/params.h>
170#include <xen/include/public/vcpu.h> 170#include <xen/include/public/vcpu.h>
171 171
172#include <x86/bootinfo.h> 172#include <x86/bootinfo.h>
173 173
174#define IDTVEC(name) __CONCAT(X, name) 174#define IDTVEC(name) __CONCAT(X, name)
175typedef void (vector)(void); 175typedef void (vector)(void);
176extern vector IDTVEC(syscall); 176extern vector IDTVEC(syscall);
177extern vector IDTVEC(syscall32); 177extern vector IDTVEC(syscall32);
178extern vector IDTVEC(osyscall); 178extern vector IDTVEC(osyscall);
179extern vector *x86_exceptions[]; 179extern vector *x86_exceptions[];
180 180
181extern vector IDTVEC(hypervisor_pvhvm_callback); 181extern vector IDTVEC(hypervisor_pvhvm_callback);
182extern volatile struct xencons_interface *xencons_interface; /* XXX */ 182extern volatile struct xencons_interface *xencons_interface; /* XXX */
183extern struct xenstore_domain_interface *xenstore_interface; /* XXX */ 183extern struct xenstore_domain_interface *xenstore_interface; /* XXX */
184 184
185volatile shared_info_t *HYPERVISOR_shared_info __read_mostly; 185volatile shared_info_t *HYPERVISOR_shared_info __read_mostly;
186paddr_t HYPERVISOR_shared_info_pa; 186paddr_t HYPERVISOR_shared_info_pa;
187union start_info_union start_info_union __aligned(PAGE_SIZE); 187union start_info_union start_info_union __aligned(PAGE_SIZE);
188 188
189static int xen_hvm_vec = 0; 189static int xen_hvm_vec = 0;
190#endif 190#endif
191 191
192int xen_version; 192int xen_version;
193 193
194/* power management, for save/restore */ 194/* power management, for save/restore */
195static bool hypervisor_suspend(device_t, const pmf_qual_t *); 195static bool hypervisor_suspend(device_t, const pmf_qual_t *);
196static bool hypervisor_resume(device_t, const pmf_qual_t *); 196static bool hypervisor_resume(device_t, const pmf_qual_t *);
197 197
198/* from FreeBSD */ 198/* from FreeBSD */
199#define XEN_MAGIC_IOPORT 0x10 199#define XEN_MAGIC_IOPORT 0x10
200enum { 200enum {
201 XMI_MAGIC = 0x49d2, 201 XMI_MAGIC = 0x49d2,
202 XMI_UNPLUG_IDE_DISKS = 0x01, 202 XMI_UNPLUG_IDE_DISKS = 0x01,
203 XMI_UNPLUG_NICS = 0x02, 203 XMI_UNPLUG_NICS = 0x02,
204 XMI_UNPLUG_IDE_EXCEPT_PRI_MASTER = 0x04 204 XMI_UNPLUG_IDE_EXCEPT_PRI_MASTER = 0x04
205};  205};
206 206
207 207
208#ifdef XENPVHVM 208#ifdef XENPVHVM
209 209
210bool xenhvm_use_percpu_callback = 0; 210bool xenhvm_use_percpu_callback = 0;
211 211
212static bool 212static bool
213xen_check_hypervisordev(void) 213xen_check_hypervisordev(void)
214{ 214{
215 extern struct cfdata cfdata[]; 215 extern struct cfdata cfdata[];
216 for (int i = 0; cfdata[i].cf_name != NULL; i++) { 216 for (int i = 0; cfdata[i].cf_name != NULL; i++) {
217 if (strcasecmp("hypervisor", cfdata[i].cf_name) == 0) { 217 if (strcasecmp("hypervisor", cfdata[i].cf_name) == 0) {
218 switch(cfdata[i].cf_fstate) { 218 switch(cfdata[i].cf_fstate) {
219 case FSTATE_NOTFOUND: 219 case FSTATE_NOTFOUND:
220 case FSTATE_FOUND: 220 case FSTATE_FOUND:
221 case FSTATE_STAR: 221 case FSTATE_STAR:
222 printf("xen_check_hypervisordev: enabled\n"); 222 printf("xen_check_hypervisordev: enabled\n");
223 return true; 223 return true;
224 default: 224 default:
225 printf("xen_check_hypervisordev: disabled\n"); 225 printf("xen_check_hypervisordev: disabled\n");
226 return false; 226 return false;
227 } 227 }
228 } 228 }
229 } 229 }
230 printf("xen_check_hypervisordev: notfound\n"); 230 printf("xen_check_hypervisordev: notfound\n");
231 return 0; 231 return 0;
232} 232}
233int 233int
234xen_hvm_init(void) 234xen_hvm_init(void)
235{ 235{
236 extern vaddr_t hypercall_page; 236 extern vaddr_t hypercall_page;
237 u_int descs[4]; 237 u_int descs[4];
238 238
239 /* 239 /*
240 * We need to setup the HVM interfaces early, so that we can 240 * We need to setup the HVM interfaces early, so that we can
241 * properly setup the CPUs later (especially, all CPUs needs to 241 * properly setup the CPUs later (especially, all CPUs needs to
242 * run x86_cpuid() locally to get their vcpuid. 242 * run x86_cpuid() locally to get their vcpuid.
243 * 243 *
244 * if everything goes fine, we switch vm_guest to VM_GUEST_XENPVHVM 244 * if everything goes fine, we switch vm_guest to VM_GUEST_XENPVHVM
245 */ 245 */
246 246
247 if (vm_guest != VM_GUEST_XENHVM) 247 if (vm_guest != VM_GUEST_XENHVM)
248 return 0; 248 return 0;
249 249
250 /* check if hypervisor was disabled with userconf */ 250 /* check if hypervisor was disabled with userconf */
251 if (!xen_check_hypervisordev()) 251 if (!xen_check_hypervisordev())
252 return 0; 252 return 0;
253 253
254 aprint_normal("Identified Guest XEN in HVM mode.\n"); 254 aprint_normal("Identified Guest XEN in HVM mode.\n");
255 255
256 x86_cpuid(XEN_CPUID_LEAF(2), descs); 256 x86_cpuid(XEN_CPUID_LEAF(2), descs);
257 257
258 /*  258 /*
259 * Given 32 bytes per hypercall stub, and an optimistic number 259 * Given 32 bytes per hypercall stub, and an optimistic number
260 * of 100 hypercalls ( the current max is 55), there shouldn't 260 * of 100 hypercalls ( the current max is 55), there shouldn't
261 * be any reason to spill over the arbitrary number of 1 261 * be any reason to spill over the arbitrary number of 1
262 * hypercall page. This is what we allocate in locore.S 262 * hypercall page. This is what we allocate in locore.S
263 * anyway. Make sure the allocation matches the registration. 263 * anyway. Make sure the allocation matches the registration.
264 */ 264 */
265 265
266 KASSERT(descs[0] == 1); 266 KASSERT(descs[0] == 1);
267 267
268 /* XXX: vtophys(&hypercall_page) */ 268 /* XXX: vtophys(&hypercall_page) */
269 wrmsr(descs[1], (uintptr_t)&hypercall_page - KERNBASE); 269 wrmsr(descs[1], (uintptr_t)&hypercall_page - KERNBASE);
270 270
271 if (-1 != HYPERVISOR_xen_version(XENVER_version, NULL)) { 271 if (-1 != HYPERVISOR_xen_version(XENVER_version, NULL)) {
272 printf("Xen HVM: detected functional hypercall page.\n"); 272 printf("Xen HVM: detected functional hypercall page.\n");
273 xen_init_features(); 273 xen_init_features();
274 } 274 }
275 275
276 /* Init various preset boot time data structures */ 276 /* Init various preset boot time data structures */
277 277
278 /* XEN xenstore shared page address, event channel */ 278 /* XEN xenstore shared page address, event channel */
279 struct xen_hvm_param xen_hvm_param; 279 struct xen_hvm_param xen_hvm_param;
280 280
281 xen_hvm_param.domid = DOMID_SELF; 281 xen_hvm_param.domid = DOMID_SELF;
282 xen_hvm_param.index = HVM_PARAM_STORE_PFN; 282 xen_hvm_param.index = HVM_PARAM_STORE_PFN;
283  283
284 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) { 284 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
285 aprint_error( 285 aprint_error(
286 "Xen HVM: Unable to obtain xenstore page address\n"); 286 "Xen HVM: Unable to obtain xenstore page address\n");
287 return 0; 287 return 0;
288 } 288 }
289 289
290 /* Re-use PV field */ 290 /* Re-use PV field */
291 xen_start_info.store_mfn = xen_hvm_param.value; 291 xen_start_info.store_mfn = xen_hvm_param.value;
292 292
293 pmap_kenter_pa((vaddr_t) xenstore_interface, ptoa(xen_start_info.store_mfn), 293 pmap_kenter_pa((vaddr_t) xenstore_interface, ptoa(xen_start_info.store_mfn),
294 VM_PROT_READ|VM_PROT_WRITE, 0); 294 VM_PROT_READ|VM_PROT_WRITE, 0);
295 295
296 xen_hvm_param.domid = DOMID_SELF; 296 xen_hvm_param.domid = DOMID_SELF;
297 xen_hvm_param.index = HVM_PARAM_STORE_EVTCHN; 297 xen_hvm_param.index = HVM_PARAM_STORE_EVTCHN;
298 298
299 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) { 299 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
300 aprint_error( 300 aprint_error(
301 "Xen HVM: Unable to obtain xenstore event channel\n"); 301 "Xen HVM: Unable to obtain xenstore event channel\n");
302 return 0; 302 return 0;
303 } 303 }
304 304
305 xen_start_info.store_evtchn = xen_hvm_param.value; 305 xen_start_info.store_evtchn = xen_hvm_param.value;
306 306
307 xen_hvm_param.domid = DOMID_SELF; 307 xen_hvm_param.domid = DOMID_SELF;
308 xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN; 308 xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN;
309  309
310 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) { 310 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
311 aprint_error( 311 aprint_error(
312 "Xen HVM: Unable to obtain xencons page address\n"); 312 "Xen HVM: Unable to obtain xencons page address\n");
313 return 0; 313 return 0;
314 } 314 }
315 315
316 /* Re-use PV field */ 316 /* Re-use PV field */
317 xen_start_info.console.domU.mfn = xen_hvm_param.value; 317 xen_start_info.console.domU.mfn = xen_hvm_param.value;
318 318
319 pmap_kenter_pa((vaddr_t) xencons_interface, ptoa(xen_start_info.console.domU.mfn), 319 pmap_kenter_pa((vaddr_t) xencons_interface, ptoa(xen_start_info.console.domU.mfn),
320 VM_PROT_READ|VM_PROT_WRITE, 0); 320 VM_PROT_READ|VM_PROT_WRITE, 0);
321 321
322 xen_hvm_param.domid = DOMID_SELF; 322 xen_hvm_param.domid = DOMID_SELF;
323 xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN; 323 xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN;
324 324
325 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) { 325 if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
326 aprint_error( 326 aprint_error(
327 "Xen HVM: Unable to obtain xencons event channel\n"); 327 "Xen HVM: Unable to obtain xencons event channel\n");
328 return 0; 328 return 0;
329 } 329 }
330 330
331 xen_start_info.console.domU.evtchn = xen_hvm_param.value; 331 xen_start_info.console.domU.evtchn = xen_hvm_param.value;
332 332
333 /* HYPERVISOR_shared_info */ 333 /* HYPERVISOR_shared_info */
334 struct xen_add_to_physmap xmap = { 334 struct xen_add_to_physmap xmap = {
335 .domid = DOMID_SELF, 335 .domid = DOMID_SELF,
336 .space = XENMAPSPACE_shared_info, 336 .space = XENMAPSPACE_shared_info,
337 .idx = 0, /* Important - XEN checks for this */ 337 .idx = 0, /* Important - XEN checks for this */
338 .gpfn = atop(HYPERVISOR_shared_info_pa) 338 .gpfn = atop(HYPERVISOR_shared_info_pa)
339 }; 339 };
340 340
341 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xmap) < 0) { 341 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xmap) < 0) {
342 aprint_error( 342 aprint_error(
343 "Xen HVM: Unable to register HYPERVISOR_shared_info\n"); 343 "Xen HVM: Unable to register HYPERVISOR_shared_info\n");
344 return 0; 344 return 0;
345 } 345 }
346 346
347 /* HYPERVISOR_shared_info va,pa has been allocated in pmap_bootstrap() */ 347 /* HYPERVISOR_shared_info va,pa has been allocated in pmap_bootstrap() */
348 pmap_kenter_pa((vaddr_t) HYPERVISOR_shared_info, 348 pmap_kenter_pa((vaddr_t) HYPERVISOR_shared_info,
349 HYPERVISOR_shared_info_pa, VM_PROT_READ|VM_PROT_WRITE, 0); 349 HYPERVISOR_shared_info_pa, VM_PROT_READ|VM_PROT_WRITE, 0);
350 350
351 /* 351 /*
352 * First register callback: here's why 352 * First register callback: here's why
353 * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867 353 * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867
354 */ 354 */
355 355
356 /* 356 /*
357 * Check for XENFEAT_hvm_callback_vector. Can't proceed 357 * Check for XENFEAT_hvm_callback_vector. Can't proceed
358 * without it. 358 * without it.
359 */ 359 */
360 if (!xen_feature(XENFEAT_hvm_callback_vector)) { 360 if (!xen_feature(XENFEAT_hvm_callback_vector)) {
361 aprint_error("Xen HVM: XENFEAT_hvm_callback_vector" 361 aprint_error("Xen HVM: XENFEAT_hvm_callback_vector"
362 "not available, cannot proceed"); 362 "not available, cannot proceed");
363 return 0; 363 return 0;
364 } 364 }
365 365
366 /* 366 /*
367 * prepare vector. 367 * prepare vector.
368 * We don't really care where it is, as long as it's free 368 * We don't really care where it is, as long as it's free
369 */ 369 */
370 xen_hvm_vec = idt_vec_alloc(129, 255); 370 xen_hvm_vec = idt_vec_alloc(129, 255);
371 idt_vec_set(xen_hvm_vec, &IDTVEC(hypervisor_pvhvm_callback)); 371 idt_vec_set(xen_hvm_vec, &IDTVEC(hypervisor_pvhvm_callback));
372 372
373 events_default_setup(); 373 events_default_setup();
374 374
375 delay_func = xen_delay; 375 delay_func = xen_delay;
376 x86_initclock_func = xen_initclocks; 376 x86_initclock_func = xen_initclocks;
377 x86_cpu_initclock_func = xen_cpu_initclocks; 377 x86_cpu_initclock_func = xen_cpu_initclocks;
378 vm_guest = VM_GUEST_XENPVHVM; /* Be more specific */ 378 vm_guest = VM_GUEST_XENPVHVM; /* Be more specific */
379 return 1; 379 return 1;
380} 380}
381 381
382int 382int
383xen_hvm_init_cpu(struct cpu_info *ci) 383xen_hvm_init_cpu(struct cpu_info *ci)
384{ 384{
385 u_int32_t descs[4]; 385 u_int32_t descs[4];
386 struct xen_hvm_param xen_hvm_param; 386 struct xen_hvm_param xen_hvm_param;
387 int error; 387 int error;
388 static bool again = 0; 388 static bool again = 0;
389 389
390 if (vm_guest != VM_GUEST_XENPVHVM) 390 if (vm_guest != VM_GUEST_XENPVHVM)
391 return 0; 391 return 0;
392 392
393 KASSERT(ci == curcpu()); 393 KASSERT(ci == curcpu());
394 394
395 descs[0] = 0; 395 descs[0] = 0;
396 x86_cpuid(XEN_CPUID_LEAF(4), descs); 396 x86_cpuid(XEN_CPUID_LEAF(4), descs);
397 if (!(descs[0] & XEN_HVM_CPUID_VCPU_ID_PRESENT)) { 397 if (!(descs[0] & XEN_HVM_CPUID_VCPU_ID_PRESENT)) {
398 aprint_error_dev(ci->ci_dev, "Xen HVM: can't get VCPU id\n"); 398 aprint_error_dev(ci->ci_dev, "Xen HVM: can't get VCPU id\n");
399 vm_guest = VM_GUEST_XENHVM; 399 vm_guest = VM_GUEST_XENHVM;
400 return 0; 400 return 0;
401 } 401 }
402 printf("cpu %s ci_acpiid %d vcpuid %d domid %d\n", 
403 device_xname(ci->ci_dev), ci->ci_acpiid, descs[1], descs[2]); 
404 402
405 ci->ci_vcpuid = descs[1]; 403 ci->ci_vcpuid = descs[1];
406 ci->ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[ci->ci_vcpuid]; 404 ci->ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[ci->ci_vcpuid];
407 405
408 /* Register event callback handler. */ 406 /* Register event callback handler. */
409 407
410 xen_hvm_param.domid = DOMID_SELF; 408 xen_hvm_param.domid = DOMID_SELF;
411 xen_hvm_param.index = HVM_PARAM_CALLBACK_IRQ; 409 xen_hvm_param.index = HVM_PARAM_CALLBACK_IRQ;
412 410
413 /* val[63:56] = 2, val[7:0] = vec */ 411 /* val[63:56] = 2, val[7:0] = vec */
414 xen_hvm_param.value = ((int64_t)0x2 << 56) | xen_hvm_vec; 412 xen_hvm_param.value = ((int64_t)0x2 << 56) | xen_hvm_vec;
415 413
416 /* First try to set up a per-cpu vector. */ 414 /* First try to set up a per-cpu vector. */
417 if (!again || xenhvm_use_percpu_callback) { 415 if (!again || xenhvm_use_percpu_callback) {
418 struct xen_hvm_evtchn_upcall_vector xen_hvm_uvec; 416 struct xen_hvm_evtchn_upcall_vector xen_hvm_uvec;
419 xen_hvm_uvec.vcpu = ci->ci_vcpuid; 417 xen_hvm_uvec.vcpu = ci->ci_vcpuid;
420 xen_hvm_uvec.vector = xen_hvm_vec; 418 xen_hvm_uvec.vector = xen_hvm_vec;
421 419
422 xenhvm_use_percpu_callback = 1; 420 xenhvm_use_percpu_callback = 1;
423 error = HYPERVISOR_hvm_op( 421 error = HYPERVISOR_hvm_op(
424 HVMOP_set_evtchn_upcall_vector, &xen_hvm_uvec); 422 HVMOP_set_evtchn_upcall_vector, &xen_hvm_uvec);
425 if (error < 0) { 423 if (error < 0) {
426 aprint_error_dev(ci->ci_dev, 424 aprint_error_dev(ci->ci_dev,
427 "failed to set event upcall vector: %d\n", error); 425 "failed to set event upcall vector: %d\n", error);
428 if (again) 426 if (again)
429 panic("event upcall vector"); 427 panic("event upcall vector");
430 aprint_error_dev(ci->ci_dev, 428 aprint_error_dev(ci->ci_dev,
431 "falling back to global vector\n"); 429 "falling back to global vector\n");
432 } else { 430 } else {
433 /* 431 /*
434 * From FreeBSD: 432 * From FreeBSD:
435 * Trick toolstack to think we are enlightened 433 * Trick toolstack to think we are enlightened
436 */ 434 */
 435 xen_hvm_param.value = 1;
437 aprint_verbose_dev(ci->ci_dev, 436 aprint_verbose_dev(ci->ci_dev,
438 "using event upcall vector: %d\n", xen_hvm_vec ); 437 "using event upcall vector: %d\n", xen_hvm_vec );
439 xen_hvm_param.value = 1; 
440 } 438 }
441 } 439 }
442 440
443 if (again) 441 if (again)
444 return 1; 442 return 1;
445 443
446 if (HYPERVISOR_hvm_op(HVMOP_set_param, &xen_hvm_param) < 0) { 444 if (HYPERVISOR_hvm_op(HVMOP_set_param, &xen_hvm_param) < 0) {
447 aprint_error_dev(ci->ci_dev, 445 aprint_error_dev(ci->ci_dev,
448 "Xen HVM: Unable to register event callback vector\n"); 446 "Xen HVM: Unable to register event callback vector\n");
449 vm_guest = VM_GUEST_XENHVM; 447 vm_guest = VM_GUEST_XENHVM;
450 return 0; 448 return 0;
451 } 449 }
452 again = 1; 450 again = 1;
453 return 1; 451 return 1;
454} 452}
455 453
456#endif /* XENPVHVM */ 454#endif /* XENPVHVM */
457 455
458/* 456/*
459 * Probe for the hypervisor; always succeeds. 457 * Probe for the hypervisor; always succeeds.
460 */ 458 */
461int 459int
462hypervisor_match(device_t parent, cfdata_t match, void *aux) 460hypervisor_match(device_t parent, cfdata_t match, void *aux)
463{ 461{
464 struct hypervisor_attach_args *haa = aux; 462 struct hypervisor_attach_args *haa = aux;
465 463
466 /* Attach path sanity check */ 464 /* Attach path sanity check */
467 if (strncmp(haa->haa_busname, "hypervisor", sizeof("hypervisor")) != 0) 465 if (strncmp(haa->haa_busname, "hypervisor", sizeof("hypervisor")) != 0)
468 return 0; 466 return 0;
469 467
470 468
471#ifdef XENPVHVM 469#ifdef XENPVHVM
472 if (vm_guest != VM_GUEST_XENPVHVM) 470 if (vm_guest != VM_GUEST_XENPVHVM)
473 return 0; 471 return 0;
474#endif 472#endif
475 /* If we got here, it must mean we matched */ 473 /* If we got here, it must mean we matched */
476 return 1; 474 return 1;
477} 475}
478 476
479#ifdef MULTIPROCESSOR 477#if defined(MULTIPROCESSOR) && defined(XENPV)
480static int 478static int
481hypervisor_vcpu_print(void *aux, const char *parent) 479hypervisor_vcpu_print(void *aux, const char *parent)
482{ 480{
483 /* Unconfigured cpus are ignored quietly. */ 481 /* Unconfigured cpus are ignored quietly. */
484 return (QUIET); 482 return (QUIET);
485} 483}
486#endif /* MULTIPROCESSOR */ 484#endif /* MULTIPROCESSOR && XENPV */
487 485
488/* 486/*
489 * Attach the hypervisor. 487 * Attach the hypervisor.
490 */ 488 */
491void 489void
492hypervisor_attach(device_t parent, device_t self, void *aux) 490hypervisor_attach(device_t parent, device_t self, void *aux)
493{ 491{
494 492
495#if NPCI >0 493#if NPCI >0
496#ifdef PCI_BUS_FIXUP 494#ifdef PCI_BUS_FIXUP
497 int pci_maxbus = 0; 495 int pci_maxbus = 0;
498#endif 496#endif
499#endif /* NPCI */ 497#endif /* NPCI */
500 union hypervisor_attach_cookie hac; 498 union hypervisor_attach_cookie hac;
501 char xen_extra_version[XEN_EXTRAVERSION_LEN]; 499 char xen_extra_version[XEN_EXTRAVERSION_LEN];
502 static char xen_version_string[20]; 500 static char xen_version_string[20];
503 int rc; 501 int rc;
504 const struct sysctlnode *node = NULL; 502 const struct sysctlnode *node = NULL;
505 503
506#ifdef XENPVHVM 504#ifdef XENPVHVM
507 /* 505 /*
508 * Set the boot device to xbd0a. 506 * Set the boot device to xbd0a.
509 * We claim this is a reasonable default which is picked up 507 * We claim this is a reasonable default which is picked up
510 * later as the rootfs device. 508 * later as the rootfs device.
511 * 509 *
512 * We need to do this because the HVM domain loader uses the 510 * We need to do this because the HVM domain loader uses the
513 * regular BIOS based native boot(8) procedure, which sets the 511 * regular BIOS based native boot(8) procedure, which sets the
514 * boot device to the native driver/partition of whatever was 512 * boot device to the native driver/partition of whatever was
515 * detected by the native bootloader. 513 * detected by the native bootloader.
516 */ 514 */
517 515
518 struct btinfo_rootdevice bi; 516 struct btinfo_rootdevice bi;
519 snprintf(bi.devname, 6, "xbd0a"); 517 snprintf(bi.devname, 6, "xbd0a");
520 bi.common.type = BTINFO_ROOTDEVICE; 518 bi.common.type = BTINFO_ROOTDEVICE;
521 bi.common.len = sizeof(struct btinfo_rootdevice); 519 bi.common.len = sizeof(struct btinfo_rootdevice);
522 520
523 /* From i386/multiboot.c */ 521 /* From i386/multiboot.c */
524 int i, len; 522 int i, len;
525 vaddr_t data; 523 vaddr_t data;
526 extern struct bootinfo bootinfo; 524 extern struct bootinfo bootinfo;
527 struct bootinfo *bip = (struct bootinfo *)&bootinfo; 525 struct bootinfo *bip = (struct bootinfo *)&bootinfo;
528 len = bi.common.len; 526 len = bi.common.len;
529 527
530 data = (vaddr_t)&bip->bi_data; 528 data = (vaddr_t)&bip->bi_data;
531 for (i = 0; i < bip->bi_nentries; i++) { 529 for (i = 0; i < bip->bi_nentries; i++) {
532 struct btinfo_common *tmp; 530 struct btinfo_common *tmp;
533 531
534 tmp = (struct btinfo_common *)data; 532 tmp = (struct btinfo_common *)data;
535 data += tmp->len; 533 data += tmp->len;
536 } 534 }
537 if (data + len < (vaddr_t)&bip->bi_data + sizeof(bip->bi_data)) { 535 if (data + len < (vaddr_t)&bip->bi_data + sizeof(bip->bi_data)) {
538 memcpy((void *)data, &bi, len); 536 memcpy((void *)data, &bi, len);
539 bip->bi_nentries++; 537 bip->bi_nentries++;
540 } 538 }
541 539
542 /* disable emulated devices */ 540 /* disable emulated devices */
543 if (inw(XEN_MAGIC_IOPORT) == XMI_MAGIC) { 541 if (inw(XEN_MAGIC_IOPORT) == XMI_MAGIC) {
544 outw(XEN_MAGIC_IOPORT, XMI_UNPLUG_IDE_DISKS | XMI_UNPLUG_NICS); 542 outw(XEN_MAGIC_IOPORT, XMI_UNPLUG_IDE_DISKS | XMI_UNPLUG_NICS);
545 } else { 543 } else {
546 aprint_error_dev(self, "Unable to disable emulated devices\n"); 544 aprint_error_dev(self, "Unable to disable emulated devices\n");
547 } 545 }
548#endif /* XENPVHVM */ 546#endif /* XENPVHVM */
549 xenkernfs_init(); 547 xenkernfs_init();
550 548
551 xen_version = HYPERVISOR_xen_version(XENVER_version, NULL); 549 xen_version = HYPERVISOR_xen_version(XENVER_version, NULL);
552 memset(xen_extra_version, 0, sizeof(xen_extra_version)); 550 memset(xen_extra_version, 0, sizeof(xen_extra_version));
553 HYPERVISOR_xen_version(XENVER_extraversion, xen_extra_version); 551 HYPERVISOR_xen_version(XENVER_extraversion, xen_extra_version);
554 rc = snprintf(xen_version_string, 20, "%d.%d%s", XEN_MAJOR(xen_version), 552 rc = snprintf(xen_version_string, 20, "%d.%d%s", XEN_MAJOR(xen_version),
555 XEN_MINOR(xen_version), xen_extra_version); 553 XEN_MINOR(xen_version), xen_extra_version);
556 aprint_normal(": Xen version %s\n", xen_version_string); 554 aprint_normal(": Xen version %s\n", xen_version_string);
557 if (rc >= 20) 555 if (rc >= 20)
558 aprint_debug(": xen_version_string truncated\n"); 556 aprint_debug(": xen_version_string truncated\n");
559 557
560 sysctl_createv(NULL, 0, NULL, &node, 0, 558 sysctl_createv(NULL, 0, NULL, &node, 0,
561 CTLTYPE_NODE, "xen", 559 CTLTYPE_NODE, "xen",
562 SYSCTL_DESCR("Xen top level node"), 560 SYSCTL_DESCR("Xen top level node"),
563 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); 561 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
564 562
565 if (node != NULL) { 563 if (node != NULL) {
566 sysctl_createv(NULL, 0, &node, NULL, CTLFLAG_READONLY, 564 sysctl_createv(NULL, 0, &node, NULL, CTLFLAG_READONLY,
567 CTLTYPE_STRING, "version", 565 CTLTYPE_STRING, "version",
568 SYSCTL_DESCR("Xen hypervisor version"), 566 SYSCTL_DESCR("Xen hypervisor version"),
569 NULL, 0, xen_version_string, 0, CTL_CREATE, CTL_EOL); 567 NULL, 0, xen_version_string, 0, CTL_CREATE, CTL_EOL);
570 } 568 }
571 569
572 aprint_verbose_dev(self, "features: "); 570 aprint_verbose_dev(self, "features: ");
573#define XEN_TST_F(n) \ 571#define XEN_TST_F(n) \
574 if (xen_feature(XENFEAT_##n)) \ 572 if (xen_feature(XENFEAT_##n)) \
575 aprint_verbose(" %s", #n); 573 aprint_verbose(" %s", #n);
576 574
577 XEN_TST_F(writable_page_tables); 575 XEN_TST_F(writable_page_tables);
578 XEN_TST_F(writable_descriptor_tables); 576 XEN_TST_F(writable_descriptor_tables);
579 XEN_TST_F(auto_translated_physmap); 577 XEN_TST_F(auto_translated_physmap);
580 XEN_TST_F(supervisor_mode_kernel); 578 XEN_TST_F(supervisor_mode_kernel);
581 XEN_TST_F(pae_pgdir_above_4gb); 579 XEN_TST_F(pae_pgdir_above_4gb);
582 XEN_TST_F(mmu_pt_update_preserve_ad); 580 XEN_TST_F(mmu_pt_update_preserve_ad);
583 XEN_TST_F(highmem_assist); 581 XEN_TST_F(highmem_assist);
584 XEN_TST_F(gnttab_map_avail_bits); 582 XEN_TST_F(gnttab_map_avail_bits);
585 XEN_TST_F(hvm_callback_vector); 583 XEN_TST_F(hvm_callback_vector);
586 XEN_TST_F(hvm_safe_pvclock); 584 XEN_TST_F(hvm_safe_pvclock);
587 XEN_TST_F(hvm_pirqs); 585 XEN_TST_F(hvm_pirqs);
588#undef XEN_TST_F 586#undef XEN_TST_F
589 aprint_verbose("\n"); 587 aprint_verbose("\n");
590 588
591 xengnt_init(); 589 xengnt_init();
592 events_init(); 590 events_init();
593 591
 592#ifdef XENPV
594 memset(&hac, 0, sizeof(hac)); 593 memset(&hac, 0, sizeof(hac));
595 hac.hac_vcaa.vcaa_name = "vcpu"; 594 hac.hac_vcaa.vcaa_name = "vcpu";
596 hac.hac_vcaa.vcaa_caa.cpu_number = 0; 595 hac.hac_vcaa.vcaa_caa.cpu_number = 0;
597 hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_BP; 596 hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_BP;
598 hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */ 597 hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */
599 config_found_ia(self, "xendevbus", &hac.hac_vcaa, hypervisor_print); 598 config_found_ia(self, "xendevbus", &hac.hac_vcaa, hypervisor_print);
600 599
601#ifdef MULTIPROCESSOR 600#ifdef MULTIPROCESSOR
602 601
603 /* 602 /*
604 * The xenstore contains the configured number of vcpus. 603 * The xenstore contains the configured number of vcpus.
605 * The xenstore however, is not accessible until much later in 604 * The xenstore however, is not accessible until much later in
606 * the boot sequence. We therefore bruteforce check for 605 * the boot sequence. We therefore bruteforce check for
607 * allocated vcpus (See: cpu.c:vcpu_match()) by iterating 606 * allocated vcpus (See: cpu.c:vcpu_match()) by iterating
608 * through the maximum supported by NetBSD MP. 607 * through the maximum supported by NetBSD MP.
609 */ 608 */
610 cpuid_t vcpuid; 609 cpuid_t vcpuid;
611 610
612 for (vcpuid = 1; vcpuid < maxcpus; vcpuid++) { 611 for (vcpuid = 1; vcpuid < maxcpus; vcpuid++) {
613 memset(&hac, 0, sizeof(hac)); 612 memset(&hac, 0, sizeof(hac));
614 hac.hac_vcaa.vcaa_name = "vcpu"; 613 hac.hac_vcaa.vcaa_name = "vcpu";
615 hac.hac_vcaa.vcaa_caa.cpu_number = vcpuid; 614 hac.hac_vcaa.vcaa_caa.cpu_number = vcpuid;
616 hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_AP; 615 hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_AP;
617 hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */ 616 hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */
618 if (NULL == config_found_ia(self, "xendevbus", &hac.hac_vcaa, 617 if (NULL == config_found_ia(self, "xendevbus", &hac.hac_vcaa,
619 hypervisor_vcpu_print)) { 618 hypervisor_vcpu_print)) {
620 break; 619 break;
621 } 620 }
622 } 621 }
623 622
624#endif /* MULTIPROCESSOR */ 623#endif /* MULTIPROCESSOR */
 624#endif /* XENPV */
625 625
626#if NXENBUS > 0 626#if NXENBUS > 0
627 extern struct x86_bus_dma_tag xenbus_bus_dma_tag; 627 extern struct x86_bus_dma_tag xenbus_bus_dma_tag;
628 memset(&hac, 0, sizeof(hac)); 628 memset(&hac, 0, sizeof(hac));
629 hac.hac_xenbus.xa_device = "xenbus"; 629 hac.hac_xenbus.xa_device = "xenbus";
630 hac.hac_xenbus.xa_dmat = &xenbus_bus_dma_tag; 630 hac.hac_xenbus.xa_dmat = &xenbus_bus_dma_tag;
631 config_found_ia(self, "xendevbus", &hac.hac_xenbus, hypervisor_print); 631 config_found_ia(self, "xendevbus", &hac.hac_xenbus, hypervisor_print);
632#endif 632#endif
633#if NXENCONS > 0 633#if NXENCONS > 0
634 memset(&hac, 0, sizeof(hac)); 634 memset(&hac, 0, sizeof(hac));
635 hac.hac_xencons.xa_device = "xencons"; 635 hac.hac_xencons.xa_device = "xencons";
636 config_found_ia(self, "xendevbus", &hac.hac_xencons, hypervisor_print); 636 config_found_ia(self, "xendevbus", &hac.hac_xencons, hypervisor_print);
637#endif 637#endif
638#ifdef DOM0OPS 638#ifdef DOM0OPS
639#if NPCI > 0 639#if NPCI > 0
640#if NACPICA > 0 640#if NACPICA > 0
641 if (acpi_present) { 641 if (acpi_present) {
642 memset(&hac, 0, sizeof(hac)); 642 memset(&hac, 0, sizeof(hac));
643 hac.hac_acpi.aa_iot = x86_bus_space_io; 643 hac.hac_acpi.aa_iot = x86_bus_space_io;
644 hac.hac_acpi.aa_memt = x86_bus_space_mem; 644 hac.hac_acpi.aa_memt = x86_bus_space_mem;
645 hac.hac_acpi.aa_pc = NULL; 645 hac.hac_acpi.aa_pc = NULL;
646 hac.hac_acpi.aa_pciflags = 646 hac.hac_acpi.aa_pciflags =
647 PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | 647 PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY |
648 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | 648 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY |
649 PCI_FLAGS_MWI_OKAY; 649 PCI_FLAGS_MWI_OKAY;
650 hac.hac_acpi.aa_ic = &x86_isa_chipset; 650 hac.hac_acpi.aa_ic = &x86_isa_chipset;
651 hac.hac_acpi.aa_dmat = &pci_bus_dma_tag; 651 hac.hac_acpi.aa_dmat = &pci_bus_dma_tag;
652#ifdef _LP64 652#ifdef _LP64
653 hac.hac_acpi.aa_dmat64 = &pci_bus_dma64_tag; 653 hac.hac_acpi.aa_dmat64 = &pci_bus_dma64_tag;
654#else 654#else
655 hac.hac_acpi.aa_dmat64 = NULL; 655 hac.hac_acpi.aa_dmat64 = NULL;
656#endif /* _LP64 */ 656#endif /* _LP64 */
657 config_found_ia(self, "acpibus", &hac.hac_acpi, 0); 657 config_found_ia(self, "acpibus", &hac.hac_acpi, 0);
658 } 658 }
659#endif /* NACPICA */ 659#endif /* NACPICA */
660 memset(&hac, 0, sizeof(hac)); 660 memset(&hac, 0, sizeof(hac));
661 hac.hac_pba.pba_iot = x86_bus_space_io; 661 hac.hac_pba.pba_iot = x86_bus_space_io;
662 hac.hac_pba.pba_memt = x86_bus_space_mem; 662 hac.hac_pba.pba_memt = x86_bus_space_mem;
663 hac.hac_pba.pba_dmat = &pci_bus_dma_tag; 663 hac.hac_pba.pba_dmat = &pci_bus_dma_tag;
664#ifdef _LP64 664#ifdef _LP64
665 hac.hac_pba.pba_dmat64 = &pci_bus_dma64_tag; 665 hac.hac_pba.pba_dmat64 = &pci_bus_dma64_tag;
666#else 666#else
667 hac.hac_pba.pba_dmat64 = NULL; 667 hac.hac_pba.pba_dmat64 = NULL;
668#endif /* _LP64 */ 668#endif /* _LP64 */
669 hac.hac_pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY; 669 hac.hac_pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY;
670 hac.hac_pba.pba_bridgetag = NULL; 670 hac.hac_pba.pba_bridgetag = NULL;
671 hac.hac_pba.pba_bus = 0; 671 hac.hac_pba.pba_bus = 0;
672#if NACPICA > 0 && defined(ACPI_SCANPCI) 672#if NACPICA > 0 && defined(ACPI_SCANPCI)
673 if (mpacpi_active) 673 if (mpacpi_active)
674 mp_pci_scan(self, &hac.hac_pba, pcibusprint); 674 mp_pci_scan(self, &hac.hac_pba, pcibusprint);
675 else 675 else
676#endif 676#endif
677#if defined(MPBIOS) && defined(MPBIOS_SCANPCI) 677#if defined(MPBIOS) && defined(MPBIOS_SCANPCI)
678 if (mpbios_scanned != 0) 678 if (mpbios_scanned != 0)
679 mp_pci_scan(self, &hac.hac_pba, pcibusprint); 679 mp_pci_scan(self, &hac.hac_pba, pcibusprint);
680 else 680 else
681#endif 681#endif
682 config_found_ia(self, "pcibus", &hac.hac_pba, pcibusprint); 682 config_found_ia(self, "pcibus", &hac.hac_pba, pcibusprint);
683#if NACPICA > 0 683#if NACPICA > 0
684 if (mp_verbose) 684 if (mp_verbose)
685 acpi_pci_link_state(); 685 acpi_pci_link_state();
686#endif 686#endif
687#if NISA > 0 687#if NISA > 0
688 if (isa_has_been_seen == 0) { 688 if (isa_has_been_seen == 0) {
689 memset(&hac, 0, sizeof(hac)); 689 memset(&hac, 0, sizeof(hac));
690 hac.hac_iba._iba_busname = "isa"; 690 hac.hac_iba._iba_busname = "isa";
691 hac.hac_iba.iba_iot = x86_bus_space_io; 691 hac.hac_iba.iba_iot = x86_bus_space_io;
692 hac.hac_iba.iba_memt = x86_bus_space_mem; 692 hac.hac_iba.iba_memt = x86_bus_space_mem;
693 hac.hac_iba.iba_dmat = &isa_bus_dma_tag; 693 hac.hac_iba.iba_dmat = &isa_bus_dma_tag;
694 hac.hac_iba.iba_ic = NULL; /* No isa DMA yet */ 694 hac.hac_iba.iba_ic = NULL; /* No isa DMA yet */
695 config_found_ia(self, "isabus", &hac.hac_iba, isabusprint); 695 config_found_ia(self, "isabus", &hac.hac_iba, isabusprint);
696 } 696 }
697#endif /* NISA */ 697#endif /* NISA */
698#endif /* NPCI */ 698#endif /* NPCI */
699 699
700 if (xendomain_is_privileged()) { 700 if (xendomain_is_privileged()) {
701 xenprivcmd_init(); 701 xenprivcmd_init();
702 } 702 }
703#endif /* DOM0OPS */ 703#endif /* DOM0OPS */
704 704
705 hypervisor_machdep_attach(); 705 hypervisor_machdep_attach();
706 706
707 if (!pmf_device_register(self, hypervisor_suspend, hypervisor_resume)) 707 if (!pmf_device_register(self, hypervisor_suspend, hypervisor_resume))
708 aprint_error_dev(self, "couldn't establish power handler\n"); 708 aprint_error_dev(self, "couldn't establish power handler\n");
709 709
710} 710}
711 711
712static bool 712static bool
713hypervisor_suspend(device_t dev, const pmf_qual_t *qual) 713hypervisor_suspend(device_t dev, const pmf_qual_t *qual)
714{ 714{
715#ifdef XENPV 715#ifdef XENPV
716 events_suspend(); 716 events_suspend();
717 xengnt_suspend(); 717 xengnt_suspend();
718#endif 718#endif
719 return true; 719 return true;
720} 720}
721 721
722static bool 722static bool
723hypervisor_resume(device_t dev, const pmf_qual_t *qual) 723hypervisor_resume(device_t dev, const pmf_qual_t *qual)
724{ 724{
725#ifdef XENPV 725#ifdef XENPV
726 hypervisor_machdep_resume(); 726 hypervisor_machdep_resume();
727 727
728 xengnt_resume(); 728 xengnt_resume();
729 events_resume(); 729 events_resume();
730#endif 730#endif
731 return true; 731 return true;
732} 732}
733 733
734static int 734static int
735hypervisor_print(void *aux, const char *parent) 735hypervisor_print(void *aux, const char *parent)
736{ 736{
737 union hypervisor_attach_cookie *hac = aux; 737 union hypervisor_attach_cookie *hac = aux;
738 738
739 if (parent) 739 if (parent)
740 aprint_normal("%s at %s", hac->hac_device, parent); 740 aprint_normal("%s at %s", hac->hac_device, parent);
741 return (UNCONF); 741 return (UNCONF);
742} 742}
743 743
744#define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 744#define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
745 745
746kernfs_parentdir_t *kernxen_pkt; 746kernfs_parentdir_t *kernxen_pkt;
747 747
748void 748void
749xenkernfs_init(void) 749xenkernfs_init(void)
750{ 750{
751 kernfs_entry_t *dkt; 751 kernfs_entry_t *dkt;
752 752
753 KERNFS_ALLOCENTRY(dkt, KM_SLEEP); 753 KERNFS_ALLOCENTRY(dkt, KM_SLEEP);
754 KERNFS_INITENTRY(dkt, DT_DIR, "xen", NULL, KFSsubdir, VDIR, DIR_MODE); 754 KERNFS_INITENTRY(dkt, DT_DIR, "xen", NULL, KFSsubdir, VDIR, DIR_MODE);
755 kernfs_addentry(NULL, dkt); 755 kernfs_addentry(NULL, dkt);
756 kernxen_pkt = KERNFS_ENTOPARENTDIR(dkt); 756 kernxen_pkt = KERNFS_ENTOPARENTDIR(dkt);
757} 757}