xref: /freebsd-12.1/sys/dev/hyperv/vmbus/vmbus.c (revision 2fb2dbe8)
1 /*-
2  * Copyright (c) 2009-2012,2016 Microsoft Corp.
3  * Copyright (c) 2012 NetApp Inc.
4  * Copyright (c) 2012 Citrix Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * VM Bus Driver Implementation
31  */
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34 
35 #include <sys/param.h>
36 #include <sys/bus.h>
37 #include <sys/kernel.h>
38 #include <sys/lock.h>
39 #include <sys/malloc.h>
40 #include <sys/module.h>
41 #include <sys/proc.h>
42 #include <sys/sysctl.h>
43 #include <sys/syslog.h>
44 #include <sys/systm.h>
45 #include <sys/rtprio.h>
46 #include <sys/interrupt.h>
47 #include <sys/sx.h>
48 #include <sys/taskqueue.h>
49 #include <sys/mutex.h>
50 #include <sys/smp.h>
51 
52 #include <machine/resource.h>
53 #include <sys/rman.h>
54 
55 #include <machine/stdarg.h>
56 #include <machine/intr_machdep.h>
57 #include <machine/md_var.h>
58 #include <machine/segments.h>
59 #include <sys/pcpu.h>
60 #include <x86/apicvar.h>
61 
62 #include <dev/hyperv/include/hyperv.h>
63 #include <dev/hyperv/vmbus/hv_vmbus_priv.h>
64 #include <dev/hyperv/vmbus/hyperv_reg.h>
65 #include <dev/hyperv/vmbus/hyperv_var.h>
66 #include <dev/hyperv/vmbus/vmbus_reg.h>
67 #include <dev/hyperv/vmbus/vmbus_var.h>
68 
69 #include <contrib/dev/acpica/include/acpi.h>
70 #include "acpi_if.h"
71 #include "vmbus_if.h"
72 
73 #define VMBUS_GPADL_START		0xe1e10
74 
75 struct vmbus_msghc {
76 	struct hypercall_postmsg_in	*mh_inprm;
77 	struct hypercall_postmsg_in	mh_inprm_save;
78 	struct hyperv_dma		mh_inprm_dma;
79 
80 	struct vmbus_message		*mh_resp;
81 	struct vmbus_message		mh_resp0;
82 };
83 
84 struct vmbus_msghc_ctx {
85 	struct vmbus_msghc		*mhc_free;
86 	struct mtx			mhc_free_lock;
87 	uint32_t			mhc_flags;
88 
89 	struct vmbus_msghc		*mhc_active;
90 	struct mtx			mhc_active_lock;
91 };
92 
93 #define VMBUS_MSGHC_CTXF_DESTROY	0x0001
94 
95 static int			vmbus_init(struct vmbus_softc *);
96 static int			vmbus_connect(struct vmbus_softc *, uint32_t);
97 static int			vmbus_req_channels(struct vmbus_softc *sc);
98 static void			vmbus_disconnect(struct vmbus_softc *);
99 static int			vmbus_scan(struct vmbus_softc *);
100 static void			vmbus_scan_wait(struct vmbus_softc *);
101 static void			vmbus_scan_newchan(struct vmbus_softc *);
102 static void			vmbus_scan_newdev(struct vmbus_softc *);
103 static void			vmbus_scan_done(struct vmbus_softc *,
104 				    const struct vmbus_message *);
105 static void			vmbus_chanmsg_handle(struct vmbus_softc *,
106 				    const struct vmbus_message *);
107 
108 static int			vmbus_sysctl_version(SYSCTL_HANDLER_ARGS);
109 
110 static struct vmbus_msghc_ctx	*vmbus_msghc_ctx_create(bus_dma_tag_t);
111 static void			vmbus_msghc_ctx_destroy(
112 				    struct vmbus_msghc_ctx *);
113 static void			vmbus_msghc_ctx_free(struct vmbus_msghc_ctx *);
114 static struct vmbus_msghc	*vmbus_msghc_alloc(bus_dma_tag_t);
115 static void			vmbus_msghc_free(struct vmbus_msghc *);
116 static struct vmbus_msghc	*vmbus_msghc_get1(struct vmbus_msghc_ctx *,
117 				    uint32_t);
118 
119 struct vmbus_softc	*vmbus_sc;
120 
121 extern inthand_t IDTVEC(vmbus_isr);
122 
123 static const uint32_t		vmbus_version[] = {
124 	VMBUS_VERSION_WIN8_1,
125 	VMBUS_VERSION_WIN8,
126 	VMBUS_VERSION_WIN7,
127 	VMBUS_VERSION_WS2008
128 };
129 
130 static const vmbus_chanmsg_proc_t
131 vmbus_chanmsg_handlers[VMBUS_CHANMSG_TYPE_MAX] = {
132 	VMBUS_CHANMSG_PROC(CHOFFER_DONE, vmbus_scan_done),
133 	VMBUS_CHANMSG_PROC_WAKEUP(CONNECT_RESP)
134 };
135 
136 static struct vmbus_msghc *
137 vmbus_msghc_alloc(bus_dma_tag_t parent_dtag)
138 {
139 	struct vmbus_msghc *mh;
140 
141 	mh = malloc(sizeof(*mh), M_DEVBUF, M_WAITOK | M_ZERO);
142 
143 	mh->mh_inprm = hyperv_dmamem_alloc(parent_dtag,
144 	    HYPERCALL_PARAM_ALIGN, 0, HYPERCALL_POSTMSGIN_SIZE,
145 	    &mh->mh_inprm_dma, BUS_DMA_WAITOK);
146 	if (mh->mh_inprm == NULL) {
147 		free(mh, M_DEVBUF);
148 		return NULL;
149 	}
150 	return mh;
151 }
152 
153 static void
154 vmbus_msghc_free(struct vmbus_msghc *mh)
155 {
156 	hyperv_dmamem_free(&mh->mh_inprm_dma, mh->mh_inprm);
157 	free(mh, M_DEVBUF);
158 }
159 
160 static void
161 vmbus_msghc_ctx_free(struct vmbus_msghc_ctx *mhc)
162 {
163 	KASSERT(mhc->mhc_active == NULL, ("still have active msg hypercall"));
164 	KASSERT(mhc->mhc_free == NULL, ("still have hypercall msg"));
165 
166 	mtx_destroy(&mhc->mhc_free_lock);
167 	mtx_destroy(&mhc->mhc_active_lock);
168 	free(mhc, M_DEVBUF);
169 }
170 
171 static struct vmbus_msghc_ctx *
172 vmbus_msghc_ctx_create(bus_dma_tag_t parent_dtag)
173 {
174 	struct vmbus_msghc_ctx *mhc;
175 
176 	mhc = malloc(sizeof(*mhc), M_DEVBUF, M_WAITOK | M_ZERO);
177 	mtx_init(&mhc->mhc_free_lock, "vmbus msghc free", NULL, MTX_DEF);
178 	mtx_init(&mhc->mhc_active_lock, "vmbus msghc act", NULL, MTX_DEF);
179 
180 	mhc->mhc_free = vmbus_msghc_alloc(parent_dtag);
181 	if (mhc->mhc_free == NULL) {
182 		vmbus_msghc_ctx_free(mhc);
183 		return NULL;
184 	}
185 	return mhc;
186 }
187 
188 static struct vmbus_msghc *
189 vmbus_msghc_get1(struct vmbus_msghc_ctx *mhc, uint32_t dtor_flag)
190 {
191 	struct vmbus_msghc *mh;
192 
193 	mtx_lock(&mhc->mhc_free_lock);
194 
195 	while ((mhc->mhc_flags & dtor_flag) == 0 && mhc->mhc_free == NULL) {
196 		mtx_sleep(&mhc->mhc_free, &mhc->mhc_free_lock, 0,
197 		    "gmsghc", 0);
198 	}
199 	if (mhc->mhc_flags & dtor_flag) {
200 		/* Being destroyed */
201 		mh = NULL;
202 	} else {
203 		mh = mhc->mhc_free;
204 		KASSERT(mh != NULL, ("no free hypercall msg"));
205 		KASSERT(mh->mh_resp == NULL,
206 		    ("hypercall msg has pending response"));
207 		mhc->mhc_free = NULL;
208 	}
209 
210 	mtx_unlock(&mhc->mhc_free_lock);
211 
212 	return mh;
213 }
214 
215 void
216 vmbus_msghc_reset(struct vmbus_msghc *mh, size_t dsize)
217 {
218 	struct hypercall_postmsg_in *inprm;
219 
220 	if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX)
221 		panic("invalid data size %zu", dsize);
222 
223 	inprm = mh->mh_inprm;
224 	memset(inprm, 0, HYPERCALL_POSTMSGIN_SIZE);
225 	inprm->hc_connid = VMBUS_CONNID_MESSAGE;
226 	inprm->hc_msgtype = HYPERV_MSGTYPE_CHANNEL;
227 	inprm->hc_dsize = dsize;
228 }
229 
230 struct vmbus_msghc *
231 vmbus_msghc_get(struct vmbus_softc *sc, size_t dsize)
232 {
233 	struct vmbus_msghc *mh;
234 
235 	if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX)
236 		panic("invalid data size %zu", dsize);
237 
238 	mh = vmbus_msghc_get1(sc->vmbus_msg_hc, VMBUS_MSGHC_CTXF_DESTROY);
239 	if (mh == NULL)
240 		return NULL;
241 
242 	vmbus_msghc_reset(mh, dsize);
243 	return mh;
244 }
245 
246 void
247 vmbus_msghc_put(struct vmbus_softc *sc, struct vmbus_msghc *mh)
248 {
249 	struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc;
250 
251 	KASSERT(mhc->mhc_active == NULL, ("msg hypercall is active"));
252 	mh->mh_resp = NULL;
253 
254 	mtx_lock(&mhc->mhc_free_lock);
255 	KASSERT(mhc->mhc_free == NULL, ("has free hypercall msg"));
256 	mhc->mhc_free = mh;
257 	mtx_unlock(&mhc->mhc_free_lock);
258 	wakeup(&mhc->mhc_free);
259 }
260 
261 void *
262 vmbus_msghc_dataptr(struct vmbus_msghc *mh)
263 {
264 	return mh->mh_inprm->hc_data;
265 }
266 
267 static void
268 vmbus_msghc_ctx_destroy(struct vmbus_msghc_ctx *mhc)
269 {
270 	struct vmbus_msghc *mh;
271 
272 	mtx_lock(&mhc->mhc_free_lock);
273 	mhc->mhc_flags |= VMBUS_MSGHC_CTXF_DESTROY;
274 	mtx_unlock(&mhc->mhc_free_lock);
275 	wakeup(&mhc->mhc_free);
276 
277 	mh = vmbus_msghc_get1(mhc, 0);
278 	if (mh == NULL)
279 		panic("can't get msghc");
280 
281 	vmbus_msghc_free(mh);
282 	vmbus_msghc_ctx_free(mhc);
283 }
284 
285 int
286 vmbus_msghc_exec_noresult(struct vmbus_msghc *mh)
287 {
288 	sbintime_t time = SBT_1MS;
289 	int i;
290 
291 	/*
292 	 * Save the input parameter so that we could restore the input
293 	 * parameter if the Hypercall failed.
294 	 *
295 	 * XXX
296 	 * Is this really necessary?!  i.e. Will the Hypercall ever
297 	 * overwrite the input parameter?
298 	 */
299 	memcpy(&mh->mh_inprm_save, mh->mh_inprm, HYPERCALL_POSTMSGIN_SIZE);
300 
301 	/*
302 	 * In order to cope with transient failures, e.g. insufficient
303 	 * resources on host side, we retry the post message Hypercall
304 	 * several times.  20 retries seem sufficient.
305 	 */
306 #define HC_RETRY_MAX	20
307 
308 	for (i = 0; i < HC_RETRY_MAX; ++i) {
309 		uint64_t status;
310 
311 		status = hypercall_post_message(mh->mh_inprm_dma.hv_paddr);
312 		if (status == HYPERCALL_STATUS_SUCCESS)
313 			return 0;
314 
315 		pause_sbt("hcpmsg", time, 0, C_HARDCLOCK);
316 		if (time < SBT_1S * 2)
317 			time *= 2;
318 
319 		/* Restore input parameter and try again */
320 		memcpy(mh->mh_inprm, &mh->mh_inprm_save,
321 		    HYPERCALL_POSTMSGIN_SIZE);
322 	}
323 
324 #undef HC_RETRY_MAX
325 
326 	return EIO;
327 }
328 
329 int
330 vmbus_msghc_exec(struct vmbus_softc *sc, struct vmbus_msghc *mh)
331 {
332 	struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc;
333 	int error;
334 
335 	KASSERT(mh->mh_resp == NULL, ("hypercall msg has pending response"));
336 
337 	mtx_lock(&mhc->mhc_active_lock);
338 	KASSERT(mhc->mhc_active == NULL, ("pending active msg hypercall"));
339 	mhc->mhc_active = mh;
340 	mtx_unlock(&mhc->mhc_active_lock);
341 
342 	error = vmbus_msghc_exec_noresult(mh);
343 	if (error) {
344 		mtx_lock(&mhc->mhc_active_lock);
345 		KASSERT(mhc->mhc_active == mh, ("msghc mismatch"));
346 		mhc->mhc_active = NULL;
347 		mtx_unlock(&mhc->mhc_active_lock);
348 	}
349 	return error;
350 }
351 
352 const struct vmbus_message *
353 vmbus_msghc_wait_result(struct vmbus_softc *sc, struct vmbus_msghc *mh)
354 {
355 	struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc;
356 
357 	mtx_lock(&mhc->mhc_active_lock);
358 
359 	KASSERT(mhc->mhc_active == mh, ("msghc mismatch"));
360 	while (mh->mh_resp == NULL) {
361 		mtx_sleep(&mhc->mhc_active, &mhc->mhc_active_lock, 0,
362 		    "wmsghc", 0);
363 	}
364 	mhc->mhc_active = NULL;
365 
366 	mtx_unlock(&mhc->mhc_active_lock);
367 
368 	return mh->mh_resp;
369 }
370 
371 void
372 vmbus_msghc_wakeup(struct vmbus_softc *sc, const struct vmbus_message *msg)
373 {
374 	struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc;
375 	struct vmbus_msghc *mh;
376 
377 	mtx_lock(&mhc->mhc_active_lock);
378 
379 	mh = mhc->mhc_active;
380 	KASSERT(mh != NULL, ("no pending msg hypercall"));
381 	memcpy(&mh->mh_resp0, msg, sizeof(mh->mh_resp0));
382 	mh->mh_resp = &mh->mh_resp0;
383 
384 	mtx_unlock(&mhc->mhc_active_lock);
385 	wakeup(&mhc->mhc_active);
386 }
387 
388 uint32_t
389 vmbus_gpadl_alloc(struct vmbus_softc *sc)
390 {
391 	return atomic_fetchadd_int(&sc->vmbus_gpadl, 1);
392 }
393 
394 static int
395 vmbus_connect(struct vmbus_softc *sc, uint32_t version)
396 {
397 	struct vmbus_chanmsg_connect *req;
398 	const struct vmbus_message *msg;
399 	struct vmbus_msghc *mh;
400 	int error, done = 0;
401 
402 	mh = vmbus_msghc_get(sc, sizeof(*req));
403 	if (mh == NULL)
404 		return ENXIO;
405 
406 	req = vmbus_msghc_dataptr(mh);
407 	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CONNECT;
408 	req->chm_ver = version;
409 	req->chm_evtflags = sc->vmbus_evtflags_dma.hv_paddr;
410 	req->chm_mnf1 = sc->vmbus_mnf1_dma.hv_paddr;
411 	req->chm_mnf2 = sc->vmbus_mnf2_dma.hv_paddr;
412 
413 	error = vmbus_msghc_exec(sc, mh);
414 	if (error) {
415 		vmbus_msghc_put(sc, mh);
416 		return error;
417 	}
418 
419 	msg = vmbus_msghc_wait_result(sc, mh);
420 	done = ((const struct vmbus_chanmsg_connect_resp *)
421 	    msg->msg_data)->chm_done;
422 
423 	vmbus_msghc_put(sc, mh);
424 
425 	return (done ? 0 : EOPNOTSUPP);
426 }
427 
428 static int
429 vmbus_init(struct vmbus_softc *sc)
430 {
431 	int i;
432 
433 	for (i = 0; i < nitems(vmbus_version); ++i) {
434 		int error;
435 
436 		error = vmbus_connect(sc, vmbus_version[i]);
437 		if (!error) {
438 			sc->vmbus_version = vmbus_version[i];
439 			device_printf(sc->vmbus_dev, "version %u.%u\n",
440 			    VMBUS_VERSION_MAJOR(sc->vmbus_version),
441 			    VMBUS_VERSION_MINOR(sc->vmbus_version));
442 			return 0;
443 		}
444 	}
445 	return ENXIO;
446 }
447 
448 static void
449 vmbus_disconnect(struct vmbus_softc *sc)
450 {
451 	struct vmbus_chanmsg_disconnect *req;
452 	struct vmbus_msghc *mh;
453 	int error;
454 
455 	mh = vmbus_msghc_get(sc, sizeof(*req));
456 	if (mh == NULL) {
457 		device_printf(sc->vmbus_dev,
458 		    "can not get msg hypercall for disconnect\n");
459 		return;
460 	}
461 
462 	req = vmbus_msghc_dataptr(mh);
463 	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_DISCONNECT;
464 
465 	error = vmbus_msghc_exec_noresult(mh);
466 	vmbus_msghc_put(sc, mh);
467 
468 	if (error) {
469 		device_printf(sc->vmbus_dev,
470 		    "disconnect msg hypercall failed\n");
471 	}
472 }
473 
474 static int
475 vmbus_req_channels(struct vmbus_softc *sc)
476 {
477 	struct vmbus_chanmsg_chrequest *req;
478 	struct vmbus_msghc *mh;
479 	int error;
480 
481 	mh = vmbus_msghc_get(sc, sizeof(*req));
482 	if (mh == NULL)
483 		return ENXIO;
484 
485 	req = vmbus_msghc_dataptr(mh);
486 	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHREQUEST;
487 
488 	error = vmbus_msghc_exec_noresult(mh);
489 	vmbus_msghc_put(sc, mh);
490 
491 	return error;
492 }
493 
494 static void
495 vmbus_scan_newchan(struct vmbus_softc *sc)
496 {
497 	mtx_lock(&sc->vmbus_scan_lock);
498 	if ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0)
499 		sc->vmbus_scan_chcnt++;
500 	mtx_unlock(&sc->vmbus_scan_lock);
501 }
502 
503 static void
504 vmbus_scan_done(struct vmbus_softc *sc,
505     const struct vmbus_message *msg __unused)
506 {
507 	mtx_lock(&sc->vmbus_scan_lock);
508 	sc->vmbus_scan_chcnt |= VMBUS_SCAN_CHCNT_DONE;
509 	mtx_unlock(&sc->vmbus_scan_lock);
510 	wakeup(&sc->vmbus_scan_chcnt);
511 }
512 
513 static void
514 vmbus_scan_newdev(struct vmbus_softc *sc)
515 {
516 	mtx_lock(&sc->vmbus_scan_lock);
517 	sc->vmbus_scan_devcnt++;
518 	mtx_unlock(&sc->vmbus_scan_lock);
519 	wakeup(&sc->vmbus_scan_devcnt);
520 }
521 
522 static void
523 vmbus_scan_wait(struct vmbus_softc *sc)
524 {
525 	uint32_t chancnt;
526 
527 	mtx_lock(&sc->vmbus_scan_lock);
528 	while ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0) {
529 		mtx_sleep(&sc->vmbus_scan_chcnt, &sc->vmbus_scan_lock, 0,
530 		    "waitch", 0);
531 	}
532 	chancnt = sc->vmbus_scan_chcnt & ~VMBUS_SCAN_CHCNT_DONE;
533 
534 	while (sc->vmbus_scan_devcnt != chancnt) {
535 		mtx_sleep(&sc->vmbus_scan_devcnt, &sc->vmbus_scan_lock, 0,
536 		    "waitdev", 0);
537 	}
538 	mtx_unlock(&sc->vmbus_scan_lock);
539 }
540 
541 static int
542 vmbus_scan(struct vmbus_softc *sc)
543 {
544 	int error;
545 
546 	/*
547 	 * Start vmbus scanning.
548 	 */
549 	error = vmbus_req_channels(sc);
550 	if (error) {
551 		device_printf(sc->vmbus_dev, "channel request failed: %d\n",
552 		    error);
553 		return error;
554 	}
555 
556 	/*
557 	 * Wait for all devices are added to vmbus.
558 	 */
559 	vmbus_scan_wait(sc);
560 
561 	/*
562 	 * Identify, probe and attach.
563 	 */
564 	bus_generic_probe(sc->vmbus_dev);
565 	bus_generic_attach(sc->vmbus_dev);
566 
567 	if (bootverbose) {
568 		device_printf(sc->vmbus_dev, "device scan, probe and attach "
569 		    "done\n");
570 	}
571 	return 0;
572 }
573 
574 static void
575 vmbus_chanmsg_handle(struct vmbus_softc *sc, const struct vmbus_message *msg)
576 {
577 	vmbus_chanmsg_proc_t msg_proc;
578 	uint32_t msg_type;
579 
580 	msg_type = ((const struct vmbus_chanmsg_hdr *)msg->msg_data)->chm_type;
581 	if (msg_type >= VMBUS_CHANMSG_TYPE_MAX) {
582 		device_printf(sc->vmbus_dev, "unknown message type 0x%x\n",
583 		    msg_type);
584 		return;
585 	}
586 
587 	msg_proc = vmbus_chanmsg_handlers[msg_type];
588 	if (msg_proc != NULL)
589 		msg_proc(sc, msg);
590 
591 	/* Channel specific processing */
592 	vmbus_chan_msgproc(sc, msg);
593 }
594 
595 static void
596 vmbus_msg_task(void *xsc, int pending __unused)
597 {
598 	struct vmbus_softc *sc = xsc;
599 	volatile struct vmbus_message *msg;
600 
601 	msg = VMBUS_PCPU_GET(sc, message, curcpu) + VMBUS_SINT_MESSAGE;
602 	for (;;) {
603 		if (msg->msg_type == HYPERV_MSGTYPE_NONE) {
604 			/* No message */
605 			break;
606 		} else if (msg->msg_type == HYPERV_MSGTYPE_CHANNEL) {
607 			/* Channel message */
608 			vmbus_chanmsg_handle(sc,
609 			    __DEVOLATILE(const struct vmbus_message *, msg));
610 		}
611 
612 		msg->msg_type = HYPERV_MSGTYPE_NONE;
613 		/*
614 		 * Make sure the write to msg_type (i.e. set to
615 		 * HYPERV_MSGTYPE_NONE) happens before we read the
616 		 * msg_flags and EOMing. Otherwise, the EOMing will
617 		 * not deliver any more messages since there is no
618 		 * empty slot
619 		 *
620 		 * NOTE:
621 		 * mb() is used here, since atomic_thread_fence_seq_cst()
622 		 * will become compiler fence on UP kernel.
623 		 */
624 		mb();
625 		if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
626 			/*
627 			 * This will cause message queue rescan to possibly
628 			 * deliver another msg from the hypervisor
629 			 */
630 			wrmsr(MSR_HV_EOM, 0);
631 		}
632 	}
633 }
634 
635 static __inline int
636 vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
637 {
638 	volatile struct vmbus_message *msg;
639 	struct vmbus_message *msg_base;
640 
641 	msg_base = VMBUS_PCPU_GET(sc, message, cpu);
642 
643 	/*
644 	 * Check event timer.
645 	 *
646 	 * TODO: move this to independent IDT vector.
647 	 */
648 	msg = msg_base + VMBUS_SINT_TIMER;
649 	if (msg->msg_type == HYPERV_MSGTYPE_TIMER_EXPIRED) {
650 		msg->msg_type = HYPERV_MSGTYPE_NONE;
651 
652 		vmbus_et_intr(frame);
653 
654 		/*
655 		 * Make sure the write to msg_type (i.e. set to
656 		 * HYPERV_MSGTYPE_NONE) happens before we read the
657 		 * msg_flags and EOMing. Otherwise, the EOMing will
658 		 * not deliver any more messages since there is no
659 		 * empty slot
660 		 *
661 		 * NOTE:
662 		 * mb() is used here, since atomic_thread_fence_seq_cst()
663 		 * will become compiler fence on UP kernel.
664 		 */
665 		mb();
666 		if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
667 			/*
668 			 * This will cause message queue rescan to possibly
669 			 * deliver another msg from the hypervisor
670 			 */
671 			wrmsr(MSR_HV_EOM, 0);
672 		}
673 	}
674 
675 	/*
676 	 * Check events.  Hot path for network and storage I/O data; high rate.
677 	 *
678 	 * NOTE:
679 	 * As recommended by the Windows guest fellows, we check events before
680 	 * checking messages.
681 	 */
682 	sc->vmbus_event_proc(sc, cpu);
683 
684 	/*
685 	 * Check messages.  Mainly management stuffs; ultra low rate.
686 	 */
687 	msg = msg_base + VMBUS_SINT_MESSAGE;
688 	if (__predict_false(msg->msg_type != HYPERV_MSGTYPE_NONE)) {
689 		taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu),
690 		    VMBUS_PCPU_PTR(sc, message_task, cpu));
691 	}
692 
693 	return (FILTER_HANDLED);
694 }
695 
696 void
697 vmbus_handle_intr(struct trapframe *trap_frame)
698 {
699 	struct vmbus_softc *sc = vmbus_get_softc();
700 	int cpu = curcpu;
701 
702 	/*
703 	 * Disable preemption.
704 	 */
705 	critical_enter();
706 
707 	/*
708 	 * Do a little interrupt counting.
709 	 */
710 	(*VMBUS_PCPU_GET(sc, intr_cnt, cpu))++;
711 
712 	vmbus_handle_intr1(sc, trap_frame, cpu);
713 
714 	/*
715 	 * Enable preemption.
716 	 */
717 	critical_exit();
718 }
719 
720 static void
721 vmbus_synic_setup(void *xsc)
722 {
723 	struct vmbus_softc *sc = xsc;
724 	int cpu = curcpu;
725 	uint64_t val, orig;
726 	uint32_t sint;
727 
728 	if (hyperv_features & CPUID_HV_MSR_VP_INDEX) {
729 		/*
730 		 * Save virtual processor id.
731 		 */
732 		VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
733 	} else {
734 		/*
735 		 * XXX
736 		 * Virtual processoor id is only used by a pretty broken
737 		 * channel selection code from storvsc.  It's nothing
738 		 * critical even if CPUID_HV_MSR_VP_INDEX is not set; keep
739 		 * moving on.
740 		 */
741 		VMBUS_PCPU_GET(sc, vcpuid, cpu) = cpu;
742 	}
743 
744 	/*
745 	 * Setup the SynIC message.
746 	 */
747 	orig = rdmsr(MSR_HV_SIMP);
748 	val = MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK) |
749 	    ((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
750 	     MSR_HV_SIMP_PGSHIFT);
751 	wrmsr(MSR_HV_SIMP, val);
752 
753 	/*
754 	 * Setup the SynIC event flags.
755 	 */
756 	orig = rdmsr(MSR_HV_SIEFP);
757 	val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
758 	    ((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu)
759 	      >> PAGE_SHIFT) << MSR_HV_SIEFP_PGSHIFT);
760 	wrmsr(MSR_HV_SIEFP, val);
761 
762 
763 	/*
764 	 * Configure and unmask SINT for message and event flags.
765 	 */
766 	sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
767 	orig = rdmsr(sint);
768 	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
769 	    (orig & MSR_HV_SINT_RSVD_MASK);
770 	wrmsr(sint, val);
771 
772 	/*
773 	 * Configure and unmask SINT for timer.
774 	 */
775 	sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
776 	orig = rdmsr(sint);
777 	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
778 	    (orig & MSR_HV_SINT_RSVD_MASK);
779 	wrmsr(sint, val);
780 
781 	/*
782 	 * All done; enable SynIC.
783 	 */
784 	orig = rdmsr(MSR_HV_SCONTROL);
785 	val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK);
786 	wrmsr(MSR_HV_SCONTROL, val);
787 }
788 
789 static void
790 vmbus_synic_teardown(void *arg)
791 {
792 	uint64_t orig;
793 	uint32_t sint;
794 
795 	/*
796 	 * Disable SynIC.
797 	 */
798 	orig = rdmsr(MSR_HV_SCONTROL);
799 	wrmsr(MSR_HV_SCONTROL, (orig & MSR_HV_SCTRL_RSVD_MASK));
800 
801 	/*
802 	 * Mask message and event flags SINT.
803 	 */
804 	sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
805 	orig = rdmsr(sint);
806 	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
807 
808 	/*
809 	 * Mask timer SINT.
810 	 */
811 	sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
812 	orig = rdmsr(sint);
813 	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
814 
815 	/*
816 	 * Teardown SynIC message.
817 	 */
818 	orig = rdmsr(MSR_HV_SIMP);
819 	wrmsr(MSR_HV_SIMP, (orig & MSR_HV_SIMP_RSVD_MASK));
820 
821 	/*
822 	 * Teardown SynIC event flags.
823 	 */
824 	orig = rdmsr(MSR_HV_SIEFP);
825 	wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
826 }
827 
828 static int
829 vmbus_dma_alloc(struct vmbus_softc *sc)
830 {
831 	bus_dma_tag_t parent_dtag;
832 	uint8_t *evtflags;
833 	int cpu;
834 
835 	parent_dtag = bus_get_dma_tag(sc->vmbus_dev);
836 	CPU_FOREACH(cpu) {
837 		void *ptr;
838 
839 		/*
840 		 * Per-cpu messages and event flags.
841 		 */
842 		ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
843 		    PAGE_SIZE, VMBUS_PCPU_PTR(sc, message_dma, cpu),
844 		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
845 		if (ptr == NULL)
846 			return ENOMEM;
847 		VMBUS_PCPU_GET(sc, message, cpu) = ptr;
848 
849 		ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
850 		    PAGE_SIZE, VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
851 		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
852 		if (ptr == NULL)
853 			return ENOMEM;
854 		VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
855 	}
856 
857 	evtflags = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
858 	    PAGE_SIZE, &sc->vmbus_evtflags_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
859 	if (evtflags == NULL)
860 		return ENOMEM;
861 	sc->vmbus_rx_evtflags = (u_long *)evtflags;
862 	sc->vmbus_tx_evtflags = (u_long *)(evtflags + (PAGE_SIZE / 2));
863 	sc->vmbus_evtflags = evtflags;
864 
865 	sc->vmbus_mnf1 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
866 	    PAGE_SIZE, &sc->vmbus_mnf1_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
867 	if (sc->vmbus_mnf1 == NULL)
868 		return ENOMEM;
869 
870 	sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
871 	    sizeof(struct vmbus_mnf), &sc->vmbus_mnf2_dma,
872 	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
873 	if (sc->vmbus_mnf2 == NULL)
874 		return ENOMEM;
875 
876 	return 0;
877 }
878 
879 static void
880 vmbus_dma_free(struct vmbus_softc *sc)
881 {
882 	int cpu;
883 
884 	if (sc->vmbus_evtflags != NULL) {
885 		hyperv_dmamem_free(&sc->vmbus_evtflags_dma, sc->vmbus_evtflags);
886 		sc->vmbus_evtflags = NULL;
887 		sc->vmbus_rx_evtflags = NULL;
888 		sc->vmbus_tx_evtflags = NULL;
889 	}
890 	if (sc->vmbus_mnf1 != NULL) {
891 		hyperv_dmamem_free(&sc->vmbus_mnf1_dma, sc->vmbus_mnf1);
892 		sc->vmbus_mnf1 = NULL;
893 	}
894 	if (sc->vmbus_mnf2 != NULL) {
895 		hyperv_dmamem_free(&sc->vmbus_mnf2_dma, sc->vmbus_mnf2);
896 		sc->vmbus_mnf2 = NULL;
897 	}
898 
899 	CPU_FOREACH(cpu) {
900 		if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) {
901 			hyperv_dmamem_free(
902 			    VMBUS_PCPU_PTR(sc, message_dma, cpu),
903 			    VMBUS_PCPU_GET(sc, message, cpu));
904 			VMBUS_PCPU_GET(sc, message, cpu) = NULL;
905 		}
906 		if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) {
907 			hyperv_dmamem_free(
908 			    VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
909 			    VMBUS_PCPU_GET(sc, event_flags, cpu));
910 			VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL;
911 		}
912 	}
913 }
914 
915 static int
916 vmbus_intr_setup(struct vmbus_softc *sc)
917 {
918 	int cpu;
919 
920 	CPU_FOREACH(cpu) {
921 		char buf[MAXCOMLEN + 1];
922 		cpuset_t cpu_mask;
923 
924 		/* Allocate an interrupt counter for Hyper-V interrupt */
925 		snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
926 		intrcnt_add(buf, VMBUS_PCPU_PTR(sc, intr_cnt, cpu));
927 
928 		/*
929 		 * Setup taskqueue to handle events.  Task will be per-
930 		 * channel.
931 		 */
932 		VMBUS_PCPU_GET(sc, event_tq, cpu) = taskqueue_create_fast(
933 		    "hyperv event", M_WAITOK, taskqueue_thread_enqueue,
934 		    VMBUS_PCPU_PTR(sc, event_tq, cpu));
935 		CPU_SETOF(cpu, &cpu_mask);
936 		taskqueue_start_threads_cpuset(
937 		    VMBUS_PCPU_PTR(sc, event_tq, cpu), 1, PI_NET, &cpu_mask,
938 		    "hvevent%d", cpu);
939 
940 		/*
941 		 * Setup tasks and taskqueues to handle messages.
942 		 */
943 		VMBUS_PCPU_GET(sc, message_tq, cpu) = taskqueue_create_fast(
944 		    "hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
945 		    VMBUS_PCPU_PTR(sc, message_tq, cpu));
946 		CPU_SETOF(cpu, &cpu_mask);
947 		taskqueue_start_threads_cpuset(
948 		    VMBUS_PCPU_PTR(sc, message_tq, cpu), 1, PI_NET, &cpu_mask,
949 		    "hvmsg%d", cpu);
950 		TASK_INIT(VMBUS_PCPU_PTR(sc, message_task, cpu), 0,
951 		    vmbus_msg_task, sc);
952 	}
953 
954 	/*
955 	 * All Hyper-V ISR required resources are setup, now let's find a
956 	 * free IDT vector for Hyper-V ISR and set it up.
957 	 */
958 	sc->vmbus_idtvec = lapic_ipi_alloc(IDTVEC(vmbus_isr));
959 	if (sc->vmbus_idtvec < 0) {
960 		device_printf(sc->vmbus_dev, "cannot find free IDT vector\n");
961 		return ENXIO;
962 	}
963 	if(bootverbose) {
964 		device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n",
965 		    sc->vmbus_idtvec);
966 	}
967 	return 0;
968 }
969 
970 static void
971 vmbus_intr_teardown(struct vmbus_softc *sc)
972 {
973 	int cpu;
974 
975 	if (sc->vmbus_idtvec >= 0) {
976 		lapic_ipi_free(sc->vmbus_idtvec);
977 		sc->vmbus_idtvec = -1;
978 	}
979 
980 	CPU_FOREACH(cpu) {
981 		if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) {
982 			taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu));
983 			VMBUS_PCPU_GET(sc, event_tq, cpu) = NULL;
984 		}
985 		if (VMBUS_PCPU_GET(sc, message_tq, cpu) != NULL) {
986 			taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu),
987 			    VMBUS_PCPU_PTR(sc, message_task, cpu));
988 			taskqueue_free(VMBUS_PCPU_GET(sc, message_tq, cpu));
989 			VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL;
990 		}
991 	}
992 }
993 
994 static int
995 vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
996 {
997 	return (ENOENT);
998 }
999 
1000 static int
1001 vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen)
1002 {
1003 	const struct hv_vmbus_channel *chan;
1004 	char guidbuf[HYPERV_GUID_STRLEN];
1005 
1006 	chan = vmbus_get_channel(child);
1007 	if (chan == NULL) {
1008 		/* Event timer device, which does not belong to a channel */
1009 		return (0);
1010 	}
1011 
1012 	strlcat(buf, "classid=", buflen);
1013 	hyperv_guid2str(&chan->ch_guid_type, guidbuf, sizeof(guidbuf));
1014 	strlcat(buf, guidbuf, buflen);
1015 
1016 	strlcat(buf, " deviceid=", buflen);
1017 	hyperv_guid2str(&chan->ch_guid_inst, guidbuf, sizeof(guidbuf));
1018 	strlcat(buf, guidbuf, buflen);
1019 
1020 	return (0);
1021 }
1022 
1023 int
1024 hv_vmbus_child_device_register(struct hv_vmbus_channel *chan)
1025 {
1026 	struct vmbus_softc *sc = chan->vmbus_sc;
1027 	device_t parent = sc->vmbus_dev;
1028 	int error = 0;
1029 
1030 	/* New channel has been offered */
1031 	vmbus_scan_newchan(sc);
1032 
1033 	chan->ch_dev = device_add_child(parent, NULL, -1);
1034 	if (chan->ch_dev == NULL) {
1035 		device_printf(parent, "device_add_child for chan%u failed\n",
1036 		    chan->ch_id);
1037 		error = ENXIO;
1038 		goto done;
1039 	}
1040 	device_set_ivars(chan->ch_dev, chan);
1041 
1042 done:
1043 	/* New device has been/should be added to vmbus. */
1044 	vmbus_scan_newdev(sc);
1045 	return error;
1046 }
1047 
1048 int
1049 hv_vmbus_child_device_unregister(struct hv_vmbus_channel *chan)
1050 {
1051 	int error;
1052 
1053 	if (chan->ch_dev == NULL) {
1054 		/* Failed to add a device. */
1055 		return 0;
1056 	}
1057 
1058 	/*
1059 	 * XXXKYS: Ensure that this is the opposite of
1060 	 * device_add_child()
1061 	 */
1062 	mtx_lock(&Giant);
1063 	error = device_delete_child(chan->vmbus_sc->vmbus_dev, chan->ch_dev);
1064 	mtx_unlock(&Giant);
1065 
1066 	return error;
1067 }
1068 
1069 static int
1070 vmbus_sysctl_version(SYSCTL_HANDLER_ARGS)
1071 {
1072 	struct vmbus_softc *sc = arg1;
1073 	char verstr[16];
1074 
1075 	snprintf(verstr, sizeof(verstr), "%u.%u",
1076 	    VMBUS_VERSION_MAJOR(sc->vmbus_version),
1077 	    VMBUS_VERSION_MINOR(sc->vmbus_version));
1078 	return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
1079 }
1080 
1081 static uint32_t
1082 vmbus_get_version_method(device_t bus, device_t dev)
1083 {
1084 	struct vmbus_softc *sc = device_get_softc(bus);
1085 
1086 	return sc->vmbus_version;
1087 }
1088 
1089 static int
1090 vmbus_probe_guid_method(device_t bus, device_t dev,
1091     const struct hyperv_guid *guid)
1092 {
1093 	const struct hv_vmbus_channel *chan = vmbus_get_channel(dev);
1094 
1095 	if (memcmp(&chan->ch_guid_type, guid, sizeof(struct hyperv_guid)) == 0)
1096 		return 0;
1097 	return ENXIO;
1098 }
1099 
1100 static int
1101 vmbus_probe(device_t dev)
1102 {
1103 	char *id[] = { "VMBUS", NULL };
1104 
1105 	if (ACPI_ID_PROBE(device_get_parent(dev), dev, id) == NULL ||
1106 	    device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV ||
1107 	    (hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
1108 		return (ENXIO);
1109 
1110 	device_set_desc(dev, "Hyper-V Vmbus");
1111 
1112 	return (BUS_PROBE_DEFAULT);
1113 }
1114 
1115 /**
1116  * @brief Main vmbus driver initialization routine.
1117  *
1118  * Here, we
1119  * - initialize the vmbus driver context
1120  * - setup various driver entry points
1121  * - invoke the vmbus hv main init routine
1122  * - get the irq resource
1123  * - invoke the vmbus to add the vmbus root device
1124  * - setup the vmbus root device
1125  * - retrieve the channel offers
1126  */
1127 static int
1128 vmbus_doattach(struct vmbus_softc *sc)
1129 {
1130 	struct sysctl_oid_list *child;
1131 	struct sysctl_ctx_list *ctx;
1132 	int ret;
1133 
1134 	if (sc->vmbus_flags & VMBUS_FLAG_ATTACHED)
1135 		return (0);
1136 	sc->vmbus_flags |= VMBUS_FLAG_ATTACHED;
1137 
1138 	mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF);
1139 	sc->vmbus_gpadl = VMBUS_GPADL_START;
1140 	mtx_init(&sc->vmbus_prichan_lock, "vmbus prichan", NULL, MTX_DEF);
1141 	TAILQ_INIT(&sc->vmbus_prichans);
1142 	sc->vmbus_chmap = malloc(
1143 	    sizeof(struct hv_vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF,
1144 	    M_WAITOK | M_ZERO);
1145 
1146 	/*
1147 	 * Create context for "post message" Hypercalls
1148 	 */
1149 	sc->vmbus_msg_hc = vmbus_msghc_ctx_create(
1150 	    bus_get_dma_tag(sc->vmbus_dev));
1151 	if (sc->vmbus_msg_hc == NULL) {
1152 		ret = ENXIO;
1153 		goto cleanup;
1154 	}
1155 
1156 	/*
1157 	 * Allocate DMA stuffs.
1158 	 */
1159 	ret = vmbus_dma_alloc(sc);
1160 	if (ret != 0)
1161 		goto cleanup;
1162 
1163 	/*
1164 	 * Setup interrupt.
1165 	 */
1166 	ret = vmbus_intr_setup(sc);
1167 	if (ret != 0)
1168 		goto cleanup;
1169 
1170 	/*
1171 	 * Setup SynIC.
1172 	 */
1173 	if (bootverbose)
1174 		device_printf(sc->vmbus_dev, "smp_started = %d\n", smp_started);
1175 	smp_rendezvous(NULL, vmbus_synic_setup, NULL, sc);
1176 	sc->vmbus_flags |= VMBUS_FLAG_SYNIC;
1177 
1178 	/*
1179 	 * Initialize vmbus, e.g. connect to Hypervisor.
1180 	 */
1181 	ret = vmbus_init(sc);
1182 	if (ret != 0)
1183 		goto cleanup;
1184 
1185 	if (sc->vmbus_version == VMBUS_VERSION_WS2008 ||
1186 	    sc->vmbus_version == VMBUS_VERSION_WIN7)
1187 		sc->vmbus_event_proc = vmbus_event_proc_compat;
1188 	else
1189 		sc->vmbus_event_proc = vmbus_event_proc;
1190 
1191 	ret = vmbus_scan(sc);
1192 	if (ret != 0)
1193 		goto cleanup;
1194 
1195 	ctx = device_get_sysctl_ctx(sc->vmbus_dev);
1196 	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vmbus_dev));
1197 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "version",
1198 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
1199 	    vmbus_sysctl_version, "A", "vmbus version");
1200 
1201 	return (ret);
1202 
1203 cleanup:
1204 	vmbus_intr_teardown(sc);
1205 	vmbus_dma_free(sc);
1206 	if (sc->vmbus_msg_hc != NULL) {
1207 		vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc);
1208 		sc->vmbus_msg_hc = NULL;
1209 	}
1210 	free(sc->vmbus_chmap, M_DEVBUF);
1211 	mtx_destroy(&sc->vmbus_scan_lock);
1212 	mtx_destroy(&sc->vmbus_prichan_lock);
1213 
1214 	return (ret);
1215 }
1216 
1217 static void
1218 vmbus_event_proc_dummy(struct vmbus_softc *sc __unused, int cpu __unused)
1219 {
1220 }
1221 
1222 static int
1223 vmbus_attach(device_t dev)
1224 {
1225 	vmbus_sc = device_get_softc(dev);
1226 	vmbus_sc->vmbus_dev = dev;
1227 	vmbus_sc->vmbus_idtvec = -1;
1228 
1229 	/*
1230 	 * Event processing logic will be configured:
1231 	 * - After the vmbus protocol version negotiation.
1232 	 * - Before we request channel offers.
1233 	 */
1234 	vmbus_sc->vmbus_event_proc = vmbus_event_proc_dummy;
1235 
1236 #ifndef EARLY_AP_STARTUP
1237 	/*
1238 	 * If the system has already booted and thread
1239 	 * scheduling is possible indicated by the global
1240 	 * cold set to zero, we just call the driver
1241 	 * initialization directly.
1242 	 */
1243 	if (!cold)
1244 #endif
1245 		vmbus_doattach(vmbus_sc);
1246 
1247 	return (0);
1248 }
1249 
1250 static void
1251 vmbus_sysinit(void *arg __unused)
1252 {
1253 	struct vmbus_softc *sc = vmbus_get_softc();
1254 
1255 	if (vm_guest != VM_GUEST_HV || sc == NULL)
1256 		return;
1257 
1258 #ifndef EARLY_AP_STARTUP
1259 	/*
1260 	 * If the system has already booted and thread
1261 	 * scheduling is possible, as indicated by the
1262 	 * global cold set to zero, we just call the driver
1263 	 * initialization directly.
1264 	 */
1265 	if (!cold)
1266 #endif
1267 		vmbus_doattach(sc);
1268 }
1269 
1270 static int
1271 vmbus_detach(device_t dev)
1272 {
1273 	struct vmbus_softc *sc = device_get_softc(dev);
1274 
1275 	vmbus_chan_destroy_all(sc);
1276 
1277 	vmbus_disconnect(sc);
1278 
1279 	if (sc->vmbus_flags & VMBUS_FLAG_SYNIC) {
1280 		sc->vmbus_flags &= ~VMBUS_FLAG_SYNIC;
1281 		smp_rendezvous(NULL, vmbus_synic_teardown, NULL, NULL);
1282 	}
1283 
1284 	vmbus_intr_teardown(sc);
1285 	vmbus_dma_free(sc);
1286 
1287 	if (sc->vmbus_msg_hc != NULL) {
1288 		vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc);
1289 		sc->vmbus_msg_hc = NULL;
1290 	}
1291 
1292 	free(sc->vmbus_chmap, M_DEVBUF);
1293 	mtx_destroy(&sc->vmbus_scan_lock);
1294 	mtx_destroy(&sc->vmbus_prichan_lock);
1295 
1296 	return (0);
1297 }
1298 
1299 static device_method_t vmbus_methods[] = {
1300 	/* Device interface */
1301 	DEVMETHOD(device_probe,			vmbus_probe),
1302 	DEVMETHOD(device_attach,		vmbus_attach),
1303 	DEVMETHOD(device_detach,		vmbus_detach),
1304 	DEVMETHOD(device_shutdown,		bus_generic_shutdown),
1305 	DEVMETHOD(device_suspend,		bus_generic_suspend),
1306 	DEVMETHOD(device_resume,		bus_generic_resume),
1307 
1308 	/* Bus interface */
1309 	DEVMETHOD(bus_add_child,		bus_generic_add_child),
1310 	DEVMETHOD(bus_print_child,		bus_generic_print_child),
1311 	DEVMETHOD(bus_read_ivar,		vmbus_read_ivar),
1312 	DEVMETHOD(bus_child_pnpinfo_str,	vmbus_child_pnpinfo_str),
1313 
1314 	/* Vmbus interface */
1315 	DEVMETHOD(vmbus_get_version,		vmbus_get_version_method),
1316 	DEVMETHOD(vmbus_probe_guid,		vmbus_probe_guid_method),
1317 
1318 	DEVMETHOD_END
1319 };
1320 
1321 static driver_t vmbus_driver = {
1322 	"vmbus",
1323 	vmbus_methods,
1324 	sizeof(struct vmbus_softc)
1325 };
1326 
1327 static devclass_t vmbus_devclass;
1328 
1329 DRIVER_MODULE(vmbus, acpi, vmbus_driver, vmbus_devclass, NULL, NULL);
1330 MODULE_DEPEND(vmbus, acpi, 1, 1, 1);
1331 MODULE_VERSION(vmbus, 1);
1332 
1333 #ifndef EARLY_AP_STARTUP
1334 /*
1335  * NOTE:
1336  * We have to start as the last step of SI_SUB_SMP, i.e. after SMP is
1337  * initialized.
1338  */
1339 SYSINIT(vmbus_initialize, SI_SUB_SMP, SI_ORDER_ANY, vmbus_sysinit, NULL);
1340 #endif
1341