vmbus.c revision 318393
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: stable/10/sys/dev/hyperv/vmbus/vmbus.c 318393 2017-05-17 02:40:06Z sephe $");
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/mutex.h>
42#include <sys/proc.h>
43#include <sys/smp.h>
44#include <sys/sysctl.h>
45#include <sys/systm.h>
46#include <sys/taskqueue.h>
47
48#include <machine/bus.h>
49#include <machine/intr_machdep.h>
50#include <machine/resource.h>
51#include <machine/apicvar.h>
52#include <machine/md_var.h>
53
54#include <contrib/dev/acpica/include/acpi.h>
55#include <dev/acpica/acpivar.h>
56
57#include <dev/hyperv/include/hyperv.h>
58#include <dev/hyperv/include/vmbus_xact.h>
59#include <dev/hyperv/vmbus/hyperv_reg.h>
60#include <dev/hyperv/vmbus/hyperv_var.h>
61#include <dev/hyperv/vmbus/vmbus_reg.h>
62#include <dev/hyperv/vmbus/vmbus_var.h>
63#include <dev/hyperv/vmbus/vmbus_chanvar.h>
64
65#include "acpi_if.h"
66#include "pcib_if.h"
67#include "vmbus_if.h"
68
69#define VMBUS_GPADL_START		0xe1e10
70
71struct vmbus_msghc {
72	struct vmbus_xact		*mh_xact;
73	struct hypercall_postmsg_in	mh_inprm_save;
74};
75
76static void			vmbus_identify(driver_t *, device_t);
77static int			vmbus_probe(device_t);
78static int			vmbus_attach(device_t);
79static int			vmbus_detach(device_t);
80static int			vmbus_read_ivar(device_t, device_t, int,
81				    uintptr_t *);
82static int			vmbus_child_pnpinfo_str(device_t, device_t,
83				    char *, size_t);
84static struct resource		*vmbus_alloc_resource(device_t dev,
85				    device_t child, int type, int *rid,
86				    rman_res_t start, rman_res_t end,
87				    rman_res_t count, u_int flags);
88static int			vmbus_alloc_msi(device_t bus, device_t dev,
89				    int count, int maxcount, int *irqs);
90static int			vmbus_release_msi(device_t bus, device_t dev,
91				    int count, int *irqs);
92static int			vmbus_alloc_msix(device_t bus, device_t dev,
93				    int *irq);
94static int			vmbus_release_msix(device_t bus, device_t dev,
95				    int irq);
96static int			vmbus_map_msi(device_t bus, device_t dev,
97				    int irq, uint64_t *addr, uint32_t *data);
98static uint32_t			vmbus_get_version_method(device_t, device_t);
99static int			vmbus_probe_guid_method(device_t, device_t,
100				    const struct hyperv_guid *);
101static uint32_t			vmbus_get_vcpu_id_method(device_t bus,
102				    device_t dev, int cpu);
103static struct taskqueue		*vmbus_get_eventtq_method(device_t, device_t,
104				    int);
105
106static int			vmbus_init(struct vmbus_softc *);
107static int			vmbus_connect(struct vmbus_softc *, uint32_t);
108static int			vmbus_req_channels(struct vmbus_softc *sc);
109static void			vmbus_disconnect(struct vmbus_softc *);
110static int			vmbus_scan(struct vmbus_softc *);
111static void			vmbus_scan_teardown(struct vmbus_softc *);
112static void			vmbus_scan_done(struct vmbus_softc *,
113				    const struct vmbus_message *);
114static void			vmbus_chanmsg_handle(struct vmbus_softc *,
115				    const struct vmbus_message *);
116static void			vmbus_msg_task(void *, int);
117static void			vmbus_synic_setup(void *);
118static void			vmbus_synic_teardown(void *);
119static int			vmbus_sysctl_version(SYSCTL_HANDLER_ARGS);
120static int			vmbus_dma_alloc(struct vmbus_softc *);
121static void			vmbus_dma_free(struct vmbus_softc *);
122static int			vmbus_intr_setup(struct vmbus_softc *);
123static void			vmbus_intr_teardown(struct vmbus_softc *);
124static int			vmbus_doattach(struct vmbus_softc *);
125static void			vmbus_event_proc_dummy(struct vmbus_softc *,
126				    int);
127
128static struct vmbus_softc	*vmbus_sc;
129
130extern inthand_t IDTVEC(rsvd), IDTVEC(vmbus_isr);
131
132static const uint32_t		vmbus_version[] = {
133	VMBUS_VERSION_WIN8_1,
134	VMBUS_VERSION_WIN8,
135	VMBUS_VERSION_WIN7,
136	VMBUS_VERSION_WS2008
137};
138
139static const vmbus_chanmsg_proc_t
140vmbus_chanmsg_handlers[VMBUS_CHANMSG_TYPE_MAX] = {
141	VMBUS_CHANMSG_PROC(CHOFFER_DONE, vmbus_scan_done),
142	VMBUS_CHANMSG_PROC_WAKEUP(CONNECT_RESP)
143};
144
145static device_method_t vmbus_methods[] = {
146	/* Device interface */
147	DEVMETHOD(device_identify,		vmbus_identify),
148	DEVMETHOD(device_probe,			vmbus_probe),
149	DEVMETHOD(device_attach,		vmbus_attach),
150	DEVMETHOD(device_detach,		vmbus_detach),
151	DEVMETHOD(device_shutdown,		bus_generic_shutdown),
152	DEVMETHOD(device_suspend,		bus_generic_suspend),
153	DEVMETHOD(device_resume,		bus_generic_resume),
154
155	/* Bus interface */
156	DEVMETHOD(bus_add_child,		bus_generic_add_child),
157	DEVMETHOD(bus_print_child,		bus_generic_print_child),
158	DEVMETHOD(bus_read_ivar,		vmbus_read_ivar),
159	DEVMETHOD(bus_child_pnpinfo_str,	vmbus_child_pnpinfo_str),
160	DEVMETHOD(bus_alloc_resource,		vmbus_alloc_resource),
161	DEVMETHOD(bus_release_resource,		bus_generic_release_resource),
162	DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
163	DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
164	DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
165	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
166#if __FreeBSD_version >= 1100000
167	DEVMETHOD(bus_get_cpus,			bus_generic_get_cpus),
168#endif
169
170	/* pcib interface */
171	DEVMETHOD(pcib_alloc_msi,		vmbus_alloc_msi),
172	DEVMETHOD(pcib_release_msi,		vmbus_release_msi),
173	DEVMETHOD(pcib_alloc_msix,		vmbus_alloc_msix),
174	DEVMETHOD(pcib_release_msix,		vmbus_release_msix),
175	DEVMETHOD(pcib_map_msi,			vmbus_map_msi),
176
177	/* Vmbus interface */
178	DEVMETHOD(vmbus_get_version,		vmbus_get_version_method),
179	DEVMETHOD(vmbus_probe_guid,		vmbus_probe_guid_method),
180	DEVMETHOD(vmbus_get_vcpu_id,		vmbus_get_vcpu_id_method),
181	DEVMETHOD(vmbus_get_event_taskq,	vmbus_get_eventtq_method),
182
183	DEVMETHOD_END
184};
185
186static driver_t vmbus_driver = {
187	"vmbus",
188	vmbus_methods,
189	sizeof(struct vmbus_softc)
190};
191
192static devclass_t vmbus_devclass;
193
194DRIVER_MODULE(vmbus, pcib, vmbus_driver, vmbus_devclass, NULL, NULL);
195DRIVER_MODULE(vmbus, acpi_syscontainer, vmbus_driver, vmbus_devclass,
196    NULL, NULL);
197
198MODULE_DEPEND(vmbus, acpi, 1, 1, 1);
199MODULE_DEPEND(vmbus, pci, 1, 1, 1);
200MODULE_VERSION(vmbus, 1);
201
202static __inline struct vmbus_softc *
203vmbus_get_softc(void)
204{
205	return vmbus_sc;
206}
207
208void
209vmbus_msghc_reset(struct vmbus_msghc *mh, size_t dsize)
210{
211	struct hypercall_postmsg_in *inprm;
212
213	if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX)
214		panic("invalid data size %zu", dsize);
215
216	inprm = vmbus_xact_req_data(mh->mh_xact);
217	memset(inprm, 0, HYPERCALL_POSTMSGIN_SIZE);
218	inprm->hc_connid = VMBUS_CONNID_MESSAGE;
219	inprm->hc_msgtype = HYPERV_MSGTYPE_CHANNEL;
220	inprm->hc_dsize = dsize;
221}
222
223struct vmbus_msghc *
224vmbus_msghc_get(struct vmbus_softc *sc, size_t dsize)
225{
226	struct vmbus_msghc *mh;
227	struct vmbus_xact *xact;
228
229	if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX)
230		panic("invalid data size %zu", dsize);
231
232	xact = vmbus_xact_get(sc->vmbus_xc,
233	    dsize + __offsetof(struct hypercall_postmsg_in, hc_data[0]));
234	if (xact == NULL)
235		return (NULL);
236
237	mh = vmbus_xact_priv(xact, sizeof(*mh));
238	mh->mh_xact = xact;
239
240	vmbus_msghc_reset(mh, dsize);
241	return (mh);
242}
243
244void
245vmbus_msghc_put(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
246{
247
248	vmbus_xact_put(mh->mh_xact);
249}
250
251void *
252vmbus_msghc_dataptr(struct vmbus_msghc *mh)
253{
254	struct hypercall_postmsg_in *inprm;
255
256	inprm = vmbus_xact_req_data(mh->mh_xact);
257	return (inprm->hc_data);
258}
259
260int
261vmbus_msghc_exec_noresult(struct vmbus_msghc *mh)
262{
263	sbintime_t time = SBT_1MS;
264	struct hypercall_postmsg_in *inprm;
265	bus_addr_t inprm_paddr;
266	int i;
267
268	inprm = vmbus_xact_req_data(mh->mh_xact);
269	inprm_paddr = vmbus_xact_req_paddr(mh->mh_xact);
270
271	/*
272	 * Save the input parameter so that we could restore the input
273	 * parameter if the Hypercall failed.
274	 *
275	 * XXX
276	 * Is this really necessary?!  i.e. Will the Hypercall ever
277	 * overwrite the input parameter?
278	 */
279	memcpy(&mh->mh_inprm_save, inprm, HYPERCALL_POSTMSGIN_SIZE);
280
281	/*
282	 * In order to cope with transient failures, e.g. insufficient
283	 * resources on host side, we retry the post message Hypercall
284	 * several times.  20 retries seem sufficient.
285	 */
286#define HC_RETRY_MAX	20
287
288	for (i = 0; i < HC_RETRY_MAX; ++i) {
289		uint64_t status;
290
291		status = hypercall_post_message(inprm_paddr);
292		if (status == HYPERCALL_STATUS_SUCCESS)
293			return 0;
294
295		pause_sbt("hcpmsg", time, 0, C_HARDCLOCK);
296		if (time < SBT_1S * 2)
297			time *= 2;
298
299		/* Restore input parameter and try again */
300		memcpy(inprm, &mh->mh_inprm_save, HYPERCALL_POSTMSGIN_SIZE);
301	}
302
303#undef HC_RETRY_MAX
304
305	return EIO;
306}
307
308int
309vmbus_msghc_exec(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
310{
311	int error;
312
313	vmbus_xact_activate(mh->mh_xact);
314	error = vmbus_msghc_exec_noresult(mh);
315	if (error)
316		vmbus_xact_deactivate(mh->mh_xact);
317	return error;
318}
319
320void
321vmbus_msghc_exec_cancel(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
322{
323
324	vmbus_xact_deactivate(mh->mh_xact);
325}
326
327const struct vmbus_message *
328vmbus_msghc_wait_result(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
329{
330	size_t resp_len;
331
332	return (vmbus_xact_wait(mh->mh_xact, &resp_len));
333}
334
335const struct vmbus_message *
336vmbus_msghc_poll_result(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
337{
338	size_t resp_len;
339
340	return (vmbus_xact_poll(mh->mh_xact, &resp_len));
341}
342
343void
344vmbus_msghc_wakeup(struct vmbus_softc *sc, const struct vmbus_message *msg)
345{
346
347	vmbus_xact_ctx_wakeup(sc->vmbus_xc, msg, sizeof(*msg));
348}
349
350uint32_t
351vmbus_gpadl_alloc(struct vmbus_softc *sc)
352{
353	uint32_t gpadl;
354
355again:
356	gpadl = atomic_fetchadd_int(&sc->vmbus_gpadl, 1);
357	if (gpadl == 0)
358		goto again;
359	return (gpadl);
360}
361
362static int
363vmbus_connect(struct vmbus_softc *sc, uint32_t version)
364{
365	struct vmbus_chanmsg_connect *req;
366	const struct vmbus_message *msg;
367	struct vmbus_msghc *mh;
368	int error, done = 0;
369
370	mh = vmbus_msghc_get(sc, sizeof(*req));
371	if (mh == NULL)
372		return ENXIO;
373
374	req = vmbus_msghc_dataptr(mh);
375	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CONNECT;
376	req->chm_ver = version;
377	req->chm_evtflags = sc->vmbus_evtflags_dma.hv_paddr;
378	req->chm_mnf1 = sc->vmbus_mnf1_dma.hv_paddr;
379	req->chm_mnf2 = sc->vmbus_mnf2_dma.hv_paddr;
380
381	error = vmbus_msghc_exec(sc, mh);
382	if (error) {
383		vmbus_msghc_put(sc, mh);
384		return error;
385	}
386
387	msg = vmbus_msghc_wait_result(sc, mh);
388	done = ((const struct vmbus_chanmsg_connect_resp *)
389	    msg->msg_data)->chm_done;
390
391	vmbus_msghc_put(sc, mh);
392
393	return (done ? 0 : EOPNOTSUPP);
394}
395
396static int
397vmbus_init(struct vmbus_softc *sc)
398{
399	int i;
400
401	for (i = 0; i < nitems(vmbus_version); ++i) {
402		int error;
403
404		error = vmbus_connect(sc, vmbus_version[i]);
405		if (!error) {
406			sc->vmbus_version = vmbus_version[i];
407			device_printf(sc->vmbus_dev, "version %u.%u\n",
408			    VMBUS_VERSION_MAJOR(sc->vmbus_version),
409			    VMBUS_VERSION_MINOR(sc->vmbus_version));
410			return 0;
411		}
412	}
413	return ENXIO;
414}
415
416static void
417vmbus_disconnect(struct vmbus_softc *sc)
418{
419	struct vmbus_chanmsg_disconnect *req;
420	struct vmbus_msghc *mh;
421	int error;
422
423	mh = vmbus_msghc_get(sc, sizeof(*req));
424	if (mh == NULL) {
425		device_printf(sc->vmbus_dev,
426		    "can not get msg hypercall for disconnect\n");
427		return;
428	}
429
430	req = vmbus_msghc_dataptr(mh);
431	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_DISCONNECT;
432
433	error = vmbus_msghc_exec_noresult(mh);
434	vmbus_msghc_put(sc, mh);
435
436	if (error) {
437		device_printf(sc->vmbus_dev,
438		    "disconnect msg hypercall failed\n");
439	}
440}
441
442static int
443vmbus_req_channels(struct vmbus_softc *sc)
444{
445	struct vmbus_chanmsg_chrequest *req;
446	struct vmbus_msghc *mh;
447	int error;
448
449	mh = vmbus_msghc_get(sc, sizeof(*req));
450	if (mh == NULL)
451		return ENXIO;
452
453	req = vmbus_msghc_dataptr(mh);
454	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHREQUEST;
455
456	error = vmbus_msghc_exec_noresult(mh);
457	vmbus_msghc_put(sc, mh);
458
459	return error;
460}
461
462static void
463vmbus_scan_done_task(void *xsc, int pending __unused)
464{
465	struct vmbus_softc *sc = xsc;
466
467	mtx_lock(&Giant);
468	sc->vmbus_scandone = true;
469	mtx_unlock(&Giant);
470	wakeup(&sc->vmbus_scandone);
471}
472
473static void
474vmbus_scan_done(struct vmbus_softc *sc,
475    const struct vmbus_message *msg __unused)
476{
477
478	taskqueue_enqueue(sc->vmbus_devtq, &sc->vmbus_scandone_task);
479}
480
481static int
482vmbus_scan(struct vmbus_softc *sc)
483{
484	int error;
485
486	/*
487	 * Identify, probe and attach for non-channel devices.
488	 */
489	bus_generic_probe(sc->vmbus_dev);
490	bus_generic_attach(sc->vmbus_dev);
491
492	/*
493	 * This taskqueue serializes vmbus devices' attach and detach
494	 * for channel offer and rescind messages.
495	 */
496	sc->vmbus_devtq = taskqueue_create("vmbus dev", M_WAITOK,
497	    taskqueue_thread_enqueue, &sc->vmbus_devtq);
498	taskqueue_start_threads(&sc->vmbus_devtq, 1, PI_NET, "vmbusdev");
499	TASK_INIT(&sc->vmbus_scandone_task, 0, vmbus_scan_done_task, sc);
500
501	/*
502	 * This taskqueue handles sub-channel detach, so that vmbus
503	 * device's detach running in vmbus_devtq can drain its sub-
504	 * channels.
505	 */
506	sc->vmbus_subchtq = taskqueue_create("vmbus subch", M_WAITOK,
507	    taskqueue_thread_enqueue, &sc->vmbus_subchtq);
508	taskqueue_start_threads(&sc->vmbus_subchtq, 1, PI_NET, "vmbussch");
509
510	/*
511	 * Start vmbus scanning.
512	 */
513	error = vmbus_req_channels(sc);
514	if (error) {
515		device_printf(sc->vmbus_dev, "channel request failed: %d\n",
516		    error);
517		return (error);
518	}
519
520	/*
521	 * Wait for all vmbus devices from the initial channel offers to be
522	 * attached.
523	 */
524	GIANT_REQUIRED;
525	while (!sc->vmbus_scandone)
526		mtx_sleep(&sc->vmbus_scandone, &Giant, 0, "vmbusdev", 0);
527
528	if (bootverbose) {
529		device_printf(sc->vmbus_dev, "device scan, probe and attach "
530		    "done\n");
531	}
532	return (0);
533}
534
535static void
536vmbus_scan_teardown(struct vmbus_softc *sc)
537{
538
539	GIANT_REQUIRED;
540	if (sc->vmbus_devtq != NULL) {
541		mtx_unlock(&Giant);
542		taskqueue_free(sc->vmbus_devtq);
543		mtx_lock(&Giant);
544		sc->vmbus_devtq = NULL;
545	}
546	if (sc->vmbus_subchtq != NULL) {
547		mtx_unlock(&Giant);
548		taskqueue_free(sc->vmbus_subchtq);
549		mtx_lock(&Giant);
550		sc->vmbus_subchtq = NULL;
551	}
552}
553
554static void
555vmbus_chanmsg_handle(struct vmbus_softc *sc, const struct vmbus_message *msg)
556{
557	vmbus_chanmsg_proc_t msg_proc;
558	uint32_t msg_type;
559
560	msg_type = ((const struct vmbus_chanmsg_hdr *)msg->msg_data)->chm_type;
561	if (msg_type >= VMBUS_CHANMSG_TYPE_MAX) {
562		device_printf(sc->vmbus_dev, "unknown message type 0x%x\n",
563		    msg_type);
564		return;
565	}
566
567	msg_proc = vmbus_chanmsg_handlers[msg_type];
568	if (msg_proc != NULL)
569		msg_proc(sc, msg);
570
571	/* Channel specific processing */
572	vmbus_chan_msgproc(sc, msg);
573}
574
575static void
576vmbus_msg_task(void *xsc, int pending __unused)
577{
578	struct vmbus_softc *sc = xsc;
579	volatile struct vmbus_message *msg;
580
581	msg = VMBUS_PCPU_GET(sc, message, curcpu) + VMBUS_SINT_MESSAGE;
582	for (;;) {
583		if (msg->msg_type == HYPERV_MSGTYPE_NONE) {
584			/* No message */
585			break;
586		} else if (msg->msg_type == HYPERV_MSGTYPE_CHANNEL) {
587			/* Channel message */
588			vmbus_chanmsg_handle(sc,
589			    __DEVOLATILE(const struct vmbus_message *, msg));
590		}
591
592		msg->msg_type = HYPERV_MSGTYPE_NONE;
593		/*
594		 * Make sure the write to msg_type (i.e. set to
595		 * HYPERV_MSGTYPE_NONE) happens before we read the
596		 * msg_flags and EOMing. Otherwise, the EOMing will
597		 * not deliver any more messages since there is no
598		 * empty slot
599		 *
600		 * NOTE:
601		 * mb() is used here, since atomic_thread_fence_seq_cst()
602		 * will become compiler fence on UP kernel.
603		 */
604		mb();
605		if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
606			/*
607			 * This will cause message queue rescan to possibly
608			 * deliver another msg from the hypervisor
609			 */
610			wrmsr(MSR_HV_EOM, 0);
611		}
612	}
613}
614
615static __inline int
616vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
617{
618	volatile struct vmbus_message *msg;
619	struct vmbus_message *msg_base;
620
621	msg_base = VMBUS_PCPU_GET(sc, message, cpu);
622
623	/*
624	 * Check event timer.
625	 *
626	 * TODO: move this to independent IDT vector.
627	 */
628	msg = msg_base + VMBUS_SINT_TIMER;
629	if (msg->msg_type == HYPERV_MSGTYPE_TIMER_EXPIRED) {
630		msg->msg_type = HYPERV_MSGTYPE_NONE;
631
632		vmbus_et_intr(frame);
633
634		/*
635		 * Make sure the write to msg_type (i.e. set to
636		 * HYPERV_MSGTYPE_NONE) happens before we read the
637		 * msg_flags and EOMing. Otherwise, the EOMing will
638		 * not deliver any more messages since there is no
639		 * empty slot
640		 *
641		 * NOTE:
642		 * mb() is used here, since atomic_thread_fence_seq_cst()
643		 * will become compiler fence on UP kernel.
644		 */
645		mb();
646		if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
647			/*
648			 * This will cause message queue rescan to possibly
649			 * deliver another msg from the hypervisor
650			 */
651			wrmsr(MSR_HV_EOM, 0);
652		}
653	}
654
655	/*
656	 * Check events.  Hot path for network and storage I/O data; high rate.
657	 *
658	 * NOTE:
659	 * As recommended by the Windows guest fellows, we check events before
660	 * checking messages.
661	 */
662	sc->vmbus_event_proc(sc, cpu);
663
664	/*
665	 * Check messages.  Mainly management stuffs; ultra low rate.
666	 */
667	msg = msg_base + VMBUS_SINT_MESSAGE;
668	if (__predict_false(msg->msg_type != HYPERV_MSGTYPE_NONE)) {
669		taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu),
670		    VMBUS_PCPU_PTR(sc, message_task, cpu));
671	}
672
673	return (FILTER_HANDLED);
674}
675
676void
677vmbus_handle_intr(struct trapframe *trap_frame)
678{
679	struct vmbus_softc *sc = vmbus_get_softc();
680	int cpu = curcpu;
681
682	/*
683	 * Disable preemption.
684	 */
685	critical_enter();
686
687	/*
688	 * Do a little interrupt counting.
689	 */
690	(*VMBUS_PCPU_GET(sc, intr_cnt, cpu))++;
691
692	vmbus_handle_intr1(sc, trap_frame, cpu);
693
694	/*
695	 * Enable preemption.
696	 */
697	critical_exit();
698}
699
700static void
701vmbus_synic_setup(void *xsc)
702{
703	struct vmbus_softc *sc = xsc;
704	int cpu = curcpu;
705	uint64_t val, orig;
706	uint32_t sint;
707
708	if (hyperv_features & CPUID_HV_MSR_VP_INDEX) {
709		/* Save virtual processor id. */
710		VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
711	} else {
712		/* Set virtual processor id to 0 for compatibility. */
713		VMBUS_PCPU_GET(sc, vcpuid, cpu) = 0;
714	}
715
716	/*
717	 * Setup the SynIC message.
718	 */
719	orig = rdmsr(MSR_HV_SIMP);
720	val = MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK) |
721	    ((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
722	     MSR_HV_SIMP_PGSHIFT);
723	wrmsr(MSR_HV_SIMP, val);
724
725	/*
726	 * Setup the SynIC event flags.
727	 */
728	orig = rdmsr(MSR_HV_SIEFP);
729	val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
730	    ((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu)
731	      >> PAGE_SHIFT) << MSR_HV_SIEFP_PGSHIFT);
732	wrmsr(MSR_HV_SIEFP, val);
733
734
735	/*
736	 * Configure and unmask SINT for message and event flags.
737	 */
738	sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
739	orig = rdmsr(sint);
740	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
741	    (orig & MSR_HV_SINT_RSVD_MASK);
742	wrmsr(sint, val);
743
744	/*
745	 * Configure and unmask SINT for timer.
746	 */
747	sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
748	orig = rdmsr(sint);
749	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
750	    (orig & MSR_HV_SINT_RSVD_MASK);
751	wrmsr(sint, val);
752
753	/*
754	 * All done; enable SynIC.
755	 */
756	orig = rdmsr(MSR_HV_SCONTROL);
757	val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK);
758	wrmsr(MSR_HV_SCONTROL, val);
759}
760
761static void
762vmbus_synic_teardown(void *arg)
763{
764	uint64_t orig;
765	uint32_t sint;
766
767	/*
768	 * Disable SynIC.
769	 */
770	orig = rdmsr(MSR_HV_SCONTROL);
771	wrmsr(MSR_HV_SCONTROL, (orig & MSR_HV_SCTRL_RSVD_MASK));
772
773	/*
774	 * Mask message and event flags SINT.
775	 */
776	sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
777	orig = rdmsr(sint);
778	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
779
780	/*
781	 * Mask timer SINT.
782	 */
783	sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
784	orig = rdmsr(sint);
785	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
786
787	/*
788	 * Teardown SynIC message.
789	 */
790	orig = rdmsr(MSR_HV_SIMP);
791	wrmsr(MSR_HV_SIMP, (orig & MSR_HV_SIMP_RSVD_MASK));
792
793	/*
794	 * Teardown SynIC event flags.
795	 */
796	orig = rdmsr(MSR_HV_SIEFP);
797	wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
798}
799
800static int
801vmbus_dma_alloc(struct vmbus_softc *sc)
802{
803	bus_dma_tag_t parent_dtag;
804	uint8_t *evtflags;
805	int cpu;
806
807	parent_dtag = bus_get_dma_tag(sc->vmbus_dev);
808	CPU_FOREACH(cpu) {
809		void *ptr;
810
811		/*
812		 * Per-cpu messages and event flags.
813		 */
814		ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
815		    PAGE_SIZE, VMBUS_PCPU_PTR(sc, message_dma, cpu),
816		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
817		if (ptr == NULL)
818			return ENOMEM;
819		VMBUS_PCPU_GET(sc, message, cpu) = ptr;
820
821		ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
822		    PAGE_SIZE, VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
823		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
824		if (ptr == NULL)
825			return ENOMEM;
826		VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
827	}
828
829	evtflags = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
830	    PAGE_SIZE, &sc->vmbus_evtflags_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
831	if (evtflags == NULL)
832		return ENOMEM;
833	sc->vmbus_rx_evtflags = (u_long *)evtflags;
834	sc->vmbus_tx_evtflags = (u_long *)(evtflags + (PAGE_SIZE / 2));
835	sc->vmbus_evtflags = evtflags;
836
837	sc->vmbus_mnf1 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
838	    PAGE_SIZE, &sc->vmbus_mnf1_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
839	if (sc->vmbus_mnf1 == NULL)
840		return ENOMEM;
841
842	sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
843	    sizeof(struct vmbus_mnf), &sc->vmbus_mnf2_dma,
844	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
845	if (sc->vmbus_mnf2 == NULL)
846		return ENOMEM;
847
848	return 0;
849}
850
851static void
852vmbus_dma_free(struct vmbus_softc *sc)
853{
854	int cpu;
855
856	if (sc->vmbus_evtflags != NULL) {
857		hyperv_dmamem_free(&sc->vmbus_evtflags_dma, sc->vmbus_evtflags);
858		sc->vmbus_evtflags = NULL;
859		sc->vmbus_rx_evtflags = NULL;
860		sc->vmbus_tx_evtflags = NULL;
861	}
862	if (sc->vmbus_mnf1 != NULL) {
863		hyperv_dmamem_free(&sc->vmbus_mnf1_dma, sc->vmbus_mnf1);
864		sc->vmbus_mnf1 = NULL;
865	}
866	if (sc->vmbus_mnf2 != NULL) {
867		hyperv_dmamem_free(&sc->vmbus_mnf2_dma, sc->vmbus_mnf2);
868		sc->vmbus_mnf2 = NULL;
869	}
870
871	CPU_FOREACH(cpu) {
872		if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) {
873			hyperv_dmamem_free(
874			    VMBUS_PCPU_PTR(sc, message_dma, cpu),
875			    VMBUS_PCPU_GET(sc, message, cpu));
876			VMBUS_PCPU_GET(sc, message, cpu) = NULL;
877		}
878		if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) {
879			hyperv_dmamem_free(
880			    VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
881			    VMBUS_PCPU_GET(sc, event_flags, cpu));
882			VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL;
883		}
884	}
885}
886
887/**
888 * @brief Find a free IDT slot and setup the interrupt handler.
889 */
890static int
891vmbus_vector_alloc(void)
892{
893	int vector;
894	uintptr_t func;
895	struct gate_descriptor *ip;
896
897	/*
898	 * Search backwards form the highest IDT vector available for use
899	 * as vmbus channel callback vector. We install 'vmbus_isr'
900	 * handler at that vector and use it to interrupt vcpus.
901	 */
902	vector = APIC_SPURIOUS_INT;
903	while (--vector >= APIC_IPI_INTS) {
904		ip = &idt[vector];
905		func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset);
906		if (func == (uintptr_t)&IDTVEC(rsvd)) {
907#ifdef __i386__
908			setidt(vector , IDTVEC(vmbus_isr), SDT_SYS386IGT,
909			    SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
910#else
911			setidt(vector , IDTVEC(vmbus_isr), SDT_SYSIGT,
912			    SEL_KPL, 0);
913#endif
914
915			return (vector);
916		}
917	}
918	return (0);
919}
920
921/**
922 * @brief Restore the IDT slot to rsvd.
923 */
924static void
925vmbus_vector_free(int vector)
926{
927	uintptr_t func;
928	struct gate_descriptor *ip;
929
930	if (vector == 0)
931		return;
932
933	KASSERT(vector >= APIC_IPI_INTS && vector < APIC_SPURIOUS_INT,
934	    ("invalid vector %d", vector));
935
936	ip = &idt[vector];
937	func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset);
938	KASSERT(func == (uintptr_t)&IDTVEC(vmbus_isr),
939	    ("invalid vector %d", vector));
940
941	setidt(vector, IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0);
942}
943
944static void
945vmbus_cpuset_setthread_task(void *xmask, int pending __unused)
946{
947	cpuset_t *mask = xmask;
948	int error;
949
950	error = cpuset_setthread(curthread->td_tid, mask);
951	if (error) {
952		panic("curthread=%ju: can't pin; error=%d",
953		    (uintmax_t)curthread->td_tid, error);
954	}
955}
956
957static int
958vmbus_intr_setup(struct vmbus_softc *sc)
959{
960	int cpu;
961
962	CPU_FOREACH(cpu) {
963		struct task cpuset_task;
964		char buf[MAXCOMLEN + 1];
965		cpuset_t cpu_mask;
966
967		/* Allocate an interrupt counter for Hyper-V interrupt */
968		snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
969		intrcnt_add(buf, VMBUS_PCPU_PTR(sc, intr_cnt, cpu));
970
971		/*
972		 * Setup taskqueue to handle events.  Task will be per-
973		 * channel.
974		 */
975		VMBUS_PCPU_GET(sc, event_tq, cpu) = taskqueue_create_fast(
976		    "hyperv event", M_WAITOK, taskqueue_thread_enqueue,
977		    VMBUS_PCPU_PTR(sc, event_tq, cpu));
978		taskqueue_start_threads(VMBUS_PCPU_PTR(sc, event_tq, cpu),
979		    1, PI_NET, "hvevent%d", cpu);
980
981		CPU_SETOF(cpu, &cpu_mask);
982		TASK_INIT(&cpuset_task, 0, vmbus_cpuset_setthread_task,
983		    &cpu_mask);
984		taskqueue_enqueue(VMBUS_PCPU_GET(sc, event_tq, cpu),
985		    &cpuset_task);
986		taskqueue_drain(VMBUS_PCPU_GET(sc, event_tq, cpu),
987		    &cpuset_task);
988
989		/*
990		 * Setup tasks and taskqueues to handle messages.
991		 */
992		VMBUS_PCPU_GET(sc, message_tq, cpu) = taskqueue_create_fast(
993		    "hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
994		    VMBUS_PCPU_PTR(sc, message_tq, cpu));
995		taskqueue_start_threads(VMBUS_PCPU_PTR(sc, message_tq, cpu), 1,
996		    PI_NET, "hvmsg%d", cpu);
997		TASK_INIT(VMBUS_PCPU_PTR(sc, message_task, cpu), 0,
998		    vmbus_msg_task, sc);
999
1000		CPU_SETOF(cpu, &cpu_mask);
1001		TASK_INIT(&cpuset_task, 0, vmbus_cpuset_setthread_task,
1002		    &cpu_mask);
1003		taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu),
1004		    &cpuset_task);
1005		taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu),
1006		    &cpuset_task);
1007	}
1008
1009	/*
1010	 * All Hyper-V ISR required resources are setup, now let's find a
1011	 * free IDT vector for Hyper-V ISR and set it up.
1012	 */
1013	sc->vmbus_idtvec = vmbus_vector_alloc();
1014	if (sc->vmbus_idtvec == 0) {
1015		device_printf(sc->vmbus_dev, "cannot find free IDT vector\n");
1016		return ENXIO;
1017	}
1018	if (bootverbose) {
1019		device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n",
1020		    sc->vmbus_idtvec);
1021	}
1022	return 0;
1023}
1024
1025static void
1026vmbus_intr_teardown(struct vmbus_softc *sc)
1027{
1028	int cpu;
1029
1030	vmbus_vector_free(sc->vmbus_idtvec);
1031
1032	CPU_FOREACH(cpu) {
1033		if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) {
1034			taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu));
1035			VMBUS_PCPU_GET(sc, event_tq, cpu) = NULL;
1036		}
1037		if (VMBUS_PCPU_GET(sc, message_tq, cpu) != NULL) {
1038			taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu),
1039			    VMBUS_PCPU_PTR(sc, message_task, cpu));
1040			taskqueue_free(VMBUS_PCPU_GET(sc, message_tq, cpu));
1041			VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL;
1042		}
1043	}
1044}
1045
1046static int
1047vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
1048{
1049	return (ENOENT);
1050}
1051
1052static int
1053vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen)
1054{
1055	const struct vmbus_channel *chan;
1056	char guidbuf[HYPERV_GUID_STRLEN];
1057
1058	chan = vmbus_get_channel(child);
1059	if (chan == NULL) {
1060		/* Event timer device, which does not belong to a channel */
1061		return (0);
1062	}
1063
1064	strlcat(buf, "classid=", buflen);
1065	hyperv_guid2str(&chan->ch_guid_type, guidbuf, sizeof(guidbuf));
1066	strlcat(buf, guidbuf, buflen);
1067
1068	strlcat(buf, " deviceid=", buflen);
1069	hyperv_guid2str(&chan->ch_guid_inst, guidbuf, sizeof(guidbuf));
1070	strlcat(buf, guidbuf, buflen);
1071
1072	return (0);
1073}
1074
1075int
1076vmbus_add_child(struct vmbus_channel *chan)
1077{
1078	struct vmbus_softc *sc = chan->ch_vmbus;
1079	device_t parent = sc->vmbus_dev;
1080
1081	mtx_lock(&Giant);
1082
1083	chan->ch_dev = device_add_child(parent, NULL, -1);
1084	if (chan->ch_dev == NULL) {
1085		mtx_unlock(&Giant);
1086		device_printf(parent, "device_add_child for chan%u failed\n",
1087		    chan->ch_id);
1088		return (ENXIO);
1089	}
1090	device_set_ivars(chan->ch_dev, chan);
1091	device_probe_and_attach(chan->ch_dev);
1092
1093	mtx_unlock(&Giant);
1094	return (0);
1095}
1096
1097int
1098vmbus_delete_child(struct vmbus_channel *chan)
1099{
1100	int error = 0;
1101
1102	mtx_lock(&Giant);
1103	if (chan->ch_dev != NULL) {
1104		error = device_delete_child(chan->ch_vmbus->vmbus_dev,
1105		    chan->ch_dev);
1106		chan->ch_dev = NULL;
1107	}
1108	mtx_unlock(&Giant);
1109	return (error);
1110}
1111
1112static int
1113vmbus_sysctl_version(SYSCTL_HANDLER_ARGS)
1114{
1115	struct vmbus_softc *sc = arg1;
1116	char verstr[16];
1117
1118	snprintf(verstr, sizeof(verstr), "%u.%u",
1119	    VMBUS_VERSION_MAJOR(sc->vmbus_version),
1120	    VMBUS_VERSION_MINOR(sc->vmbus_version));
1121	return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
1122}
1123
1124/*
1125 * We need the function to make sure the MMIO resource is allocated from the
1126 * ranges found in _CRS.
1127 *
1128 * For the release function, we can use bus_generic_release_resource().
1129 */
1130static struct resource *
1131vmbus_alloc_resource(device_t dev, device_t child, int type, int *rid,
1132    rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
1133{
1134	device_t parent = device_get_parent(dev);
1135	struct resource *res;
1136
1137#ifdef NEW_PCIB
1138	if (type == SYS_RES_MEMORY) {
1139		struct vmbus_softc *sc = device_get_softc(dev);
1140
1141		res = pcib_host_res_alloc(&sc->vmbus_mmio_res, child, type,
1142		    rid, start, end, count, flags);
1143	} else
1144#endif
1145	{
1146		res = BUS_ALLOC_RESOURCE(parent, child, type, rid, start,
1147		    end, count, flags);
1148	}
1149
1150	return (res);
1151}
1152
1153static int
1154vmbus_alloc_msi(device_t bus, device_t dev, int count, int maxcount, int *irqs)
1155{
1156
1157	return (PCIB_ALLOC_MSI(device_get_parent(bus), dev, count, maxcount,
1158	    irqs));
1159}
1160
1161static int
1162vmbus_release_msi(device_t bus, device_t dev, int count, int *irqs)
1163{
1164
1165	return (PCIB_RELEASE_MSI(device_get_parent(bus), dev, count, irqs));
1166}
1167
1168static int
1169vmbus_alloc_msix(device_t bus, device_t dev, int *irq)
1170{
1171
1172	return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq));
1173}
1174
1175static int
1176vmbus_release_msix(device_t bus, device_t dev, int irq)
1177{
1178
1179	return (PCIB_RELEASE_MSIX(device_get_parent(bus), dev, irq));
1180}
1181
1182static int
1183vmbus_map_msi(device_t bus, device_t dev, int irq, uint64_t *addr,
1184	uint32_t *data)
1185{
1186
1187	return (PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data));
1188}
1189
1190static uint32_t
1191vmbus_get_version_method(device_t bus, device_t dev)
1192{
1193	struct vmbus_softc *sc = device_get_softc(bus);
1194
1195	return sc->vmbus_version;
1196}
1197
1198static int
1199vmbus_probe_guid_method(device_t bus, device_t dev,
1200    const struct hyperv_guid *guid)
1201{
1202	const struct vmbus_channel *chan = vmbus_get_channel(dev);
1203
1204	if (memcmp(&chan->ch_guid_type, guid, sizeof(struct hyperv_guid)) == 0)
1205		return 0;
1206	return ENXIO;
1207}
1208
1209static uint32_t
1210vmbus_get_vcpu_id_method(device_t bus, device_t dev, int cpu)
1211{
1212	const struct vmbus_softc *sc = device_get_softc(bus);
1213
1214	return (VMBUS_PCPU_GET(sc, vcpuid, cpu));
1215}
1216
1217static struct taskqueue *
1218vmbus_get_eventtq_method(device_t bus, device_t dev __unused, int cpu)
1219{
1220	const struct vmbus_softc *sc = device_get_softc(bus);
1221
1222	KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpu%d", cpu));
1223	return (VMBUS_PCPU_GET(sc, event_tq, cpu));
1224}
1225
1226#ifdef NEW_PCIB
1227#define VTPM_BASE_ADDR 0xfed40000
1228#define FOUR_GB (1ULL << 32)
1229
1230enum parse_pass { parse_64, parse_32 };
1231
1232struct parse_context {
1233	device_t vmbus_dev;
1234	enum parse_pass pass;
1235};
1236
1237static ACPI_STATUS
1238parse_crs(ACPI_RESOURCE *res, void *ctx)
1239{
1240	const struct parse_context *pc = ctx;
1241	device_t vmbus_dev = pc->vmbus_dev;
1242
1243	struct vmbus_softc *sc = device_get_softc(vmbus_dev);
1244	UINT64 start, end;
1245
1246	switch (res->Type) {
1247	case ACPI_RESOURCE_TYPE_ADDRESS32:
1248		start = res->Data.Address32.Address.Minimum;
1249		end = res->Data.Address32.Address.Maximum;
1250		break;
1251
1252	case ACPI_RESOURCE_TYPE_ADDRESS64:
1253		start = res->Data.Address64.Address.Minimum;
1254		end = res->Data.Address64.Address.Maximum;
1255		break;
1256
1257	default:
1258		/* Unused types. */
1259		return (AE_OK);
1260	}
1261
1262	/*
1263	 * We don't use <1MB addresses.
1264	 */
1265	if (end < 0x100000)
1266		return (AE_OK);
1267
1268	/* Don't conflict with vTPM. */
1269	if (end >= VTPM_BASE_ADDR && start < VTPM_BASE_ADDR)
1270		end = VTPM_BASE_ADDR - 1;
1271
1272	if ((pc->pass == parse_32 && start < FOUR_GB) ||
1273	    (pc->pass == parse_64 && start >= FOUR_GB))
1274		pcib_host_res_decodes(&sc->vmbus_mmio_res, SYS_RES_MEMORY,
1275		    start, end, 0);
1276
1277	return (AE_OK);
1278}
1279
1280static void
1281vmbus_get_crs(device_t dev, device_t vmbus_dev, enum parse_pass pass)
1282{
1283	struct parse_context pc;
1284	ACPI_STATUS status;
1285
1286	if (bootverbose)
1287		device_printf(dev, "walking _CRS, pass=%d\n", pass);
1288
1289	pc.vmbus_dev = vmbus_dev;
1290	pc.pass = pass;
1291	status = AcpiWalkResources(acpi_get_handle(dev), "_CRS",
1292			parse_crs, &pc);
1293
1294	if (bootverbose && ACPI_FAILURE(status))
1295		device_printf(dev, "_CRS: not found, pass=%d\n", pass);
1296}
1297
1298static void
1299vmbus_get_mmio_res_pass(device_t dev, enum parse_pass pass)
1300{
1301	device_t acpi0, parent;
1302
1303	parent = device_get_parent(dev);
1304
1305	acpi0 = device_get_parent(parent);
1306	if (strcmp("acpi0", device_get_nameunit(acpi0)) == 0) {
1307		device_t *children;
1308		int count;
1309
1310		/*
1311		 * Try to locate VMBUS resources and find _CRS on them.
1312		 */
1313		if (device_get_children(acpi0, &children, &count) == 0) {
1314			int i;
1315
1316			for (i = 0; i < count; ++i) {
1317				if (!device_is_attached(children[i]))
1318					continue;
1319
1320				if (strcmp("vmbus_res",
1321				    device_get_name(children[i])) == 0)
1322					vmbus_get_crs(children[i], dev, pass);
1323			}
1324			free(children, M_TEMP);
1325		}
1326
1327		/*
1328		 * Try to find _CRS on acpi.
1329		 */
1330		vmbus_get_crs(acpi0, dev, pass);
1331	} else {
1332		device_printf(dev, "not grandchild of acpi\n");
1333	}
1334
1335	/*
1336	 * Try to find _CRS on parent.
1337	 */
1338	vmbus_get_crs(parent, dev, pass);
1339}
1340
1341static void
1342vmbus_get_mmio_res(device_t dev)
1343{
1344	struct vmbus_softc *sc = device_get_softc(dev);
1345	/*
1346	 * We walk the resources twice to make sure that: in the resource
1347	 * list, the 32-bit resources appear behind the 64-bit resources.
1348	 * NB: resource_list_add() uses INSERT_TAIL. This way, when we
1349	 * iterate through the list to find a range for a 64-bit BAR in
1350	 * vmbus_alloc_resource(), we can make sure we try to use >4GB
1351	 * ranges first.
1352	 */
1353	pcib_host_res_init(dev, &sc->vmbus_mmio_res);
1354
1355	vmbus_get_mmio_res_pass(dev, parse_64);
1356	vmbus_get_mmio_res_pass(dev, parse_32);
1357}
1358
1359static void
1360vmbus_free_mmio_res(device_t dev)
1361{
1362	struct vmbus_softc *sc = device_get_softc(dev);
1363
1364	pcib_host_res_free(dev, &sc->vmbus_mmio_res);
1365}
1366#endif	/* NEW_PCIB */
1367
1368static void
1369vmbus_identify(driver_t *driver, device_t parent)
1370{
1371
1372	if (device_get_unit(parent) != 0 || vm_guest != VM_GUEST_HV ||
1373	    (hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
1374		return;
1375	device_add_child(parent, "vmbus", -1);
1376}
1377
1378static int
1379vmbus_probe(device_t dev)
1380{
1381
1382	if (device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV ||
1383	    (hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
1384		return (ENXIO);
1385
1386	device_set_desc(dev, "Hyper-V Vmbus");
1387	return (BUS_PROBE_DEFAULT);
1388}
1389
1390/**
1391 * @brief Main vmbus driver initialization routine.
1392 *
1393 * Here, we
1394 * - initialize the vmbus driver context
1395 * - setup various driver entry points
1396 * - invoke the vmbus hv main init routine
1397 * - get the irq resource
1398 * - invoke the vmbus to add the vmbus root device
1399 * - setup the vmbus root device
1400 * - retrieve the channel offers
1401 */
1402static int
1403vmbus_doattach(struct vmbus_softc *sc)
1404{
1405	struct sysctl_oid_list *child;
1406	struct sysctl_ctx_list *ctx;
1407	int ret;
1408
1409	if (sc->vmbus_flags & VMBUS_FLAG_ATTACHED)
1410		return (0);
1411
1412#ifdef NEW_PCIB
1413	vmbus_get_mmio_res(sc->vmbus_dev);
1414#endif
1415
1416	sc->vmbus_flags |= VMBUS_FLAG_ATTACHED;
1417
1418	sc->vmbus_gpadl = VMBUS_GPADL_START;
1419	mtx_init(&sc->vmbus_prichan_lock, "vmbus prichan", NULL, MTX_DEF);
1420	TAILQ_INIT(&sc->vmbus_prichans);
1421	mtx_init(&sc->vmbus_chan_lock, "vmbus channel", NULL, MTX_DEF);
1422	TAILQ_INIT(&sc->vmbus_chans);
1423	sc->vmbus_chmap = malloc(
1424	    sizeof(struct vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF,
1425	    M_WAITOK | M_ZERO);
1426
1427	/*
1428	 * Create context for "post message" Hypercalls
1429	 */
1430	sc->vmbus_xc = vmbus_xact_ctx_create(bus_get_dma_tag(sc->vmbus_dev),
1431	    HYPERCALL_POSTMSGIN_SIZE, VMBUS_MSG_SIZE,
1432	    sizeof(struct vmbus_msghc));
1433	if (sc->vmbus_xc == NULL) {
1434		ret = ENXIO;
1435		goto cleanup;
1436	}
1437
1438	/*
1439	 * Allocate DMA stuffs.
1440	 */
1441	ret = vmbus_dma_alloc(sc);
1442	if (ret != 0)
1443		goto cleanup;
1444
1445	/*
1446	 * Setup interrupt.
1447	 */
1448	ret = vmbus_intr_setup(sc);
1449	if (ret != 0)
1450		goto cleanup;
1451
1452	/*
1453	 * Setup SynIC.
1454	 */
1455	if (bootverbose)
1456		device_printf(sc->vmbus_dev, "smp_started = %d\n", smp_started);
1457	smp_rendezvous(NULL, vmbus_synic_setup, NULL, sc);
1458	sc->vmbus_flags |= VMBUS_FLAG_SYNIC;
1459
1460	/*
1461	 * Initialize vmbus, e.g. connect to Hypervisor.
1462	 */
1463	ret = vmbus_init(sc);
1464	if (ret != 0)
1465		goto cleanup;
1466
1467	if (sc->vmbus_version == VMBUS_VERSION_WS2008 ||
1468	    sc->vmbus_version == VMBUS_VERSION_WIN7)
1469		sc->vmbus_event_proc = vmbus_event_proc_compat;
1470	else
1471		sc->vmbus_event_proc = vmbus_event_proc;
1472
1473	ret = vmbus_scan(sc);
1474	if (ret != 0)
1475		goto cleanup;
1476
1477	ctx = device_get_sysctl_ctx(sc->vmbus_dev);
1478	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vmbus_dev));
1479	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "version",
1480	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
1481	    vmbus_sysctl_version, "A", "vmbus version");
1482
1483	return (ret);
1484
1485cleanup:
1486	vmbus_scan_teardown(sc);
1487	vmbus_intr_teardown(sc);
1488	vmbus_dma_free(sc);
1489	if (sc->vmbus_xc != NULL) {
1490		vmbus_xact_ctx_destroy(sc->vmbus_xc);
1491		sc->vmbus_xc = NULL;
1492	}
1493	free(__DEVOLATILE(void *, sc->vmbus_chmap), M_DEVBUF);
1494	mtx_destroy(&sc->vmbus_prichan_lock);
1495	mtx_destroy(&sc->vmbus_chan_lock);
1496
1497	return (ret);
1498}
1499
1500static void
1501vmbus_event_proc_dummy(struct vmbus_softc *sc __unused, int cpu __unused)
1502{
1503}
1504
1505static int
1506vmbus_attach(device_t dev)
1507{
1508	vmbus_sc = device_get_softc(dev);
1509	vmbus_sc->vmbus_dev = dev;
1510
1511	/*
1512	 * Event processing logic will be configured:
1513	 * - After the vmbus protocol version negotiation.
1514	 * - Before we request channel offers.
1515	 */
1516	vmbus_sc->vmbus_event_proc = vmbus_event_proc_dummy;
1517
1518	/*
1519	 * If the system has already booted and thread
1520	 * scheduling is possible indicated by the global
1521	 * cold set to zero, we just call the driver
1522	 * initialization directly.
1523	 */
1524	if (!cold)
1525		vmbus_doattach(vmbus_sc);
1526
1527	return (0);
1528}
1529
1530static int
1531vmbus_detach(device_t dev)
1532{
1533	struct vmbus_softc *sc = device_get_softc(dev);
1534
1535	bus_generic_detach(dev);
1536	vmbus_chan_destroy_all(sc);
1537
1538	vmbus_scan_teardown(sc);
1539
1540	vmbus_disconnect(sc);
1541
1542	if (sc->vmbus_flags & VMBUS_FLAG_SYNIC) {
1543		sc->vmbus_flags &= ~VMBUS_FLAG_SYNIC;
1544		smp_rendezvous(NULL, vmbus_synic_teardown, NULL, NULL);
1545	}
1546
1547	vmbus_intr_teardown(sc);
1548	vmbus_dma_free(sc);
1549
1550	if (sc->vmbus_xc != NULL) {
1551		vmbus_xact_ctx_destroy(sc->vmbus_xc);
1552		sc->vmbus_xc = NULL;
1553	}
1554
1555	free(__DEVOLATILE(void *, sc->vmbus_chmap), M_DEVBUF);
1556	mtx_destroy(&sc->vmbus_prichan_lock);
1557	mtx_destroy(&sc->vmbus_chan_lock);
1558
1559#ifdef NEW_PCIB
1560	vmbus_free_mmio_res(dev);
1561#endif
1562
1563	return (0);
1564}
1565
1566static void
1567vmbus_sysinit(void *arg __unused)
1568{
1569	struct vmbus_softc *sc = vmbus_get_softc();
1570
1571	if (vm_guest != VM_GUEST_HV || sc == NULL)
1572		return;
1573
1574	/*
1575	 * If the system has already booted and thread
1576	 * scheduling is possible, as indicated by the
1577	 * global cold set to zero, we just call the driver
1578	 * initialization directly.
1579	 */
1580	if (!cold)
1581		vmbus_doattach(sc);
1582}
1583/*
1584 * NOTE:
1585 * We have to start as the last step of SI_SUB_SMP, i.e. after SMP is
1586 * initialized.
1587 */
1588SYSINIT(vmbus_initialize, SI_SUB_SMP, SI_ORDER_ANY, vmbus_sysinit, NULL);
1589