xref: /freebsd/sys/dev/hyperv/vmbus/vmbus.c (revision 2c8d04d0228871c24017509cf039e7c5d97d97be)
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/hyperv_reg.h>
64 #include <dev/hyperv/vmbus/hyperv_var.h>
65 #include <dev/hyperv/vmbus/vmbus_reg.h>
66 #include <dev/hyperv/vmbus/vmbus_var.h>
67 #include <dev/hyperv/vmbus/vmbus_chanvar.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 		/* Save virtual processor id. */
730 		VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
731 	} else {
732 		/* Set virtual processor id to 0 for compatibility. */
733 		VMBUS_PCPU_GET(sc, vcpuid, cpu) = 0;
734 	}
735 
736 	/*
737 	 * Setup the SynIC message.
738 	 */
739 	orig = rdmsr(MSR_HV_SIMP);
740 	val = MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK) |
741 	    ((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
742 	     MSR_HV_SIMP_PGSHIFT);
743 	wrmsr(MSR_HV_SIMP, val);
744 
745 	/*
746 	 * Setup the SynIC event flags.
747 	 */
748 	orig = rdmsr(MSR_HV_SIEFP);
749 	val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
750 	    ((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu)
751 	      >> PAGE_SHIFT) << MSR_HV_SIEFP_PGSHIFT);
752 	wrmsr(MSR_HV_SIEFP, val);
753 
754 
755 	/*
756 	 * Configure and unmask SINT for message and event flags.
757 	 */
758 	sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
759 	orig = rdmsr(sint);
760 	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
761 	    (orig & MSR_HV_SINT_RSVD_MASK);
762 	wrmsr(sint, val);
763 
764 	/*
765 	 * Configure and unmask SINT for timer.
766 	 */
767 	sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
768 	orig = rdmsr(sint);
769 	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
770 	    (orig & MSR_HV_SINT_RSVD_MASK);
771 	wrmsr(sint, val);
772 
773 	/*
774 	 * All done; enable SynIC.
775 	 */
776 	orig = rdmsr(MSR_HV_SCONTROL);
777 	val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK);
778 	wrmsr(MSR_HV_SCONTROL, val);
779 }
780 
781 static void
782 vmbus_synic_teardown(void *arg)
783 {
784 	uint64_t orig;
785 	uint32_t sint;
786 
787 	/*
788 	 * Disable SynIC.
789 	 */
790 	orig = rdmsr(MSR_HV_SCONTROL);
791 	wrmsr(MSR_HV_SCONTROL, (orig & MSR_HV_SCTRL_RSVD_MASK));
792 
793 	/*
794 	 * Mask message and event flags SINT.
795 	 */
796 	sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
797 	orig = rdmsr(sint);
798 	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
799 
800 	/*
801 	 * Mask timer SINT.
802 	 */
803 	sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
804 	orig = rdmsr(sint);
805 	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
806 
807 	/*
808 	 * Teardown SynIC message.
809 	 */
810 	orig = rdmsr(MSR_HV_SIMP);
811 	wrmsr(MSR_HV_SIMP, (orig & MSR_HV_SIMP_RSVD_MASK));
812 
813 	/*
814 	 * Teardown SynIC event flags.
815 	 */
816 	orig = rdmsr(MSR_HV_SIEFP);
817 	wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
818 }
819 
820 static int
821 vmbus_dma_alloc(struct vmbus_softc *sc)
822 {
823 	bus_dma_tag_t parent_dtag;
824 	uint8_t *evtflags;
825 	int cpu;
826 
827 	parent_dtag = bus_get_dma_tag(sc->vmbus_dev);
828 	CPU_FOREACH(cpu) {
829 		void *ptr;
830 
831 		/*
832 		 * Per-cpu messages and event flags.
833 		 */
834 		ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
835 		    PAGE_SIZE, VMBUS_PCPU_PTR(sc, message_dma, cpu),
836 		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
837 		if (ptr == NULL)
838 			return ENOMEM;
839 		VMBUS_PCPU_GET(sc, message, cpu) = ptr;
840 
841 		ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
842 		    PAGE_SIZE, VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
843 		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
844 		if (ptr == NULL)
845 			return ENOMEM;
846 		VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
847 	}
848 
849 	evtflags = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
850 	    PAGE_SIZE, &sc->vmbus_evtflags_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
851 	if (evtflags == NULL)
852 		return ENOMEM;
853 	sc->vmbus_rx_evtflags = (u_long *)evtflags;
854 	sc->vmbus_tx_evtflags = (u_long *)(evtflags + (PAGE_SIZE / 2));
855 	sc->vmbus_evtflags = evtflags;
856 
857 	sc->vmbus_mnf1 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
858 	    PAGE_SIZE, &sc->vmbus_mnf1_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
859 	if (sc->vmbus_mnf1 == NULL)
860 		return ENOMEM;
861 
862 	sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
863 	    sizeof(struct vmbus_mnf), &sc->vmbus_mnf2_dma,
864 	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
865 	if (sc->vmbus_mnf2 == NULL)
866 		return ENOMEM;
867 
868 	return 0;
869 }
870 
871 static void
872 vmbus_dma_free(struct vmbus_softc *sc)
873 {
874 	int cpu;
875 
876 	if (sc->vmbus_evtflags != NULL) {
877 		hyperv_dmamem_free(&sc->vmbus_evtflags_dma, sc->vmbus_evtflags);
878 		sc->vmbus_evtflags = NULL;
879 		sc->vmbus_rx_evtflags = NULL;
880 		sc->vmbus_tx_evtflags = NULL;
881 	}
882 	if (sc->vmbus_mnf1 != NULL) {
883 		hyperv_dmamem_free(&sc->vmbus_mnf1_dma, sc->vmbus_mnf1);
884 		sc->vmbus_mnf1 = NULL;
885 	}
886 	if (sc->vmbus_mnf2 != NULL) {
887 		hyperv_dmamem_free(&sc->vmbus_mnf2_dma, sc->vmbus_mnf2);
888 		sc->vmbus_mnf2 = NULL;
889 	}
890 
891 	CPU_FOREACH(cpu) {
892 		if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) {
893 			hyperv_dmamem_free(
894 			    VMBUS_PCPU_PTR(sc, message_dma, cpu),
895 			    VMBUS_PCPU_GET(sc, message, cpu));
896 			VMBUS_PCPU_GET(sc, message, cpu) = NULL;
897 		}
898 		if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) {
899 			hyperv_dmamem_free(
900 			    VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
901 			    VMBUS_PCPU_GET(sc, event_flags, cpu));
902 			VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL;
903 		}
904 	}
905 }
906 
907 static int
908 vmbus_intr_setup(struct vmbus_softc *sc)
909 {
910 	int cpu;
911 
912 	CPU_FOREACH(cpu) {
913 		char buf[MAXCOMLEN + 1];
914 		cpuset_t cpu_mask;
915 
916 		/* Allocate an interrupt counter for Hyper-V interrupt */
917 		snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
918 		intrcnt_add(buf, VMBUS_PCPU_PTR(sc, intr_cnt, cpu));
919 
920 		/*
921 		 * Setup taskqueue to handle events.  Task will be per-
922 		 * channel.
923 		 */
924 		VMBUS_PCPU_GET(sc, event_tq, cpu) = taskqueue_create_fast(
925 		    "hyperv event", M_WAITOK, taskqueue_thread_enqueue,
926 		    VMBUS_PCPU_PTR(sc, event_tq, cpu));
927 		CPU_SETOF(cpu, &cpu_mask);
928 		taskqueue_start_threads_cpuset(
929 		    VMBUS_PCPU_PTR(sc, event_tq, cpu), 1, PI_NET, &cpu_mask,
930 		    "hvevent%d", cpu);
931 
932 		/*
933 		 * Setup tasks and taskqueues to handle messages.
934 		 */
935 		VMBUS_PCPU_GET(sc, message_tq, cpu) = taskqueue_create_fast(
936 		    "hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
937 		    VMBUS_PCPU_PTR(sc, message_tq, cpu));
938 		CPU_SETOF(cpu, &cpu_mask);
939 		taskqueue_start_threads_cpuset(
940 		    VMBUS_PCPU_PTR(sc, message_tq, cpu), 1, PI_NET, &cpu_mask,
941 		    "hvmsg%d", cpu);
942 		TASK_INIT(VMBUS_PCPU_PTR(sc, message_task, cpu), 0,
943 		    vmbus_msg_task, sc);
944 	}
945 
946 	/*
947 	 * All Hyper-V ISR required resources are setup, now let's find a
948 	 * free IDT vector for Hyper-V ISR and set it up.
949 	 */
950 	sc->vmbus_idtvec = lapic_ipi_alloc(IDTVEC(vmbus_isr));
951 	if (sc->vmbus_idtvec < 0) {
952 		device_printf(sc->vmbus_dev, "cannot find free IDT vector\n");
953 		return ENXIO;
954 	}
955 	if(bootverbose) {
956 		device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n",
957 		    sc->vmbus_idtvec);
958 	}
959 	return 0;
960 }
961 
962 static void
963 vmbus_intr_teardown(struct vmbus_softc *sc)
964 {
965 	int cpu;
966 
967 	if (sc->vmbus_idtvec >= 0) {
968 		lapic_ipi_free(sc->vmbus_idtvec);
969 		sc->vmbus_idtvec = -1;
970 	}
971 
972 	CPU_FOREACH(cpu) {
973 		if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) {
974 			taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu));
975 			VMBUS_PCPU_GET(sc, event_tq, cpu) = NULL;
976 		}
977 		if (VMBUS_PCPU_GET(sc, message_tq, cpu) != NULL) {
978 			taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu),
979 			    VMBUS_PCPU_PTR(sc, message_task, cpu));
980 			taskqueue_free(VMBUS_PCPU_GET(sc, message_tq, cpu));
981 			VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL;
982 		}
983 	}
984 }
985 
986 static int
987 vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
988 {
989 	return (ENOENT);
990 }
991 
992 static int
993 vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen)
994 {
995 	const struct vmbus_channel *chan;
996 	char guidbuf[HYPERV_GUID_STRLEN];
997 
998 	chan = vmbus_get_channel(child);
999 	if (chan == NULL) {
1000 		/* Event timer device, which does not belong to a channel */
1001 		return (0);
1002 	}
1003 
1004 	strlcat(buf, "classid=", buflen);
1005 	hyperv_guid2str(&chan->ch_guid_type, guidbuf, sizeof(guidbuf));
1006 	strlcat(buf, guidbuf, buflen);
1007 
1008 	strlcat(buf, " deviceid=", buflen);
1009 	hyperv_guid2str(&chan->ch_guid_inst, guidbuf, sizeof(guidbuf));
1010 	strlcat(buf, guidbuf, buflen);
1011 
1012 	return (0);
1013 }
1014 
1015 int
1016 vmbus_add_child(struct vmbus_channel *chan)
1017 {
1018 	struct vmbus_softc *sc = chan->ch_vmbus;
1019 	device_t parent = sc->vmbus_dev;
1020 	int error = 0;
1021 
1022 	/* New channel has been offered */
1023 	vmbus_scan_newchan(sc);
1024 
1025 	chan->ch_dev = device_add_child(parent, NULL, -1);
1026 	if (chan->ch_dev == NULL) {
1027 		device_printf(parent, "device_add_child for chan%u failed\n",
1028 		    chan->ch_id);
1029 		error = ENXIO;
1030 		goto done;
1031 	}
1032 	device_set_ivars(chan->ch_dev, chan);
1033 
1034 done:
1035 	/* New device has been/should be added to vmbus. */
1036 	vmbus_scan_newdev(sc);
1037 	return error;
1038 }
1039 
1040 int
1041 vmbus_delete_child(struct vmbus_channel *chan)
1042 {
1043 	int error;
1044 
1045 	if (chan->ch_dev == NULL) {
1046 		/* Failed to add a device. */
1047 		return 0;
1048 	}
1049 
1050 	/*
1051 	 * XXXKYS: Ensure that this is the opposite of
1052 	 * device_add_child()
1053 	 */
1054 	mtx_lock(&Giant);
1055 	error = device_delete_child(chan->ch_vmbus->vmbus_dev, chan->ch_dev);
1056 	mtx_unlock(&Giant);
1057 
1058 	return error;
1059 }
1060 
1061 static int
1062 vmbus_sysctl_version(SYSCTL_HANDLER_ARGS)
1063 {
1064 	struct vmbus_softc *sc = arg1;
1065 	char verstr[16];
1066 
1067 	snprintf(verstr, sizeof(verstr), "%u.%u",
1068 	    VMBUS_VERSION_MAJOR(sc->vmbus_version),
1069 	    VMBUS_VERSION_MINOR(sc->vmbus_version));
1070 	return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
1071 }
1072 
1073 static uint32_t
1074 vmbus_get_version_method(device_t bus, device_t dev)
1075 {
1076 	struct vmbus_softc *sc = device_get_softc(bus);
1077 
1078 	return sc->vmbus_version;
1079 }
1080 
1081 static int
1082 vmbus_probe_guid_method(device_t bus, device_t dev,
1083     const struct hyperv_guid *guid)
1084 {
1085 	const struct vmbus_channel *chan = vmbus_get_channel(dev);
1086 
1087 	if (memcmp(&chan->ch_guid_type, guid, sizeof(struct hyperv_guid)) == 0)
1088 		return 0;
1089 	return ENXIO;
1090 }
1091 
1092 static int
1093 vmbus_probe(device_t dev)
1094 {
1095 	char *id[] = { "VMBUS", NULL };
1096 
1097 	if (ACPI_ID_PROBE(device_get_parent(dev), dev, id) == NULL ||
1098 	    device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV ||
1099 	    (hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
1100 		return (ENXIO);
1101 
1102 	device_set_desc(dev, "Hyper-V Vmbus");
1103 
1104 	return (BUS_PROBE_DEFAULT);
1105 }
1106 
1107 /**
1108  * @brief Main vmbus driver initialization routine.
1109  *
1110  * Here, we
1111  * - initialize the vmbus driver context
1112  * - setup various driver entry points
1113  * - invoke the vmbus hv main init routine
1114  * - get the irq resource
1115  * - invoke the vmbus to add the vmbus root device
1116  * - setup the vmbus root device
1117  * - retrieve the channel offers
1118  */
1119 static int
1120 vmbus_doattach(struct vmbus_softc *sc)
1121 {
1122 	struct sysctl_oid_list *child;
1123 	struct sysctl_ctx_list *ctx;
1124 	int ret;
1125 
1126 	if (sc->vmbus_flags & VMBUS_FLAG_ATTACHED)
1127 		return (0);
1128 	sc->vmbus_flags |= VMBUS_FLAG_ATTACHED;
1129 
1130 	mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF);
1131 	sc->vmbus_gpadl = VMBUS_GPADL_START;
1132 	mtx_init(&sc->vmbus_prichan_lock, "vmbus prichan", NULL, MTX_DEF);
1133 	TAILQ_INIT(&sc->vmbus_prichans);
1134 	sc->vmbus_chmap = malloc(
1135 	    sizeof(struct vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF,
1136 	    M_WAITOK | M_ZERO);
1137 
1138 	/*
1139 	 * Create context for "post message" Hypercalls
1140 	 */
1141 	sc->vmbus_msg_hc = vmbus_msghc_ctx_create(
1142 	    bus_get_dma_tag(sc->vmbus_dev));
1143 	if (sc->vmbus_msg_hc == NULL) {
1144 		ret = ENXIO;
1145 		goto cleanup;
1146 	}
1147 
1148 	/*
1149 	 * Allocate DMA stuffs.
1150 	 */
1151 	ret = vmbus_dma_alloc(sc);
1152 	if (ret != 0)
1153 		goto cleanup;
1154 
1155 	/*
1156 	 * Setup interrupt.
1157 	 */
1158 	ret = vmbus_intr_setup(sc);
1159 	if (ret != 0)
1160 		goto cleanup;
1161 
1162 	/*
1163 	 * Setup SynIC.
1164 	 */
1165 	if (bootverbose)
1166 		device_printf(sc->vmbus_dev, "smp_started = %d\n", smp_started);
1167 	smp_rendezvous(NULL, vmbus_synic_setup, NULL, sc);
1168 	sc->vmbus_flags |= VMBUS_FLAG_SYNIC;
1169 
1170 	/*
1171 	 * Initialize vmbus, e.g. connect to Hypervisor.
1172 	 */
1173 	ret = vmbus_init(sc);
1174 	if (ret != 0)
1175 		goto cleanup;
1176 
1177 	if (sc->vmbus_version == VMBUS_VERSION_WS2008 ||
1178 	    sc->vmbus_version == VMBUS_VERSION_WIN7)
1179 		sc->vmbus_event_proc = vmbus_event_proc_compat;
1180 	else
1181 		sc->vmbus_event_proc = vmbus_event_proc;
1182 
1183 	ret = vmbus_scan(sc);
1184 	if (ret != 0)
1185 		goto cleanup;
1186 
1187 	ctx = device_get_sysctl_ctx(sc->vmbus_dev);
1188 	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vmbus_dev));
1189 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "version",
1190 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
1191 	    vmbus_sysctl_version, "A", "vmbus version");
1192 
1193 	return (ret);
1194 
1195 cleanup:
1196 	vmbus_intr_teardown(sc);
1197 	vmbus_dma_free(sc);
1198 	if (sc->vmbus_msg_hc != NULL) {
1199 		vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc);
1200 		sc->vmbus_msg_hc = NULL;
1201 	}
1202 	free(sc->vmbus_chmap, M_DEVBUF);
1203 	mtx_destroy(&sc->vmbus_scan_lock);
1204 	mtx_destroy(&sc->vmbus_prichan_lock);
1205 
1206 	return (ret);
1207 }
1208 
1209 static void
1210 vmbus_event_proc_dummy(struct vmbus_softc *sc __unused, int cpu __unused)
1211 {
1212 }
1213 
1214 static int
1215 vmbus_attach(device_t dev)
1216 {
1217 	vmbus_sc = device_get_softc(dev);
1218 	vmbus_sc->vmbus_dev = dev;
1219 	vmbus_sc->vmbus_idtvec = -1;
1220 
1221 	/*
1222 	 * Event processing logic will be configured:
1223 	 * - After the vmbus protocol version negotiation.
1224 	 * - Before we request channel offers.
1225 	 */
1226 	vmbus_sc->vmbus_event_proc = vmbus_event_proc_dummy;
1227 
1228 #ifndef EARLY_AP_STARTUP
1229 	/*
1230 	 * If the system has already booted and thread
1231 	 * scheduling is possible indicated by the global
1232 	 * cold set to zero, we just call the driver
1233 	 * initialization directly.
1234 	 */
1235 	if (!cold)
1236 #endif
1237 		vmbus_doattach(vmbus_sc);
1238 
1239 	return (0);
1240 }
1241 
1242 static void
1243 vmbus_sysinit(void *arg __unused)
1244 {
1245 	struct vmbus_softc *sc = vmbus_get_softc();
1246 
1247 	if (vm_guest != VM_GUEST_HV || sc == NULL)
1248 		return;
1249 
1250 #ifndef EARLY_AP_STARTUP
1251 	/*
1252 	 * If the system has already booted and thread
1253 	 * scheduling is possible, as indicated by the
1254 	 * global cold set to zero, we just call the driver
1255 	 * initialization directly.
1256 	 */
1257 	if (!cold)
1258 #endif
1259 		vmbus_doattach(sc);
1260 }
1261 
1262 static int
1263 vmbus_detach(device_t dev)
1264 {
1265 	struct vmbus_softc *sc = device_get_softc(dev);
1266 
1267 	vmbus_chan_destroy_all(sc);
1268 
1269 	vmbus_disconnect(sc);
1270 
1271 	if (sc->vmbus_flags & VMBUS_FLAG_SYNIC) {
1272 		sc->vmbus_flags &= ~VMBUS_FLAG_SYNIC;
1273 		smp_rendezvous(NULL, vmbus_synic_teardown, NULL, NULL);
1274 	}
1275 
1276 	vmbus_intr_teardown(sc);
1277 	vmbus_dma_free(sc);
1278 
1279 	if (sc->vmbus_msg_hc != NULL) {
1280 		vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc);
1281 		sc->vmbus_msg_hc = NULL;
1282 	}
1283 
1284 	free(sc->vmbus_chmap, M_DEVBUF);
1285 	mtx_destroy(&sc->vmbus_scan_lock);
1286 	mtx_destroy(&sc->vmbus_prichan_lock);
1287 
1288 	return (0);
1289 }
1290 
1291 static device_method_t vmbus_methods[] = {
1292 	/* Device interface */
1293 	DEVMETHOD(device_probe,			vmbus_probe),
1294 	DEVMETHOD(device_attach,		vmbus_attach),
1295 	DEVMETHOD(device_detach,		vmbus_detach),
1296 	DEVMETHOD(device_shutdown,		bus_generic_shutdown),
1297 	DEVMETHOD(device_suspend,		bus_generic_suspend),
1298 	DEVMETHOD(device_resume,		bus_generic_resume),
1299 
1300 	/* Bus interface */
1301 	DEVMETHOD(bus_add_child,		bus_generic_add_child),
1302 	DEVMETHOD(bus_print_child,		bus_generic_print_child),
1303 	DEVMETHOD(bus_read_ivar,		vmbus_read_ivar),
1304 	DEVMETHOD(bus_child_pnpinfo_str,	vmbus_child_pnpinfo_str),
1305 
1306 	/* Vmbus interface */
1307 	DEVMETHOD(vmbus_get_version,		vmbus_get_version_method),
1308 	DEVMETHOD(vmbus_probe_guid,		vmbus_probe_guid_method),
1309 
1310 	DEVMETHOD_END
1311 };
1312 
1313 static driver_t vmbus_driver = {
1314 	"vmbus",
1315 	vmbus_methods,
1316 	sizeof(struct vmbus_softc)
1317 };
1318 
1319 static devclass_t vmbus_devclass;
1320 
1321 DRIVER_MODULE(vmbus, acpi, vmbus_driver, vmbus_devclass, NULL, NULL);
1322 MODULE_DEPEND(vmbus, acpi, 1, 1, 1);
1323 MODULE_VERSION(vmbus, 1);
1324 
1325 #ifndef EARLY_AP_STARTUP
1326 /*
1327  * NOTE:
1328  * We have to start as the last step of SI_SUB_SMP, i.e. after SMP is
1329  * initialized.
1330  */
1331 SYSINIT(vmbus_initialize, SI_SUB_SMP, SI_ORDER_ANY, vmbus_sysinit, NULL);
1332 #endif
1333