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 #include <sys/param.h>
30 #include <sys/bus.h>
31 #include <sys/callout.h>
32 #include <sys/kernel.h>
33 #include <sys/lock.h>
34 #include <sys/malloc.h>
35 #include <sys/mutex.h>
36 #include <sys/smp.h>
37 #include <sys/stdarg.h>
38 #include <sys/sysctl.h>
39 #include <sys/systm.h>
40
41 #include <machine/atomic.h>
42
43 #include <vm/vm.h>
44 #include <vm/pmap.h>
45 #include <vm/vm_extern.h>
46
47 #include <dev/hyperv/include/vmbus_xact.h>
48 #include <dev/hyperv/vmbus/hyperv_var.h>
49 #include <dev/hyperv/vmbus/vmbus_reg.h>
50 #include <dev/hyperv/vmbus/vmbus_var.h>
51 #include <dev/hyperv/vmbus/vmbus_brvar.h>
52 #include <dev/hyperv/vmbus/vmbus_chanvar.h>
53
54 struct vmbus_chan_pollarg {
55 struct vmbus_channel *poll_chan;
56 u_int poll_hz;
57 };
58
59 static void vmbus_chan_update_evtflagcnt(
60 struct vmbus_softc *,
61 const struct vmbus_channel *);
62 static int vmbus_chan_close_internal(
63 struct vmbus_channel *);
64 static int vmbus_chan_sysctl_mnf(SYSCTL_HANDLER_ARGS);
65 static void vmbus_chan_sysctl_create(
66 struct vmbus_channel *);
67 static struct vmbus_channel *vmbus_chan_alloc(struct vmbus_softc *);
68 static void vmbus_chan_free(struct vmbus_channel *);
69 static int vmbus_chan_add(struct vmbus_channel *);
70 static void vmbus_chan_cpu_default(struct vmbus_channel *);
71 static int vmbus_chan_release(struct vmbus_channel *);
72 static void vmbus_chan_set_chmap(struct vmbus_channel *);
73 static void vmbus_chan_clear_chmap(struct vmbus_channel *);
74 static void vmbus_chan_detach(struct vmbus_channel *);
75 static bool vmbus_chan_wait_revoke(
76 const struct vmbus_channel *, bool);
77 static void vmbus_chan_poll_timeout(void *);
78 static bool vmbus_chan_poll_cancel_intq(
79 struct vmbus_channel *);
80 static void vmbus_chan_poll_cancel(struct vmbus_channel *);
81
82 static void vmbus_chan_ins_prilist(struct vmbus_softc *,
83 struct vmbus_channel *);
84 static void vmbus_chan_rem_prilist(struct vmbus_softc *,
85 struct vmbus_channel *);
86 static void vmbus_chan_ins_list(struct vmbus_softc *,
87 struct vmbus_channel *);
88 static void vmbus_chan_rem_list(struct vmbus_softc *,
89 struct vmbus_channel *);
90 static void vmbus_chan_ins_sublist(struct vmbus_channel *,
91 struct vmbus_channel *);
92 static void vmbus_chan_rem_sublist(struct vmbus_channel *,
93 struct vmbus_channel *);
94
95 static void vmbus_chan_task(void *, int);
96 static void vmbus_chan_task_nobatch(void *, int);
97 static void vmbus_chan_poll_task(void *, int);
98 static void vmbus_chan_clrchmap_task(void *, int);
99 static void vmbus_chan_pollcfg_task(void *, int);
100 static void vmbus_chan_polldis_task(void *, int);
101 static void vmbus_chan_poll_cancel_task(void *, int);
102 static void vmbus_prichan_attach_task(void *, int);
103 static void vmbus_subchan_attach_task(void *, int);
104 static void vmbus_prichan_detach_task(void *, int);
105 static void vmbus_subchan_detach_task(void *, int);
106
107 static void vmbus_chan_msgproc_choffer(struct vmbus_softc *,
108 const struct vmbus_message *);
109 static void vmbus_chan_msgproc_chrescind(
110 struct vmbus_softc *,
111 const struct vmbus_message *);
112
113 static int vmbus_chan_printf(const struct vmbus_channel *,
114 const char *, ...) __printflike(2, 3);
115
116 /*
117 * Vmbus channel message processing.
118 */
119 static const vmbus_chanmsg_proc_t
120 vmbus_chan_msgprocs[VMBUS_CHANMSG_TYPE_MAX] = {
121 VMBUS_CHANMSG_PROC(CHOFFER, vmbus_chan_msgproc_choffer),
122 VMBUS_CHANMSG_PROC(CHRESCIND, vmbus_chan_msgproc_chrescind),
123
124 VMBUS_CHANMSG_PROC_WAKEUP(CHOPEN_RESP),
125 VMBUS_CHANMSG_PROC_WAKEUP(GPADL_CONNRESP),
126 VMBUS_CHANMSG_PROC_WAKEUP(GPADL_DISCONNRESP)
127 };
128
129 /*
130 * Notify host that there are data pending on our TX bufring or
131 * we have put some data on the TX bufring.
132 */
133 static __inline void
vmbus_chan_signal(const struct vmbus_channel * chan)134 vmbus_chan_signal(const struct vmbus_channel *chan)
135 {
136 atomic_set_long(chan->ch_evtflag, chan->ch_evtflag_mask);
137 if (chan->ch_txflags & VMBUS_CHAN_TXF_HASMNF)
138 atomic_set_int(chan->ch_montrig, chan->ch_montrig_mask);
139 else
140 hypercall_signal_event(pmap_kextract(
141 (vm_offset_t)chan->ch_monprm));
142 }
143
144 static __inline void
vmbus_chan_signal_tx(struct vmbus_channel * chan)145 vmbus_chan_signal_tx(struct vmbus_channel *chan)
146 {
147 chan->ch_txbr.txbr_intrcnt ++;
148
149 vmbus_chan_signal(chan);
150 }
151
152 static __inline void
vmbus_chan_signal_rx(struct vmbus_channel * chan)153 vmbus_chan_signal_rx(struct vmbus_channel *chan)
154 {
155 chan->ch_rxbr.rxbr_intrcnt ++;
156
157 vmbus_chan_signal(chan);
158 }
159
160 static void
vmbus_chan_ins_prilist(struct vmbus_softc * sc,struct vmbus_channel * chan)161 vmbus_chan_ins_prilist(struct vmbus_softc *sc, struct vmbus_channel *chan)
162 {
163
164 mtx_assert(&sc->vmbus_prichan_lock, MA_OWNED);
165 if (atomic_testandset_int(&chan->ch_stflags,
166 VMBUS_CHAN_ST_ONPRIL_SHIFT))
167 panic("channel is already on the prilist");
168 TAILQ_INSERT_TAIL(&sc->vmbus_prichans, chan, ch_prilink);
169 }
170
171 static void
vmbus_chan_rem_prilist(struct vmbus_softc * sc,struct vmbus_channel * chan)172 vmbus_chan_rem_prilist(struct vmbus_softc *sc, struct vmbus_channel *chan)
173 {
174
175 mtx_assert(&sc->vmbus_prichan_lock, MA_OWNED);
176 if (atomic_testandclear_int(&chan->ch_stflags,
177 VMBUS_CHAN_ST_ONPRIL_SHIFT) == 0)
178 panic("channel is not on the prilist");
179 TAILQ_REMOVE(&sc->vmbus_prichans, chan, ch_prilink);
180 }
181
182 static void
vmbus_chan_ins_sublist(struct vmbus_channel * prichan,struct vmbus_channel * chan)183 vmbus_chan_ins_sublist(struct vmbus_channel *prichan,
184 struct vmbus_channel *chan)
185 {
186
187 mtx_assert(&prichan->ch_subchan_lock, MA_OWNED);
188
189 if (atomic_testandset_int(&chan->ch_stflags,
190 VMBUS_CHAN_ST_ONSUBL_SHIFT))
191 panic("channel is already on the sublist");
192 TAILQ_INSERT_TAIL(&prichan->ch_subchans, chan, ch_sublink);
193
194 /* Bump sub-channel count. */
195 prichan->ch_subchan_cnt++;
196 }
197
198 static void
vmbus_chan_rem_sublist(struct vmbus_channel * prichan,struct vmbus_channel * chan)199 vmbus_chan_rem_sublist(struct vmbus_channel *prichan,
200 struct vmbus_channel *chan)
201 {
202
203 mtx_assert(&prichan->ch_subchan_lock, MA_OWNED);
204
205 KASSERT(prichan->ch_subchan_cnt > 0,
206 ("invalid subchan_cnt %d", prichan->ch_subchan_cnt));
207 prichan->ch_subchan_cnt--;
208
209 if (atomic_testandclear_int(&chan->ch_stflags,
210 VMBUS_CHAN_ST_ONSUBL_SHIFT) == 0)
211 panic("channel is not on the sublist");
212 TAILQ_REMOVE(&prichan->ch_subchans, chan, ch_sublink);
213 }
214
215 static void
vmbus_chan_ins_list(struct vmbus_softc * sc,struct vmbus_channel * chan)216 vmbus_chan_ins_list(struct vmbus_softc *sc, struct vmbus_channel *chan)
217 {
218
219 mtx_assert(&sc->vmbus_chan_lock, MA_OWNED);
220 if (atomic_testandset_int(&chan->ch_stflags,
221 VMBUS_CHAN_ST_ONLIST_SHIFT))
222 panic("channel is already on the list");
223 TAILQ_INSERT_TAIL(&sc->vmbus_chans, chan, ch_link);
224 }
225
226 static void
vmbus_chan_rem_list(struct vmbus_softc * sc,struct vmbus_channel * chan)227 vmbus_chan_rem_list(struct vmbus_softc *sc, struct vmbus_channel *chan)
228 {
229
230 mtx_assert(&sc->vmbus_chan_lock, MA_OWNED);
231 if (atomic_testandclear_int(&chan->ch_stflags,
232 VMBUS_CHAN_ST_ONLIST_SHIFT) == 0)
233 panic("channel is not on the list");
234 TAILQ_REMOVE(&sc->vmbus_chans, chan, ch_link);
235 }
236
237 static int
vmbus_chan_sysctl_mnf(SYSCTL_HANDLER_ARGS)238 vmbus_chan_sysctl_mnf(SYSCTL_HANDLER_ARGS)
239 {
240 struct vmbus_channel *chan = arg1;
241 int mnf = 0;
242
243 if (chan->ch_txflags & VMBUS_CHAN_TXF_HASMNF)
244 mnf = 1;
245 return sysctl_handle_int(oidp, &mnf, 0, req);
246 }
247
248 static void
vmbus_chan_sysctl_create(struct vmbus_channel * chan)249 vmbus_chan_sysctl_create(struct vmbus_channel *chan)
250 {
251 struct sysctl_oid *ch_tree, *chid_tree, *br_tree;
252 struct sysctl_ctx_list *ctx;
253 uint32_t ch_id;
254 char name[16];
255
256 /*
257 * Add sysctl nodes related to this channel to this
258 * channel's sysctl ctx, so that they can be destroyed
259 * independently upon close of this channel, which can
260 * happen even if the device is not detached.
261 */
262 ctx = &chan->ch_sysctl_ctx;
263 sysctl_ctx_init(ctx);
264
265 /*
266 * Create dev.NAME.UNIT.channel tree.
267 */
268 ch_tree = SYSCTL_ADD_NODE(ctx,
269 SYSCTL_CHILDREN(device_get_sysctl_tree(chan->ch_dev)),
270 OID_AUTO, "channel", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
271 if (ch_tree == NULL)
272 return;
273
274 /*
275 * Create dev.NAME.UNIT.channel.CHANID tree.
276 */
277 if (VMBUS_CHAN_ISPRIMARY(chan)) {
278 ch_id = chan->ch_id;
279 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(ch_tree), OID_AUTO,
280 "ch_id", CTLFLAG_RD, &chan->ch_id, 0, "owner channel id");
281 } else
282 ch_id = chan->ch_prichan->ch_id;
283 snprintf(name, sizeof(name), "%d", ch_id);
284 chid_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(ch_tree),
285 OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
286 if (chid_tree == NULL)
287 return;
288
289 if (!VMBUS_CHAN_ISPRIMARY(chan)) {
290 /*
291 * Create dev.NAME.UNIT.channel.CHANID.sub tree.
292 */
293 ch_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree),
294 OID_AUTO, "sub", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
295 if (ch_tree == NULL)
296 return;
297
298 /*
299 * Create dev.NAME.UNIT.channel.CHANID.sub.SUBIDX tree.
300 *
301 * NOTE:
302 * chid_tree is changed to this new sysctl tree.
303 */
304 snprintf(name, sizeof(name), "%d", chan->ch_subidx);
305 chid_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(ch_tree),
306 OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
307 if (chid_tree == NULL)
308 return;
309
310 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
311 "chanid", CTLFLAG_RD, &chan->ch_id, 0, "channel id");
312 }
313
314 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
315 "ch_subidx", CTLFLAG_RD, &chan->ch_subidx, 0, "subchan index");
316 SYSCTL_ADD_U8(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
317 "monitor_id", CTLFLAG_RD, &chan->ch_monitor_id, 0,
318 "owner monitor id");
319 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
320 "cpu", CTLFLAG_RD, &chan->ch_cpuid, 0, "owner CPU id");
321 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
322 "mnf", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
323 chan, 0, vmbus_chan_sysctl_mnf, "I",
324 "has monitor notification facilities");
325
326 br_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
327 "br", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
328 if (br_tree != NULL) {
329 /*
330 * Create sysctl tree for RX bufring.
331 */
332 vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_rxbr.rxbr, "rx");
333 /*
334 * Create sysctl tree for TX bufring.
335 */
336 vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_txbr.txbr, "tx");
337 }
338 }
339
340 int
vmbus_chan_open(struct vmbus_channel * chan,int txbr_size,int rxbr_size,const void * udata,int udlen,vmbus_chan_callback_t cb,void * cbarg)341 vmbus_chan_open(struct vmbus_channel *chan, int txbr_size, int rxbr_size,
342 const void *udata, int udlen, vmbus_chan_callback_t cb, void *cbarg)
343 {
344 struct vmbus_chan_br cbr;
345 int error;
346
347 /*
348 * Allocate the TX+RX bufrings.
349 */
350 KASSERT(chan->ch_bufring == NULL, ("bufrings are allocated"));
351 chan->ch_bufring = contigmalloc(txbr_size + rxbr_size, M_DEVBUF,
352 M_WAITOK | M_ZERO, 0ul, ~0ul, PAGE_SIZE, 0);
353 if (chan->ch_bufring == NULL) {
354 vmbus_chan_printf(chan, "bufring allocation failed\n");
355 return (ENOMEM);
356 }
357
358 cbr.cbr = chan->ch_bufring;
359 cbr.cbr_paddr = pmap_kextract((vm_offset_t)chan->ch_bufring);
360 cbr.cbr_txsz = txbr_size;
361 cbr.cbr_rxsz = rxbr_size;
362
363 error = vmbus_chan_open_br(chan, &cbr, udata, udlen, cb, cbarg);
364 if (error) {
365 if (error == EISCONN) {
366 /*
367 * XXX
368 * The bufring GPADL is still connected; abandon
369 * this bufring, instead of having mysterious
370 * crash or trashed data later on.
371 */
372 vmbus_chan_printf(chan, "chan%u bufring GPADL "
373 "is still connected upon channel open error; "
374 "leak %d bytes memory\n", chan->ch_id,
375 txbr_size + rxbr_size);
376 } else {
377 free(chan->ch_bufring, M_DEVBUF);
378 }
379 chan->ch_bufring = NULL;
380 }
381 return (error);
382 }
383
384 int
vmbus_chan_open_br(struct vmbus_channel * chan,const struct vmbus_chan_br * cbr,const void * udata,int udlen,vmbus_chan_callback_t cb,void * cbarg)385 vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr,
386 const void *udata, int udlen, vmbus_chan_callback_t cb, void *cbarg)
387 {
388 struct vmbus_softc *sc = chan->ch_vmbus;
389 const struct vmbus_message *msg;
390 struct vmbus_chanmsg_chopen *req;
391 struct vmbus_msghc *mh;
392 uint32_t status;
393 int error, txbr_size, rxbr_size;
394 task_fn_t *task_fn;
395 uint8_t *br;
396
397 if (udlen > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) {
398 vmbus_chan_printf(chan,
399 "invalid udata len %d for chan%u\n", udlen, chan->ch_id);
400 return (EINVAL);
401 }
402
403 br = cbr->cbr;
404 txbr_size = cbr->cbr_txsz;
405 rxbr_size = cbr->cbr_rxsz;
406 KASSERT((txbr_size & PAGE_MASK) == 0,
407 ("send bufring size is not multiple page"));
408 KASSERT((rxbr_size & PAGE_MASK) == 0,
409 ("recv bufring size is not multiple page"));
410 KASSERT((cbr->cbr_paddr & PAGE_MASK) == 0,
411 ("bufring is not page aligned"));
412
413 /*
414 * Zero out the TX/RX bufrings, in case that they were used before.
415 */
416 memset(br, 0, txbr_size + rxbr_size);
417
418 if (atomic_testandset_int(&chan->ch_stflags,
419 VMBUS_CHAN_ST_OPENED_SHIFT))
420 panic("double-open chan%u", chan->ch_id);
421
422 chan->ch_cb = cb;
423 chan->ch_cbarg = cbarg;
424
425 vmbus_chan_update_evtflagcnt(sc, chan);
426
427 chan->ch_tq = VMBUS_PCPU_GET(chan->ch_vmbus, event_tq, chan->ch_cpuid);
428 if (chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD)
429 task_fn = vmbus_chan_task;
430 else
431 task_fn = vmbus_chan_task_nobatch;
432 TASK_INIT(&chan->ch_task, 0, task_fn, chan);
433
434 /* TX bufring comes first */
435 vmbus_txbr_setup(&chan->ch_txbr, br, txbr_size);
436 /* RX bufring immediately follows TX bufring */
437 vmbus_rxbr_setup(&chan->ch_rxbr, br + txbr_size, rxbr_size);
438
439 /* Create sysctl tree for this channel */
440 vmbus_chan_sysctl_create(chan);
441
442 /*
443 * Connect the bufrings, both RX and TX, to this channel.
444 */
445 error = vmbus_chan_gpadl_connect(chan, cbr->cbr_paddr,
446 txbr_size + rxbr_size, &chan->ch_bufring_gpadl);
447 if (error) {
448 vmbus_chan_printf(chan,
449 "failed to connect bufring GPADL to chan%u\n", chan->ch_id);
450 goto failed;
451 }
452
453 /*
454 * Install this channel, before it is opened, but after everything
455 * else has been setup.
456 */
457 vmbus_chan_set_chmap(chan);
458
459 /*
460 * Open channel w/ the bufring GPADL on the target CPU.
461 */
462 mh = vmbus_msghc_get(sc, sizeof(*req));
463 if (mh == NULL) {
464 vmbus_chan_printf(chan,
465 "can not get msg hypercall for chopen(chan%u)\n",
466 chan->ch_id);
467 error = ENXIO;
468 goto failed;
469 }
470
471 req = vmbus_msghc_dataptr(mh);
472 req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHOPEN;
473 req->chm_chanid = chan->ch_id;
474 req->chm_openid = chan->ch_id;
475 req->chm_gpadl = chan->ch_bufring_gpadl;
476 req->chm_vcpuid = chan->ch_vcpuid;
477 req->chm_txbr_pgcnt = txbr_size >> PAGE_SHIFT;
478 if (udlen > 0)
479 memcpy(req->chm_udata, udata, udlen);
480
481 error = vmbus_msghc_exec(sc, mh);
482 if (error) {
483 vmbus_chan_printf(chan,
484 "chopen(chan%u) msg hypercall exec failed: %d\n",
485 chan->ch_id, error);
486 vmbus_msghc_put(sc, mh);
487 goto failed;
488 }
489
490 for (;;) {
491 msg = vmbus_msghc_poll_result(sc, mh);
492 if (msg != NULL)
493 break;
494 if (vmbus_chan_is_revoked(chan)) {
495 int i;
496
497 /*
498 * NOTE:
499 * Hypervisor does _not_ send response CHOPEN to
500 * a revoked channel.
501 */
502 vmbus_chan_printf(chan,
503 "chan%u is revoked, when it is being opened\n",
504 chan->ch_id);
505
506 /*
507 * XXX
508 * Add extra delay before cancel the hypercall
509 * execution; mainly to close any possible
510 * CHRESCIND and CHOPEN_RESP races on the
511 * hypervisor side.
512 */
513 #define REVOKE_LINGER 100
514 for (i = 0; i < REVOKE_LINGER; ++i) {
515 msg = vmbus_msghc_poll_result(sc, mh);
516 if (msg != NULL)
517 break;
518 pause("rchopen", 1);
519 }
520 #undef REVOKE_LINGER
521 if (msg == NULL)
522 vmbus_msghc_exec_cancel(sc, mh);
523 break;
524 }
525 pause("chopen", 1);
526 }
527 if (msg != NULL) {
528 status = ((const struct vmbus_chanmsg_chopen_resp *)
529 msg->msg_data)->chm_status;
530 } else {
531 /* XXX any non-0 value is ok here. */
532 status = 0xff;
533 }
534
535 vmbus_msghc_put(sc, mh);
536
537 if (status == 0) {
538 if (bootverbose)
539 vmbus_chan_printf(chan, "chan%u opened\n", chan->ch_id);
540 return (0);
541 }
542
543 vmbus_chan_printf(chan, "failed to open chan%u\n", chan->ch_id);
544 error = ENXIO;
545
546 failed:
547 sysctl_ctx_free(&chan->ch_sysctl_ctx);
548 vmbus_chan_clear_chmap(chan);
549 if (chan->ch_bufring_gpadl != 0) {
550 int error1;
551
552 error1 = vmbus_chan_gpadl_disconnect(chan,
553 chan->ch_bufring_gpadl);
554 if (error1) {
555 /*
556 * Give caller a hint that the bufring GPADL is still
557 * connected.
558 */
559 error = EISCONN;
560 }
561 chan->ch_bufring_gpadl = 0;
562 }
563 atomic_clear_int(&chan->ch_stflags, VMBUS_CHAN_ST_OPENED);
564 return (error);
565 }
566
567 int
vmbus_chan_gpadl_connect(struct vmbus_channel * chan,bus_addr_t paddr,int size,uint32_t * gpadl0)568 vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr,
569 int size, uint32_t *gpadl0)
570 {
571 struct vmbus_softc *sc = chan->ch_vmbus;
572 struct vmbus_msghc *mh;
573 struct vmbus_chanmsg_gpadl_conn *req;
574 const struct vmbus_message *msg;
575 size_t reqsz;
576 uint32_t gpadl, status;
577 int page_count, range_len, i, cnt, error;
578 uint64_t page_id;
579
580 KASSERT(*gpadl0 == 0, ("GPADL is not zero"));
581
582 /*
583 * Preliminary checks.
584 */
585
586 KASSERT((size & PAGE_MASK) == 0,
587 ("invalid GPA size %d, not multiple page size", size));
588 page_count = size >> PAGE_SHIFT;
589
590 KASSERT((paddr & PAGE_MASK) == 0,
591 ("GPA is not page aligned %jx", (uintmax_t)paddr));
592 page_id = paddr >> PAGE_SHIFT;
593
594 range_len = __offsetof(struct vmbus_gpa_range, gpa_page[page_count]);
595 /*
596 * We don't support multiple GPA ranges.
597 */
598 if (range_len > UINT16_MAX) {
599 vmbus_chan_printf(chan, "GPA too large, %d pages\n",
600 page_count);
601 return EOPNOTSUPP;
602 }
603
604 /*
605 * Allocate GPADL id.
606 */
607 gpadl = vmbus_gpadl_alloc(sc);
608
609 /*
610 * Connect this GPADL to the target channel.
611 *
612 * NOTE:
613 * Since each message can only hold small set of page
614 * addresses, several messages may be required to
615 * complete the connection.
616 */
617 if (page_count > VMBUS_CHANMSG_GPADL_CONN_PGMAX)
618 cnt = VMBUS_CHANMSG_GPADL_CONN_PGMAX;
619 else
620 cnt = page_count;
621 page_count -= cnt;
622
623 reqsz = __offsetof(struct vmbus_chanmsg_gpadl_conn,
624 chm_range.gpa_page[cnt]);
625 mh = vmbus_msghc_get(sc, reqsz);
626 if (mh == NULL) {
627 vmbus_chan_printf(chan,
628 "can not get msg hypercall for gpadl_conn(chan%u)\n",
629 chan->ch_id);
630 return EIO;
631 }
632
633 req = vmbus_msghc_dataptr(mh);
634 req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_CONN;
635 req->chm_chanid = chan->ch_id;
636 req->chm_gpadl = gpadl;
637 req->chm_range_len = range_len;
638 req->chm_range_cnt = 1;
639 req->chm_range.gpa_len = size;
640 req->chm_range.gpa_ofs = 0;
641 for (i = 0; i < cnt; ++i)
642 req->chm_range.gpa_page[i] = page_id++;
643
644 error = vmbus_msghc_exec(sc, mh);
645 if (error) {
646 vmbus_chan_printf(chan,
647 "gpadl_conn(chan%u) msg hypercall exec failed: %d\n",
648 chan->ch_id, error);
649 vmbus_msghc_put(sc, mh);
650 return error;
651 }
652
653 while (page_count > 0) {
654 struct vmbus_chanmsg_gpadl_subconn *subreq;
655
656 if (page_count > VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX)
657 cnt = VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX;
658 else
659 cnt = page_count;
660 page_count -= cnt;
661
662 reqsz = __offsetof(struct vmbus_chanmsg_gpadl_subconn,
663 chm_gpa_page[cnt]);
664 vmbus_msghc_reset(mh, reqsz);
665
666 subreq = vmbus_msghc_dataptr(mh);
667 subreq->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_SUBCONN;
668 subreq->chm_gpadl = gpadl;
669 for (i = 0; i < cnt; ++i)
670 subreq->chm_gpa_page[i] = page_id++;
671
672 vmbus_msghc_exec_noresult(mh);
673 }
674 KASSERT(page_count == 0, ("invalid page count %d", page_count));
675
676 msg = vmbus_msghc_wait_result(sc, mh);
677 status = ((const struct vmbus_chanmsg_gpadl_connresp *)
678 msg->msg_data)->chm_status;
679
680 vmbus_msghc_put(sc, mh);
681
682 if (status != 0) {
683 vmbus_chan_printf(chan, "gpadl_conn(chan%u) failed: %u\n",
684 chan->ch_id, status);
685 return EIO;
686 }
687
688 /* Done; commit the GPADL id. */
689 *gpadl0 = gpadl;
690 if (bootverbose) {
691 vmbus_chan_printf(chan, "gpadl_conn(chan%u) succeeded\n",
692 chan->ch_id);
693 }
694 return 0;
695 }
696
697 static bool
vmbus_chan_wait_revoke(const struct vmbus_channel * chan,bool can_sleep)698 vmbus_chan_wait_revoke(const struct vmbus_channel *chan, bool can_sleep)
699 {
700 #define WAIT_COUNT 200 /* 200ms */
701
702 int i;
703
704 for (i = 0; i < WAIT_COUNT; ++i) {
705 if (vmbus_chan_is_revoked(chan))
706 return (true);
707 if (can_sleep)
708 pause("wchrev", 1);
709 else
710 DELAY(1000);
711 }
712 return (false);
713
714 #undef WAIT_COUNT
715 }
716
717 /*
718 * Disconnect the GPA from the target channel
719 */
720 int
vmbus_chan_gpadl_disconnect(struct vmbus_channel * chan,uint32_t gpadl)721 vmbus_chan_gpadl_disconnect(struct vmbus_channel *chan, uint32_t gpadl)
722 {
723 struct vmbus_softc *sc = chan->ch_vmbus;
724 struct vmbus_msghc *mh;
725 struct vmbus_chanmsg_gpadl_disconn *req;
726 int error;
727
728 KASSERT(gpadl != 0, ("GPADL is zero"));
729
730 mh = vmbus_msghc_get(sc, sizeof(*req));
731 if (mh == NULL) {
732 vmbus_chan_printf(chan,
733 "can not get msg hypercall for gpadl_disconn(chan%u)\n",
734 chan->ch_id);
735 return (EBUSY);
736 }
737
738 req = vmbus_msghc_dataptr(mh);
739 req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_DISCONN;
740 req->chm_chanid = chan->ch_id;
741 req->chm_gpadl = gpadl;
742
743 error = vmbus_msghc_exec(sc, mh);
744 if (error) {
745 vmbus_msghc_put(sc, mh);
746
747 if (vmbus_chan_wait_revoke(chan, true)) {
748 /*
749 * Error is benign; this channel is revoked,
750 * so this GPADL will not be touched anymore.
751 */
752 vmbus_chan_printf(chan,
753 "gpadl_disconn(revoked chan%u) msg hypercall "
754 "exec failed: %d\n", chan->ch_id, error);
755 return (0);
756 }
757 vmbus_chan_printf(chan,
758 "gpadl_disconn(chan%u) msg hypercall exec failed: %d\n",
759 chan->ch_id, error);
760 return (error);
761 }
762
763 vmbus_msghc_wait_result(sc, mh);
764 /* Discard result; no useful information */
765 vmbus_msghc_put(sc, mh);
766
767 return (0);
768 }
769
770 static void
vmbus_chan_detach(struct vmbus_channel * chan)771 vmbus_chan_detach(struct vmbus_channel *chan)
772 {
773 int refs;
774
775 KASSERT(chan->ch_refs > 0, ("chan%u: invalid refcnt %d",
776 chan->ch_id, chan->ch_refs));
777 refs = atomic_fetchadd_int(&chan->ch_refs, -1);
778 #ifdef INVARIANTS
779 if (VMBUS_CHAN_ISPRIMARY(chan)) {
780 KASSERT(refs == 1, ("chan%u: invalid refcnt %d for prichan",
781 chan->ch_id, refs + 1));
782 }
783 #endif
784 if (refs == 1) {
785 /*
786 * Detach the target channel.
787 */
788 if (bootverbose) {
789 vmbus_chan_printf(chan, "chan%u detached\n",
790 chan->ch_id);
791 }
792 taskqueue_enqueue(chan->ch_mgmt_tq, &chan->ch_detach_task);
793 }
794 }
795
796 static void
vmbus_chan_clrchmap_task(void * xchan,int pending __unused)797 vmbus_chan_clrchmap_task(void *xchan, int pending __unused)
798 {
799 struct vmbus_channel *chan = xchan;
800
801 chan->ch_vmbus->vmbus_chmap[chan->ch_id] = NULL;
802 }
803
804 static void
vmbus_chan_clear_chmap(struct vmbus_channel * chan)805 vmbus_chan_clear_chmap(struct vmbus_channel *chan)
806 {
807 struct task chmap_task;
808
809 TASK_INIT(&chmap_task, 0, vmbus_chan_clrchmap_task, chan);
810 vmbus_chan_run_task(chan, &chmap_task);
811 }
812
813 static void
vmbus_chan_set_chmap(struct vmbus_channel * chan)814 vmbus_chan_set_chmap(struct vmbus_channel *chan)
815 {
816 __compiler_membar();
817 chan->ch_vmbus->vmbus_chmap[chan->ch_id] = chan;
818 }
819
820 static void
vmbus_chan_poll_cancel_task(void * xchan,int pending __unused)821 vmbus_chan_poll_cancel_task(void *xchan, int pending __unused)
822 {
823
824 vmbus_chan_poll_cancel_intq(xchan);
825 }
826
827 static void
vmbus_chan_poll_cancel(struct vmbus_channel * chan)828 vmbus_chan_poll_cancel(struct vmbus_channel *chan)
829 {
830 struct task poll_cancel;
831
832 TASK_INIT(&poll_cancel, 0, vmbus_chan_poll_cancel_task, chan);
833 vmbus_chan_run_task(chan, &poll_cancel);
834 }
835
836 static int
vmbus_chan_close_internal(struct vmbus_channel * chan)837 vmbus_chan_close_internal(struct vmbus_channel *chan)
838 {
839 struct vmbus_softc *sc = chan->ch_vmbus;
840 struct vmbus_msghc *mh;
841 struct vmbus_chanmsg_chclose *req;
842 uint32_t old_stflags;
843 int error;
844
845 /*
846 * NOTE:
847 * Sub-channels are closed upon their primary channel closing,
848 * so they can be closed even before they are opened.
849 */
850 for (;;) {
851 old_stflags = chan->ch_stflags;
852 if (atomic_cmpset_int(&chan->ch_stflags, old_stflags,
853 old_stflags & ~VMBUS_CHAN_ST_OPENED))
854 break;
855 }
856 if ((old_stflags & VMBUS_CHAN_ST_OPENED) == 0) {
857 /* Not opened yet; done */
858 if (bootverbose) {
859 vmbus_chan_printf(chan, "chan%u not opened\n",
860 chan->ch_id);
861 }
862 return (0);
863 }
864
865 /*
866 * Free this channel's sysctl tree attached to its device's
867 * sysctl tree.
868 */
869 sysctl_ctx_free(&chan->ch_sysctl_ctx);
870
871 /*
872 * Cancel polling, if it is enabled.
873 */
874 vmbus_chan_poll_cancel(chan);
875
876 /*
877 * NOTE:
878 * Order is critical. This channel _must_ be uninstalled first,
879 * else the channel task may be enqueued by the IDT after it has
880 * been drained.
881 */
882 vmbus_chan_clear_chmap(chan);
883 taskqueue_drain(chan->ch_tq, &chan->ch_task);
884 chan->ch_tq = NULL;
885
886 /*
887 * Close this channel.
888 */
889 mh = vmbus_msghc_get(sc, sizeof(*req));
890 if (mh == NULL) {
891 vmbus_chan_printf(chan,
892 "can not get msg hypercall for chclose(chan%u)\n",
893 chan->ch_id);
894 error = ENXIO;
895 goto disconnect;
896 }
897
898 req = vmbus_msghc_dataptr(mh);
899 req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHCLOSE;
900 req->chm_chanid = chan->ch_id;
901
902 error = vmbus_msghc_exec_noresult(mh);
903 vmbus_msghc_put(sc, mh);
904
905 if (error) {
906 vmbus_chan_printf(chan,
907 "chclose(chan%u) msg hypercall exec failed: %d\n",
908 chan->ch_id, error);
909 goto disconnect;
910 }
911
912 if (bootverbose)
913 vmbus_chan_printf(chan, "chan%u closed\n", chan->ch_id);
914
915 disconnect:
916 /*
917 * Disconnect the TX+RX bufrings from this channel.
918 */
919 if (chan->ch_bufring_gpadl != 0) {
920 int error1;
921
922 error1 = vmbus_chan_gpadl_disconnect(chan,
923 chan->ch_bufring_gpadl);
924 if (error1) {
925 /*
926 * XXX
927 * The bufring GPADL is still connected; abandon
928 * this bufring, instead of having mysterious
929 * crash or trashed data later on.
930 */
931 vmbus_chan_printf(chan, "chan%u bufring GPADL "
932 "is still connected after close\n", chan->ch_id);
933 chan->ch_bufring = NULL;
934 /*
935 * Give caller a hint that the bufring GPADL is
936 * still connected.
937 */
938 error = EISCONN;
939 }
940 chan->ch_bufring_gpadl = 0;
941 }
942
943 /*
944 * Destroy the TX+RX bufrings.
945 */
946 if (chan->ch_bufring != NULL) {
947 free(chan->ch_bufring, M_DEVBUF);
948 chan->ch_bufring = NULL;
949 }
950 return (error);
951 }
952
953 int
vmbus_chan_close_direct(struct vmbus_channel * chan)954 vmbus_chan_close_direct(struct vmbus_channel *chan)
955 {
956 int error;
957
958 #ifdef INVARIANTS
959 if (VMBUS_CHAN_ISPRIMARY(chan)) {
960 struct vmbus_channel *subchan;
961
962 /*
963 * All sub-channels _must_ have been closed, or are _not_
964 * opened at all.
965 */
966 mtx_lock(&chan->ch_subchan_lock);
967 TAILQ_FOREACH(subchan, &chan->ch_subchans, ch_sublink) {
968 KASSERT(
969 (subchan->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0,
970 ("chan%u: subchan%u is still opened",
971 chan->ch_id, subchan->ch_subidx));
972 }
973 mtx_unlock(&chan->ch_subchan_lock);
974 }
975 #endif
976
977 error = vmbus_chan_close_internal(chan);
978 if (!VMBUS_CHAN_ISPRIMARY(chan)) {
979 /*
980 * This sub-channel is referenced, when it is linked to
981 * the primary channel; drop that reference now.
982 */
983 vmbus_chan_detach(chan);
984 }
985 return (error);
986 }
987
988 /*
989 * Caller should make sure that all sub-channels have
990 * been added to 'chan' and all to-be-closed channels
991 * are not being opened.
992 */
993 void
vmbus_chan_close(struct vmbus_channel * chan)994 vmbus_chan_close(struct vmbus_channel *chan)
995 {
996 int subchan_cnt;
997
998 if (!VMBUS_CHAN_ISPRIMARY(chan)) {
999 /*
1000 * Sub-channel is closed when its primary channel
1001 * is closed; done.
1002 */
1003 return;
1004 }
1005
1006 /*
1007 * Close all sub-channels, if any.
1008 */
1009 subchan_cnt = chan->ch_subchan_cnt;
1010 if (subchan_cnt > 0) {
1011 struct vmbus_channel **subchan;
1012 int i;
1013
1014 subchan = vmbus_subchan_get(chan, subchan_cnt);
1015 for (i = 0; i < subchan_cnt; ++i) {
1016 vmbus_chan_close_internal(subchan[i]);
1017 /*
1018 * This sub-channel is referenced, when it is
1019 * linked to the primary channel; drop that
1020 * reference now.
1021 */
1022 vmbus_chan_detach(subchan[i]);
1023 }
1024 vmbus_subchan_rel(subchan, subchan_cnt);
1025 }
1026
1027 /* Then close the primary channel. */
1028 vmbus_chan_close_internal(chan);
1029 }
1030
1031 void
vmbus_chan_intr_drain(struct vmbus_channel * chan)1032 vmbus_chan_intr_drain(struct vmbus_channel *chan)
1033 {
1034
1035 taskqueue_drain(chan->ch_tq, &chan->ch_task);
1036 }
1037
1038 uint32_t
vmbus_chan_write_available(struct vmbus_channel * chan)1039 vmbus_chan_write_available(struct vmbus_channel *chan)
1040 {
1041 return (vmbus_txbr_available(&chan->ch_txbr));
1042 }
1043
1044 bool
vmbus_chan_write_signal(struct vmbus_channel * chan,int32_t min_signal_size)1045 vmbus_chan_write_signal(struct vmbus_channel *chan,
1046 int32_t min_signal_size)
1047 {
1048 if (min_signal_size >= 0 &&
1049 vmbus_chan_write_available(chan) > min_signal_size) {
1050 return false;
1051 }
1052
1053 if (!vmbus_txbr_get_imask(&chan->ch_txbr)) {
1054 /* txbr imask is not set, signal the reader */
1055 vmbus_chan_signal_tx(chan);
1056 return true;
1057 }
1058
1059 return false;
1060 }
1061
1062 void
vmbus_chan_set_pending_send_size(struct vmbus_channel * chan,uint32_t size)1063 vmbus_chan_set_pending_send_size(struct vmbus_channel *chan,
1064 uint32_t size)
1065 {
1066 if (chan)
1067 vmbus_txbr_set_pending_snd_sz(&chan->ch_txbr, size);
1068 }
1069
1070 int
vmbus_chan_iov_send(struct vmbus_channel * chan,const struct iovec iov[],int iovlen,vmbus_br_copy_callback_t cb,void * cbarg)1071 vmbus_chan_iov_send(struct vmbus_channel *chan,
1072 const struct iovec iov[], int iovlen,
1073 vmbus_br_copy_callback_t cb, void *cbarg)
1074 {
1075 int error;
1076 boolean_t send_evt;
1077
1078 if (iovlen == 0)
1079 return (0);
1080
1081 error = vmbus_txbr_write_call(&chan->ch_txbr, iov, iovlen,
1082 cb, cbarg, &send_evt);
1083
1084 if (!error && send_evt) {
1085 vmbus_chan_signal_tx(chan);
1086 }
1087
1088 return error;
1089 }
1090
1091 int
vmbus_chan_send(struct vmbus_channel * chan,uint16_t type,uint16_t flags,void * data,int dlen,uint64_t xactid)1092 vmbus_chan_send(struct vmbus_channel *chan, uint16_t type, uint16_t flags,
1093 void *data, int dlen, uint64_t xactid)
1094 {
1095 struct vmbus_chanpkt pkt;
1096 int pktlen, pad_pktlen, hlen, error;
1097 uint64_t pad = 0;
1098 struct iovec iov[3];
1099 boolean_t send_evt;
1100
1101 hlen = sizeof(pkt);
1102 pktlen = hlen + dlen;
1103 pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen);
1104 KASSERT(pad_pktlen <= vmbus_txbr_maxpktsz(&chan->ch_txbr),
1105 ("invalid packet size %d", pad_pktlen));
1106
1107 pkt.cp_hdr.cph_type = type;
1108 pkt.cp_hdr.cph_flags = flags;
1109 VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen);
1110 VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen);
1111 pkt.cp_hdr.cph_xactid = xactid;
1112
1113 iov[0].iov_base = &pkt;
1114 iov[0].iov_len = hlen;
1115 iov[1].iov_base = data;
1116 iov[1].iov_len = dlen;
1117 iov[2].iov_base = &pad;
1118 iov[2].iov_len = pad_pktlen - pktlen;
1119
1120 error = vmbus_txbr_write(&chan->ch_txbr, iov, 3, &send_evt);
1121 if (!error && send_evt)
1122 vmbus_chan_signal_tx(chan);
1123 return error;
1124 }
1125
1126 int
vmbus_chan_send_sglist(struct vmbus_channel * chan,struct vmbus_gpa sg[],int sglen,void * data,int dlen,uint64_t xactid)1127 vmbus_chan_send_sglist(struct vmbus_channel *chan,
1128 struct vmbus_gpa sg[], int sglen, void *data, int dlen, uint64_t xactid)
1129 {
1130 struct vmbus_chanpkt_sglist pkt;
1131 int pktlen, pad_pktlen, hlen, error;
1132 struct iovec iov[4];
1133 boolean_t send_evt;
1134 uint64_t pad = 0;
1135
1136 hlen = __offsetof(struct vmbus_chanpkt_sglist, cp_gpa[sglen]);
1137 pktlen = hlen + dlen;
1138 pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen);
1139 KASSERT(pad_pktlen <= vmbus_txbr_maxpktsz(&chan->ch_txbr),
1140 ("invalid packet size %d", pad_pktlen));
1141
1142 pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA;
1143 pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC;
1144 VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen);
1145 VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen);
1146 pkt.cp_hdr.cph_xactid = xactid;
1147 pkt.cp_rsvd = 0;
1148 pkt.cp_gpa_cnt = sglen;
1149
1150 iov[0].iov_base = &pkt;
1151 iov[0].iov_len = sizeof(pkt);
1152 iov[1].iov_base = sg;
1153 iov[1].iov_len = sizeof(struct vmbus_gpa) * sglen;
1154 iov[2].iov_base = data;
1155 iov[2].iov_len = dlen;
1156 iov[3].iov_base = &pad;
1157 iov[3].iov_len = pad_pktlen - pktlen;
1158
1159 error = vmbus_txbr_write(&chan->ch_txbr, iov, 4, &send_evt);
1160 if (!error && send_evt)
1161 vmbus_chan_signal_tx(chan);
1162 return error;
1163 }
1164
1165 int
vmbus_chan_send_prplist(struct vmbus_channel * chan,struct vmbus_gpa_range * prp,int prp_cnt,void * data,int dlen,uint64_t xactid)1166 vmbus_chan_send_prplist(struct vmbus_channel *chan,
1167 struct vmbus_gpa_range *prp, int prp_cnt, void *data, int dlen,
1168 uint64_t xactid)
1169 {
1170 struct vmbus_chanpkt_prplist pkt;
1171 int pktlen, pad_pktlen, hlen, error;
1172 struct iovec iov[4];
1173 boolean_t send_evt;
1174 uint64_t pad = 0;
1175
1176 hlen = __offsetof(struct vmbus_chanpkt_prplist,
1177 cp_range[0].gpa_page[prp_cnt]);
1178 pktlen = hlen + dlen;
1179 pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen);
1180 KASSERT(pad_pktlen <= vmbus_txbr_maxpktsz(&chan->ch_txbr),
1181 ("invalid packet size %d", pad_pktlen));
1182
1183 pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA;
1184 pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC;
1185 VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen);
1186 VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen);
1187 pkt.cp_hdr.cph_xactid = xactid;
1188 pkt.cp_rsvd = 0;
1189 pkt.cp_range_cnt = 1;
1190
1191 iov[0].iov_base = &pkt;
1192 iov[0].iov_len = sizeof(pkt);
1193 iov[1].iov_base = prp;
1194 iov[1].iov_len = __offsetof(struct vmbus_gpa_range, gpa_page[prp_cnt]);
1195 iov[2].iov_base = data;
1196 iov[2].iov_len = dlen;
1197 iov[3].iov_base = &pad;
1198 iov[3].iov_len = pad_pktlen - pktlen;
1199
1200 error = vmbus_txbr_write(&chan->ch_txbr, iov, 4, &send_evt);
1201 if (!error && send_evt)
1202 vmbus_chan_signal_tx(chan);
1203 return error;
1204 }
1205
1206 int
vmbus_chan_recv(struct vmbus_channel * chan,void * data,int * dlen0,uint64_t * xactid)1207 vmbus_chan_recv(struct vmbus_channel *chan, void *data, int *dlen0,
1208 uint64_t *xactid)
1209 {
1210 struct vmbus_chanpkt_hdr pkt;
1211 int error, dlen, hlen;
1212 boolean_t sig_event;
1213
1214 error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt));
1215 if (error)
1216 return (error);
1217
1218 if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) {
1219 vmbus_chan_printf(chan, "invalid hlen %u\n", pkt.cph_hlen);
1220 /* XXX this channel is dead actually. */
1221 return (EIO);
1222 }
1223 if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) {
1224 vmbus_chan_printf(chan, "invalid hlen %u and tlen %u\n",
1225 pkt.cph_hlen, pkt.cph_tlen);
1226 /* XXX this channel is dead actually. */
1227 return (EIO);
1228 }
1229
1230 hlen = VMBUS_CHANPKT_GETLEN(pkt.cph_hlen);
1231 dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen;
1232
1233 if (*dlen0 < dlen) {
1234 /* Return the size of this packet's data. */
1235 *dlen0 = dlen;
1236 return (ENOBUFS);
1237 }
1238
1239 *xactid = pkt.cph_xactid;
1240 *dlen0 = dlen;
1241
1242 /* Skip packet header */
1243 error = vmbus_rxbr_read(&chan->ch_rxbr, data, dlen, hlen, &sig_event);
1244 KASSERT(!error, ("vmbus_rxbr_read failed"));
1245
1246 if (!error && sig_event)
1247 vmbus_chan_signal_rx(chan);
1248
1249 return (0);
1250 }
1251
1252 int
vmbus_chan_recv_pkt(struct vmbus_channel * chan,struct vmbus_chanpkt_hdr * pkt,int * pktlen0)1253 vmbus_chan_recv_pkt(struct vmbus_channel *chan,
1254 struct vmbus_chanpkt_hdr *pkt, int *pktlen0)
1255 {
1256 int error, pktlen, pkt_hlen;
1257 boolean_t sig_event;
1258
1259 pkt_hlen = sizeof(*pkt);
1260 error = vmbus_rxbr_peek(&chan->ch_rxbr, pkt, pkt_hlen);
1261 if (error)
1262 return (error);
1263
1264 if (__predict_false(pkt->cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) {
1265 vmbus_chan_printf(chan, "invalid hlen %u\n", pkt->cph_hlen);
1266 /* XXX this channel is dead actually. */
1267 return (EIO);
1268 }
1269 if (__predict_false(pkt->cph_hlen > pkt->cph_tlen)) {
1270 vmbus_chan_printf(chan, "invalid hlen %u and tlen %u\n",
1271 pkt->cph_hlen, pkt->cph_tlen);
1272 /* XXX this channel is dead actually. */
1273 return (EIO);
1274 }
1275
1276 pktlen = VMBUS_CHANPKT_GETLEN(pkt->cph_tlen);
1277 if (*pktlen0 < pktlen) {
1278 /* Return the size of this packet. */
1279 *pktlen0 = pktlen;
1280 return (ENOBUFS);
1281 }
1282 *pktlen0 = pktlen;
1283
1284 /*
1285 * Skip the fixed-size packet header, which has been filled
1286 * by the above vmbus_rxbr_peek().
1287 */
1288 error = vmbus_rxbr_read(&chan->ch_rxbr, pkt + 1,
1289 pktlen - pkt_hlen, pkt_hlen, &sig_event);
1290 KASSERT(!error, ("vmbus_rxbr_read failed"));
1291
1292 if (!error && sig_event)
1293 vmbus_chan_signal_rx(chan);
1294
1295 return (0);
1296 }
1297
1298 uint32_t
vmbus_chan_read_available(struct vmbus_channel * chan)1299 vmbus_chan_read_available(struct vmbus_channel *chan)
1300 {
1301 return (vmbus_rxbr_available(&chan->ch_rxbr));
1302 }
1303
1304 /*
1305 * This routine does:
1306 * - Advance the channel read index for 'advance' bytes
1307 * - Copy data_len bytes in to the buffer pointed by 'data'
1308 * Return 0 if operation succeed. EAGAIN if operations if failed.
1309 * If failed, the buffer pointed by 'data' is intact, and the
1310 * channel read index is not advanced at all.
1311 */
1312 int
vmbus_chan_recv_peek(struct vmbus_channel * chan,void * data,int data_len,uint32_t advance)1313 vmbus_chan_recv_peek(struct vmbus_channel *chan,
1314 void *data, int data_len, uint32_t advance)
1315 {
1316 int error;
1317 boolean_t sig_event;
1318
1319 if (data == NULL || data_len <= 0)
1320 return (EINVAL);
1321
1322 error = vmbus_rxbr_idxadv_peek(&chan->ch_rxbr,
1323 data, data_len, advance, &sig_event);
1324
1325 if (!error && sig_event) {
1326 vmbus_chan_signal_rx(chan);
1327 }
1328
1329 return (error);
1330 }
1331
1332 /*
1333 * This routine does:
1334 * - Advance the channel read index for 'advance' bytes
1335 */
1336 int
vmbus_chan_recv_idxadv(struct vmbus_channel * chan,uint32_t advance)1337 vmbus_chan_recv_idxadv(struct vmbus_channel *chan, uint32_t advance)
1338 {
1339 int error;
1340 boolean_t sig_event;
1341
1342 if (advance == 0)
1343 return (EINVAL);
1344
1345 error = vmbus_rxbr_idxadv(&chan->ch_rxbr, advance, &sig_event);
1346
1347 if (!error && sig_event) {
1348 vmbus_chan_signal_rx(chan);
1349 }
1350
1351 return (error);
1352 }
1353
1354
1355 /*
1356 * Caller should hold its own lock to serialize the ring buffer
1357 * copy.
1358 */
1359 int
vmbus_chan_recv_peek_call(struct vmbus_channel * chan,int data_len,uint32_t skip,vmbus_br_copy_callback_t cb,void * cbarg)1360 vmbus_chan_recv_peek_call(struct vmbus_channel *chan, int data_len,
1361 uint32_t skip, vmbus_br_copy_callback_t cb, void *cbarg)
1362 {
1363 if (!chan || data_len <= 0 || cb == NULL)
1364 return (EINVAL);
1365
1366 return (vmbus_rxbr_peek_call(&chan->ch_rxbr, data_len, skip,
1367 cb, cbarg));
1368 }
1369
1370 static void
vmbus_chan_task(void * xchan,int pending __unused)1371 vmbus_chan_task(void *xchan, int pending __unused)
1372 {
1373 struct vmbus_channel *chan = xchan;
1374 vmbus_chan_callback_t cb = chan->ch_cb;
1375 void *cbarg = chan->ch_cbarg;
1376
1377 KASSERT(chan->ch_poll_intvl == 0,
1378 ("chan%u: interrupted in polling mode", chan->ch_id));
1379
1380 /*
1381 * Optimize host to guest signaling by ensuring:
1382 * 1. While reading the channel, we disable interrupts from
1383 * host.
1384 * 2. Ensure that we process all posted messages from the host
1385 * before returning from this callback.
1386 * 3. Once we return, enable signaling from the host. Once this
1387 * state is set we check to see if additional packets are
1388 * available to read. In this case we repeat the process.
1389 *
1390 * NOTE: Interrupt has been disabled in the ISR.
1391 */
1392 for (;;) {
1393 uint32_t left;
1394
1395 cb(chan, cbarg);
1396
1397 left = vmbus_rxbr_intr_unmask(&chan->ch_rxbr);
1398 if (left == 0) {
1399 /* No more data in RX bufring; done */
1400 break;
1401 }
1402 vmbus_rxbr_intr_mask(&chan->ch_rxbr);
1403 }
1404 }
1405
1406 static void
vmbus_chan_task_nobatch(void * xchan,int pending __unused)1407 vmbus_chan_task_nobatch(void *xchan, int pending __unused)
1408 {
1409 struct vmbus_channel *chan = xchan;
1410
1411 KASSERT(chan->ch_poll_intvl == 0,
1412 ("chan%u: interrupted in polling mode", chan->ch_id));
1413 chan->ch_cb(chan, chan->ch_cbarg);
1414 }
1415
1416 static void
vmbus_chan_poll_timeout(void * xchan)1417 vmbus_chan_poll_timeout(void *xchan)
1418 {
1419 struct vmbus_channel *chan = xchan;
1420
1421 KASSERT(chan->ch_poll_intvl != 0,
1422 ("chan%u: polling timeout in interrupt mode", chan->ch_id));
1423 taskqueue_enqueue(chan->ch_tq, &chan->ch_poll_task);
1424 }
1425
1426 static void
vmbus_chan_poll_task(void * xchan,int pending __unused)1427 vmbus_chan_poll_task(void *xchan, int pending __unused)
1428 {
1429 struct vmbus_channel *chan = xchan;
1430
1431 KASSERT(chan->ch_poll_intvl != 0,
1432 ("chan%u: polling in interrupt mode", chan->ch_id));
1433 callout_reset_sbt_curcpu(&chan->ch_poll_timeo, chan->ch_poll_intvl, 0,
1434 vmbus_chan_poll_timeout, chan, chan->ch_poll_flags);
1435 chan->ch_cb(chan, chan->ch_cbarg);
1436 }
1437
1438 static void
vmbus_chan_pollcfg_task(void * xarg,int pending __unused)1439 vmbus_chan_pollcfg_task(void *xarg, int pending __unused)
1440 {
1441 const struct vmbus_chan_pollarg *arg = xarg;
1442 struct vmbus_channel *chan = arg->poll_chan;
1443 sbintime_t intvl;
1444 int poll_flags;
1445
1446 /*
1447 * Save polling interval.
1448 */
1449 intvl = SBT_1S / arg->poll_hz;
1450 if (intvl == 0)
1451 intvl = 1;
1452 if (intvl == chan->ch_poll_intvl) {
1453 /* Nothing changes; done */
1454 return;
1455 }
1456 chan->ch_poll_intvl = intvl;
1457
1458 /* Adjust callout flags. */
1459 poll_flags = C_DIRECT_EXEC;
1460 if (arg->poll_hz <= hz)
1461 poll_flags |= C_HARDCLOCK;
1462 chan->ch_poll_flags = poll_flags;
1463
1464 /*
1465 * Disconnect this channel from the channel map to make sure that
1466 * the RX bufring interrupt enabling bit can not be touched, and
1467 * ISR can not enqueue this channel task anymore. THEN, disable
1468 * interrupt from the RX bufring (TX bufring does not generate
1469 * interrupt to VM).
1470 *
1471 * NOTE: order is critical.
1472 */
1473 chan->ch_vmbus->vmbus_chmap[chan->ch_id] = NULL;
1474 __compiler_membar();
1475 vmbus_rxbr_intr_mask(&chan->ch_rxbr);
1476
1477 /*
1478 * NOTE:
1479 * At this point, this channel task will not be enqueued by
1480 * the ISR anymore, time to cancel the pending one.
1481 */
1482 taskqueue_cancel(chan->ch_tq, &chan->ch_task, NULL);
1483
1484 /* Kick start! */
1485 taskqueue_enqueue(chan->ch_tq, &chan->ch_poll_task);
1486 }
1487
1488 static bool
vmbus_chan_poll_cancel_intq(struct vmbus_channel * chan)1489 vmbus_chan_poll_cancel_intq(struct vmbus_channel *chan)
1490 {
1491
1492 if (chan->ch_poll_intvl == 0) {
1493 /* Not enabled. */
1494 return (false);
1495 }
1496
1497 /*
1498 * Stop polling callout, so that channel polling task
1499 * will not be enqueued anymore.
1500 */
1501 callout_drain(&chan->ch_poll_timeo);
1502
1503 /*
1504 * Disable polling by resetting polling interval.
1505 *
1506 * NOTE:
1507 * The polling interval resetting MUST be conducted
1508 * after the callout is drained; mainly to keep the
1509 * proper assertion in place.
1510 */
1511 chan->ch_poll_intvl = 0;
1512
1513 /*
1514 * NOTE:
1515 * At this point, this channel polling task will not be
1516 * enqueued by the callout anymore, time to cancel the
1517 * pending one.
1518 */
1519 taskqueue_cancel(chan->ch_tq, &chan->ch_poll_task, NULL);
1520
1521 /* Polling was enabled. */
1522 return (true);
1523 }
1524
1525 static void
vmbus_chan_polldis_task(void * xchan,int pending __unused)1526 vmbus_chan_polldis_task(void *xchan, int pending __unused)
1527 {
1528 struct vmbus_channel *chan = xchan;
1529
1530 if (!vmbus_chan_poll_cancel_intq(chan)) {
1531 /* Already disabled; done. */
1532 return;
1533 }
1534
1535 /*
1536 * Plug this channel back to the channel map and unmask
1537 * the RX bufring interrupt.
1538 */
1539 chan->ch_vmbus->vmbus_chmap[chan->ch_id] = chan;
1540 __compiler_membar();
1541 vmbus_rxbr_intr_unmask(&chan->ch_rxbr);
1542
1543 /*
1544 * Kick start the interrupt task, just in case unmasking
1545 * interrupt races ISR.
1546 */
1547 taskqueue_enqueue(chan->ch_tq, &chan->ch_task);
1548 }
1549
1550 static __inline void
vmbus_event_flags_proc(struct vmbus_softc * sc,volatile u_long * event_flags,int flag_cnt)1551 vmbus_event_flags_proc(struct vmbus_softc *sc, volatile u_long *event_flags,
1552 int flag_cnt)
1553 {
1554 int f;
1555
1556 for (f = 0; f < flag_cnt; ++f) {
1557 uint32_t chid_base;
1558 u_long flags;
1559 int chid_ofs;
1560
1561 if (event_flags[f] == 0)
1562 continue;
1563
1564 flags = atomic_swap_long(&event_flags[f], 0);
1565 chid_base = f * VMBUS_EVTFLAG_LEN;
1566
1567 while ((chid_ofs = ffsl(flags)) != 0) {
1568 struct vmbus_channel *chan;
1569
1570 --chid_ofs; /* NOTE: ffsl is 1-based */
1571 flags &= ~(1UL << chid_ofs);
1572
1573 chan = sc->vmbus_chmap[chid_base + chid_ofs];
1574 if (__predict_false(chan == NULL)) {
1575 /* Channel is closed. */
1576 continue;
1577 }
1578 __compiler_membar();
1579
1580 if (chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD)
1581 vmbus_rxbr_intr_mask(&chan->ch_rxbr);
1582 taskqueue_enqueue(chan->ch_tq, &chan->ch_task);
1583 }
1584 }
1585 }
1586
1587 void
vmbus_event_proc(struct vmbus_softc * sc,int cpu)1588 vmbus_event_proc(struct vmbus_softc *sc, int cpu)
1589 {
1590 struct vmbus_evtflags *eventf;
1591
1592 /*
1593 * On Host with Win8 or above, the event page can be checked directly
1594 * to get the id of the channel that has the pending interrupt.
1595 */
1596 eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE;
1597 vmbus_event_flags_proc(sc, eventf->evt_flags,
1598 VMBUS_PCPU_GET(sc, event_flags_cnt, cpu));
1599 }
1600
1601 void
vmbus_event_proc_compat(struct vmbus_softc * sc,int cpu)1602 vmbus_event_proc_compat(struct vmbus_softc *sc, int cpu)
1603 {
1604 struct vmbus_evtflags *eventf;
1605
1606 eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE;
1607 if (atomic_testandclear_long(&eventf->evt_flags[0], 0)) {
1608 vmbus_event_flags_proc(sc, sc->vmbus_rx_evtflags,
1609 VMBUS_CHAN_MAX_COMPAT / VMBUS_EVTFLAG_LEN);
1610 }
1611 }
1612
1613 static void
vmbus_chan_update_evtflagcnt(struct vmbus_softc * sc,const struct vmbus_channel * chan)1614 vmbus_chan_update_evtflagcnt(struct vmbus_softc *sc,
1615 const struct vmbus_channel *chan)
1616 {
1617 volatile int *flag_cnt_ptr;
1618 int flag_cnt;
1619
1620 flag_cnt = (chan->ch_id / VMBUS_EVTFLAG_LEN) + 1;
1621 flag_cnt_ptr = VMBUS_PCPU_PTR(sc, event_flags_cnt, chan->ch_cpuid);
1622
1623 for (;;) {
1624 int old_flag_cnt;
1625
1626 old_flag_cnt = *flag_cnt_ptr;
1627 if (old_flag_cnt >= flag_cnt)
1628 break;
1629 if (atomic_cmpset_int(flag_cnt_ptr, old_flag_cnt, flag_cnt)) {
1630 if (bootverbose) {
1631 vmbus_chan_printf(chan,
1632 "chan%u update cpu%d flag_cnt to %d\n",
1633 chan->ch_id, chan->ch_cpuid, flag_cnt);
1634 }
1635 break;
1636 }
1637 }
1638 }
1639
1640 static struct vmbus_channel *
vmbus_chan_alloc(struct vmbus_softc * sc)1641 vmbus_chan_alloc(struct vmbus_softc *sc)
1642 {
1643 struct vmbus_channel *chan;
1644
1645 chan = malloc(sizeof(*chan), M_DEVBUF, M_WAITOK | M_ZERO);
1646
1647 chan->ch_monprm = contigmalloc(sizeof(struct hyperv_mon_param),
1648 M_DEVBUF, M_WAITOK | M_ZERO, 0ul, ~0ul, HYPERCALL_PARAM_ALIGN, 0);
1649 if (chan->ch_monprm == NULL) {
1650 device_printf(sc->vmbus_dev, "monprm alloc failed\n");
1651 free(chan, M_DEVBUF);
1652 return NULL;
1653 }
1654
1655 chan->ch_refs = 1;
1656 chan->ch_vmbus = sc;
1657 mtx_init(&chan->ch_subchan_lock, "vmbus subchan", NULL, MTX_DEF);
1658 sx_init(&chan->ch_orphan_lock, "vmbus chorphan");
1659 TAILQ_INIT(&chan->ch_subchans);
1660 vmbus_rxbr_init(&chan->ch_rxbr);
1661 vmbus_txbr_init(&chan->ch_txbr);
1662
1663 TASK_INIT(&chan->ch_poll_task, 0, vmbus_chan_poll_task, chan);
1664 callout_init(&chan->ch_poll_timeo, 1);
1665
1666 return chan;
1667 }
1668
1669 static void
vmbus_chan_free(struct vmbus_channel * chan)1670 vmbus_chan_free(struct vmbus_channel *chan)
1671 {
1672
1673 KASSERT(TAILQ_EMPTY(&chan->ch_subchans) && chan->ch_subchan_cnt == 0,
1674 ("still owns sub-channels"));
1675 KASSERT((chan->ch_stflags &
1676 (VMBUS_CHAN_ST_OPENED |
1677 VMBUS_CHAN_ST_ONPRIL |
1678 VMBUS_CHAN_ST_ONSUBL |
1679 VMBUS_CHAN_ST_ONLIST)) == 0, ("free busy channel"));
1680 KASSERT(chan->ch_orphan_xact == NULL,
1681 ("still has orphan xact installed"));
1682 KASSERT(chan->ch_refs == 0, ("chan%u: invalid refcnt %d",
1683 chan->ch_id, chan->ch_refs));
1684 KASSERT(chan->ch_poll_intvl == 0, ("chan%u: polling is activated",
1685 chan->ch_id));
1686
1687 free(chan->ch_monprm, M_DEVBUF);
1688 mtx_destroy(&chan->ch_subchan_lock);
1689 sx_destroy(&chan->ch_orphan_lock);
1690 vmbus_rxbr_deinit(&chan->ch_rxbr);
1691 vmbus_txbr_deinit(&chan->ch_txbr);
1692 free(chan, M_DEVBUF);
1693 }
1694
1695 static int
vmbus_chan_add(struct vmbus_channel * newchan)1696 vmbus_chan_add(struct vmbus_channel *newchan)
1697 {
1698 struct vmbus_softc *sc = newchan->ch_vmbus;
1699 struct vmbus_channel *prichan;
1700
1701 if (newchan->ch_id == 0) {
1702 /*
1703 * XXX
1704 * Chan0 will neither be processed nor should be offered;
1705 * skip it.
1706 */
1707 device_printf(sc->vmbus_dev, "got chan0 offer, discard\n");
1708 return EINVAL;
1709 } else if (newchan->ch_id >= VMBUS_CHAN_MAX) {
1710 device_printf(sc->vmbus_dev, "invalid chan%u offer\n",
1711 newchan->ch_id);
1712 return EINVAL;
1713 }
1714
1715 mtx_lock(&sc->vmbus_prichan_lock);
1716 TAILQ_FOREACH(prichan, &sc->vmbus_prichans, ch_prilink) {
1717 /*
1718 * Sub-channel will have the same type GUID and instance
1719 * GUID as its primary channel.
1720 */
1721 if (memcmp(&prichan->ch_guid_type, &newchan->ch_guid_type,
1722 sizeof(struct hyperv_guid)) == 0 &&
1723 memcmp(&prichan->ch_guid_inst, &newchan->ch_guid_inst,
1724 sizeof(struct hyperv_guid)) == 0)
1725 break;
1726 }
1727 if (VMBUS_CHAN_ISPRIMARY(newchan)) {
1728 if (prichan == NULL) {
1729 /* Install the new primary channel */
1730 vmbus_chan_ins_prilist(sc, newchan);
1731 mtx_unlock(&sc->vmbus_prichan_lock);
1732 goto done;
1733 } else {
1734 mtx_unlock(&sc->vmbus_prichan_lock);
1735 device_printf(sc->vmbus_dev,
1736 "duplicated primary chan%u\n", newchan->ch_id);
1737 return EINVAL;
1738 }
1739 } else { /* Sub-channel */
1740 if (prichan == NULL) {
1741 mtx_unlock(&sc->vmbus_prichan_lock);
1742 device_printf(sc->vmbus_dev,
1743 "no primary chan for chan%u\n", newchan->ch_id);
1744 return EINVAL;
1745 }
1746 /*
1747 * Found the primary channel for this sub-channel and
1748 * move on.
1749 *
1750 * XXX refcnt prichan
1751 */
1752 }
1753 mtx_unlock(&sc->vmbus_prichan_lock);
1754
1755 /*
1756 * This is a sub-channel; link it with the primary channel.
1757 */
1758 KASSERT(!VMBUS_CHAN_ISPRIMARY(newchan),
1759 ("new channel is not sub-channel"));
1760 KASSERT(prichan != NULL, ("no primary channel"));
1761
1762 /*
1763 * Reference count this sub-channel; it will be dereferenced
1764 * when this sub-channel is closed.
1765 */
1766 KASSERT(newchan->ch_refs == 1, ("chan%u: invalid refcnt %d",
1767 newchan->ch_id, newchan->ch_refs));
1768 atomic_add_int(&newchan->ch_refs, 1);
1769
1770 newchan->ch_prichan = prichan;
1771 newchan->ch_dev = prichan->ch_dev;
1772
1773 mtx_lock(&prichan->ch_subchan_lock);
1774 vmbus_chan_ins_sublist(prichan, newchan);
1775 mtx_unlock(&prichan->ch_subchan_lock);
1776 /*
1777 * Notify anyone that is interested in this sub-channel,
1778 * after this sub-channel is setup.
1779 */
1780 wakeup(prichan);
1781 done:
1782 /*
1783 * Hook this channel up for later revocation.
1784 */
1785 mtx_lock(&sc->vmbus_chan_lock);
1786 vmbus_chan_ins_list(sc, newchan);
1787 mtx_unlock(&sc->vmbus_chan_lock);
1788
1789 if (bootverbose) {
1790 vmbus_chan_printf(newchan, "chan%u subidx%u offer\n",
1791 newchan->ch_id, newchan->ch_subidx);
1792 }
1793
1794 /* Select default cpu for this channel. */
1795 vmbus_chan_cpu_default(newchan);
1796
1797 return 0;
1798 }
1799
1800 void
vmbus_chan_cpu_set(struct vmbus_channel * chan,int cpu)1801 vmbus_chan_cpu_set(struct vmbus_channel *chan, int cpu)
1802 {
1803 KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpu %d", cpu));
1804
1805 if (chan->ch_vmbus->vmbus_version == VMBUS_VERSION_WS2008 ||
1806 chan->ch_vmbus->vmbus_version == VMBUS_VERSION_WIN7) {
1807 /* Only cpu0 is supported */
1808 cpu = 0;
1809 }
1810
1811 chan->ch_cpuid = cpu;
1812 chan->ch_vcpuid = VMBUS_PCPU_GET(chan->ch_vmbus, vcpuid, cpu);
1813
1814 if (bootverbose) {
1815 vmbus_chan_printf(chan,
1816 "chan%u assigned to cpu%u [vcpu%u]\n",
1817 chan->ch_id, chan->ch_cpuid, chan->ch_vcpuid);
1818 }
1819 }
1820
1821 void
vmbus_chan_cpu_rr(struct vmbus_channel * chan)1822 vmbus_chan_cpu_rr(struct vmbus_channel *chan)
1823 {
1824 static uint32_t vmbus_chan_nextcpu;
1825 int cpu;
1826
1827 cpu = atomic_fetchadd_int(&vmbus_chan_nextcpu, 1) % mp_ncpus;
1828 vmbus_chan_cpu_set(chan, cpu);
1829 }
1830
1831 static void
vmbus_chan_cpu_default(struct vmbus_channel * chan)1832 vmbus_chan_cpu_default(struct vmbus_channel *chan)
1833 {
1834 /*
1835 * By default, pin the channel to cpu0. Devices having
1836 * special channel-cpu mapping requirement should call
1837 * vmbus_chan_cpu_{set,rr}().
1838 */
1839 vmbus_chan_cpu_set(chan, 0);
1840 }
1841
1842 static void
vmbus_chan_msgproc_choffer(struct vmbus_softc * sc,const struct vmbus_message * msg)1843 vmbus_chan_msgproc_choffer(struct vmbus_softc *sc,
1844 const struct vmbus_message *msg)
1845 {
1846 const struct vmbus_chanmsg_choffer *offer;
1847 struct vmbus_channel *chan;
1848 task_fn_t *detach_fn, *attach_fn;
1849 int error;
1850
1851 offer = (const struct vmbus_chanmsg_choffer *)msg->msg_data;
1852
1853 chan = vmbus_chan_alloc(sc);
1854 if (chan == NULL) {
1855 device_printf(sc->vmbus_dev, "allocate chan%u failed\n",
1856 offer->chm_chanid);
1857 return;
1858 }
1859
1860 chan->ch_id = offer->chm_chanid;
1861 chan->ch_subidx = offer->chm_subidx;
1862 chan->ch_guid_type = offer->chm_chtype;
1863 chan->ch_guid_inst = offer->chm_chinst;
1864 chan->ch_monitor_id = offer->chm_montrig;
1865
1866 /* Batch reading is on by default */
1867 chan->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD;
1868
1869 chan->ch_monprm->mp_connid = VMBUS_CONNID_EVENT;
1870 if (sc->vmbus_version != VMBUS_VERSION_WS2008)
1871 chan->ch_monprm->mp_connid = offer->chm_connid;
1872
1873 if (offer->chm_flags1 & VMBUS_CHOFFER_FLAG1_HASMNF) {
1874 int trig_idx;
1875
1876 /*
1877 * Setup MNF stuffs.
1878 */
1879 chan->ch_txflags |= VMBUS_CHAN_TXF_HASMNF;
1880
1881 trig_idx = offer->chm_montrig / VMBUS_MONTRIG_LEN;
1882 if (trig_idx >= VMBUS_MONTRIGS_MAX)
1883 panic("invalid monitor trigger %u", offer->chm_montrig);
1884 chan->ch_montrig =
1885 &sc->vmbus_mnf2->mnf_trigs[trig_idx].mt_pending;
1886
1887 chan->ch_montrig_mask =
1888 1 << (offer->chm_montrig % VMBUS_MONTRIG_LEN);
1889 }
1890
1891 if (offer->chm_chflags & VMBUS_CHAN_TLNPI_PROVIDER_OFFER) {
1892 /* This is HyperV socket channel */
1893 chan->ch_is_hvs = true;
1894 /* The first byte != 0 means the host initiated connection. */
1895 chan->ch_hvs_conn_from_host =
1896 offer->chm_udata.pipe.user_def[0];
1897
1898 if (bootverbose) {
1899 device_printf(sc->vmbus_dev,
1900 "chan%u is hyperv socket channel "
1901 "connected %s host\n",
1902 chan->ch_id,
1903 (chan->ch_hvs_conn_from_host != 0) ?
1904 "from" : "to");
1905 }
1906 } else {
1907 chan->ch_is_hvs = false;
1908 }
1909
1910 /*
1911 * Setup event flag.
1912 */
1913 chan->ch_evtflag =
1914 &sc->vmbus_tx_evtflags[chan->ch_id / VMBUS_EVTFLAG_LEN];
1915 chan->ch_evtflag_mask = 1UL << (chan->ch_id & VMBUS_EVTFLAG_MASK);
1916
1917 /*
1918 * Setup attach and detach tasks.
1919 */
1920 if (VMBUS_CHAN_ISPRIMARY(chan)) {
1921 chan->ch_mgmt_tq = sc->vmbus_devtq;
1922 attach_fn = vmbus_prichan_attach_task;
1923 detach_fn = vmbus_prichan_detach_task;
1924 } else {
1925 chan->ch_mgmt_tq = sc->vmbus_subchtq;
1926 attach_fn = vmbus_subchan_attach_task;
1927 detach_fn = vmbus_subchan_detach_task;
1928 }
1929 TASK_INIT(&chan->ch_attach_task, 0, attach_fn, chan);
1930 TASK_INIT(&chan->ch_detach_task, 0, detach_fn, chan);
1931
1932 error = vmbus_chan_add(chan);
1933 if (error) {
1934 device_printf(sc->vmbus_dev, "add chan%u failed: %d\n",
1935 chan->ch_id, error);
1936 atomic_subtract_int(&chan->ch_refs, 1);
1937 vmbus_chan_free(chan);
1938 return;
1939 }
1940 taskqueue_enqueue(chan->ch_mgmt_tq, &chan->ch_attach_task);
1941 }
1942
1943 static void
vmbus_chan_msgproc_chrescind(struct vmbus_softc * sc,const struct vmbus_message * msg)1944 vmbus_chan_msgproc_chrescind(struct vmbus_softc *sc,
1945 const struct vmbus_message *msg)
1946 {
1947 const struct vmbus_chanmsg_chrescind *note;
1948 struct vmbus_channel *chan;
1949
1950 note = (const struct vmbus_chanmsg_chrescind *)msg->msg_data;
1951 if (note->chm_chanid > VMBUS_CHAN_MAX) {
1952 device_printf(sc->vmbus_dev, "invalid revoked chan%u\n",
1953 note->chm_chanid);
1954 return;
1955 }
1956
1957 /*
1958 * Find and remove the target channel from the channel list.
1959 */
1960 mtx_lock(&sc->vmbus_chan_lock);
1961 TAILQ_FOREACH(chan, &sc->vmbus_chans, ch_link) {
1962 if (chan->ch_id == note->chm_chanid)
1963 break;
1964 }
1965 if (chan == NULL) {
1966 mtx_unlock(&sc->vmbus_chan_lock);
1967 device_printf(sc->vmbus_dev, "chan%u is not offered\n",
1968 note->chm_chanid);
1969 return;
1970 }
1971 mtx_unlock(&sc->vmbus_chan_lock);
1972
1973 if (chan->ch_dev && chan->ch_rescind_cb) {
1974 chan->ch_rescind_cb(chan);
1975 return;
1976 }
1977
1978 mtx_lock(&sc->vmbus_chan_lock);
1979 vmbus_chan_rem_list(sc, chan);
1980 mtx_unlock(&sc->vmbus_chan_lock);
1981
1982 if (VMBUS_CHAN_ISPRIMARY(chan)) {
1983 /*
1984 * The target channel is a primary channel; remove the
1985 * target channel from the primary channel list now,
1986 * instead of later, so that it will not be found by
1987 * other sub-channel offers, which are processed in
1988 * this thread.
1989 */
1990 mtx_lock(&sc->vmbus_prichan_lock);
1991 vmbus_chan_rem_prilist(sc, chan);
1992 mtx_unlock(&sc->vmbus_prichan_lock);
1993 }
1994
1995 /*
1996 * NOTE:
1997 * The following processing order is critical:
1998 * Set the REVOKED state flag before orphaning the installed xact.
1999 */
2000
2001 if (atomic_testandset_int(&chan->ch_stflags,
2002 VMBUS_CHAN_ST_REVOKED_SHIFT))
2003 panic("channel has already been revoked");
2004
2005 sx_xlock(&chan->ch_orphan_lock);
2006 if (chan->ch_orphan_xact != NULL)
2007 vmbus_xact_ctx_orphan(chan->ch_orphan_xact);
2008 sx_xunlock(&chan->ch_orphan_lock);
2009
2010 if (bootverbose)
2011 vmbus_chan_printf(chan, "chan%u revoked\n", note->chm_chanid);
2012 vmbus_chan_detach(chan);
2013 }
2014
2015 static int
vmbus_chan_release(struct vmbus_channel * chan)2016 vmbus_chan_release(struct vmbus_channel *chan)
2017 {
2018 struct vmbus_softc *sc = chan->ch_vmbus;
2019 struct vmbus_chanmsg_chfree *req;
2020 struct vmbus_msghc *mh;
2021 int error;
2022
2023 mh = vmbus_msghc_get(sc, sizeof(*req));
2024 if (mh == NULL) {
2025 vmbus_chan_printf(chan,
2026 "can not get msg hypercall for chfree(chan%u)\n",
2027 chan->ch_id);
2028 return (ENXIO);
2029 }
2030
2031 req = vmbus_msghc_dataptr(mh);
2032 req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHFREE;
2033 req->chm_chanid = chan->ch_id;
2034
2035 error = vmbus_msghc_exec_noresult(mh);
2036 vmbus_msghc_put(sc, mh);
2037
2038 if (error) {
2039 vmbus_chan_printf(chan,
2040 "chfree(chan%u) msg hypercall exec failed: %d\n",
2041 chan->ch_id, error);
2042 } else {
2043 if (bootverbose)
2044 vmbus_chan_printf(chan, "chan%u freed\n", chan->ch_id);
2045 }
2046 return (error);
2047 }
2048
2049 static void
vmbus_prichan_detach_task(void * xchan,int pending __unused)2050 vmbus_prichan_detach_task(void *xchan, int pending __unused)
2051 {
2052 struct vmbus_channel *chan = xchan;
2053
2054 KASSERT(VMBUS_CHAN_ISPRIMARY(chan),
2055 ("chan%u is not primary channel", chan->ch_id));
2056
2057 /* Delete and detach the device associated with this channel. */
2058 vmbus_delete_child(chan);
2059
2060 /* Release this channel (back to vmbus). */
2061 vmbus_chan_release(chan);
2062
2063 /* Free this channel's resource. */
2064 vmbus_chan_free(chan);
2065 }
2066
2067 static void
vmbus_subchan_detach_task(void * xchan,int pending __unused)2068 vmbus_subchan_detach_task(void *xchan, int pending __unused)
2069 {
2070 struct vmbus_channel *chan = xchan;
2071 struct vmbus_channel *pri_chan = chan->ch_prichan;
2072
2073 KASSERT(!VMBUS_CHAN_ISPRIMARY(chan),
2074 ("chan%u is primary channel", chan->ch_id));
2075
2076 /* Release this channel (back to vmbus). */
2077 vmbus_chan_release(chan);
2078
2079 /* Unlink from its primary channel's sub-channel list. */
2080 mtx_lock(&pri_chan->ch_subchan_lock);
2081 vmbus_chan_rem_sublist(pri_chan, chan);
2082 mtx_unlock(&pri_chan->ch_subchan_lock);
2083 /* Notify anyone that is waiting for this sub-channel to vanish. */
2084 wakeup(pri_chan);
2085
2086 /* Free this channel's resource. */
2087 vmbus_chan_free(chan);
2088 }
2089
2090 static void
vmbus_prichan_attach_task(void * xchan,int pending __unused)2091 vmbus_prichan_attach_task(void *xchan, int pending __unused)
2092 {
2093
2094 /*
2095 * Add device for this primary channel.
2096 */
2097 vmbus_add_child(xchan);
2098 }
2099
2100 static void
vmbus_subchan_attach_task(void * xchan __unused,int pending __unused)2101 vmbus_subchan_attach_task(void *xchan __unused, int pending __unused)
2102 {
2103
2104 /* Nothing */
2105 }
2106
2107 void
vmbus_chan_destroy_all(struct vmbus_softc * sc)2108 vmbus_chan_destroy_all(struct vmbus_softc *sc)
2109 {
2110
2111 /*
2112 * Detach all devices and destroy the corresponding primary
2113 * channels.
2114 */
2115 for (;;) {
2116 struct vmbus_channel *chan;
2117
2118 mtx_lock(&sc->vmbus_chan_lock);
2119 TAILQ_FOREACH(chan, &sc->vmbus_chans, ch_link) {
2120 if (VMBUS_CHAN_ISPRIMARY(chan))
2121 break;
2122 }
2123 if (chan == NULL) {
2124 /* No more primary channels; done. */
2125 mtx_unlock(&sc->vmbus_chan_lock);
2126 break;
2127 }
2128 vmbus_chan_rem_list(sc, chan);
2129 mtx_unlock(&sc->vmbus_chan_lock);
2130
2131 mtx_lock(&sc->vmbus_prichan_lock);
2132 vmbus_chan_rem_prilist(sc, chan);
2133 mtx_unlock(&sc->vmbus_prichan_lock);
2134
2135 taskqueue_enqueue(chan->ch_mgmt_tq, &chan->ch_detach_task);
2136 }
2137 }
2138
2139 struct vmbus_channel **
vmbus_subchan_get(struct vmbus_channel * pri_chan,int subchan_cnt)2140 vmbus_subchan_get(struct vmbus_channel *pri_chan, int subchan_cnt)
2141 {
2142 struct vmbus_channel **ret, *chan;
2143 int i;
2144
2145 KASSERT(subchan_cnt > 0, ("invalid sub-channel count %d", subchan_cnt));
2146
2147 ret = malloc(subchan_cnt * sizeof(struct vmbus_channel *), M_TEMP,
2148 M_WAITOK);
2149
2150 mtx_lock(&pri_chan->ch_subchan_lock);
2151
2152 while (pri_chan->ch_subchan_cnt < subchan_cnt)
2153 mtx_sleep(pri_chan, &pri_chan->ch_subchan_lock, 0, "subch", 0);
2154
2155 i = 0;
2156 TAILQ_FOREACH(chan, &pri_chan->ch_subchans, ch_sublink) {
2157 /* TODO: refcnt chan */
2158 ret[i] = chan;
2159
2160 ++i;
2161 if (i == subchan_cnt)
2162 break;
2163 }
2164 KASSERT(i == subchan_cnt, ("invalid subchan count %d, should be %d",
2165 pri_chan->ch_subchan_cnt, subchan_cnt));
2166
2167 mtx_unlock(&pri_chan->ch_subchan_lock);
2168
2169 return ret;
2170 }
2171
2172 void
vmbus_subchan_rel(struct vmbus_channel ** subchan,int subchan_cnt __unused)2173 vmbus_subchan_rel(struct vmbus_channel **subchan, int subchan_cnt __unused)
2174 {
2175
2176 free(subchan, M_TEMP);
2177 }
2178
2179 void
vmbus_subchan_drain(struct vmbus_channel * pri_chan)2180 vmbus_subchan_drain(struct vmbus_channel *pri_chan)
2181 {
2182 mtx_lock(&pri_chan->ch_subchan_lock);
2183 while (pri_chan->ch_subchan_cnt > 0)
2184 mtx_sleep(pri_chan, &pri_chan->ch_subchan_lock, 0, "dsubch", 0);
2185 mtx_unlock(&pri_chan->ch_subchan_lock);
2186 }
2187
2188 void
vmbus_chan_msgproc(struct vmbus_softc * sc,const struct vmbus_message * msg)2189 vmbus_chan_msgproc(struct vmbus_softc *sc, const struct vmbus_message *msg)
2190 {
2191 vmbus_chanmsg_proc_t msg_proc;
2192 uint32_t msg_type;
2193
2194 msg_type = ((const struct vmbus_chanmsg_hdr *)msg->msg_data)->chm_type;
2195 KASSERT(msg_type < VMBUS_CHANMSG_TYPE_MAX,
2196 ("invalid message type %u", msg_type));
2197
2198 msg_proc = vmbus_chan_msgprocs[msg_type];
2199 if (msg_proc != NULL)
2200 msg_proc(sc, msg);
2201 }
2202
2203 void
vmbus_chan_set_readbatch(struct vmbus_channel * chan,bool on)2204 vmbus_chan_set_readbatch(struct vmbus_channel *chan, bool on)
2205 {
2206 if (!on)
2207 chan->ch_flags &= ~VMBUS_CHAN_FLAG_BATCHREAD;
2208 else
2209 chan->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD;
2210 }
2211
2212 uint32_t
vmbus_chan_id(const struct vmbus_channel * chan)2213 vmbus_chan_id(const struct vmbus_channel *chan)
2214 {
2215 return chan->ch_id;
2216 }
2217
2218 uint32_t
vmbus_chan_subidx(const struct vmbus_channel * chan)2219 vmbus_chan_subidx(const struct vmbus_channel *chan)
2220 {
2221 return chan->ch_subidx;
2222 }
2223
2224 bool
vmbus_chan_is_primary(const struct vmbus_channel * chan)2225 vmbus_chan_is_primary(const struct vmbus_channel *chan)
2226 {
2227 if (VMBUS_CHAN_ISPRIMARY(chan))
2228 return true;
2229 else
2230 return false;
2231 }
2232
2233 bool
vmbus_chan_is_hvs(const struct vmbus_channel * chan)2234 vmbus_chan_is_hvs(const struct vmbus_channel *chan)
2235 {
2236 return chan->ch_is_hvs;
2237 }
2238
2239 bool
vmbus_chan_is_hvs_conn_from_host(const struct vmbus_channel * chan)2240 vmbus_chan_is_hvs_conn_from_host(const struct vmbus_channel *chan)
2241 {
2242 KASSERT(vmbus_chan_is_hvs(chan) == true,
2243 ("Not a HyperV Socket channel %u", chan->ch_id));
2244 if (chan->ch_hvs_conn_from_host != 0)
2245 return true;
2246 else
2247 return false;
2248 }
2249
2250 struct hyperv_guid *
vmbus_chan_guid_type(struct vmbus_channel * chan)2251 vmbus_chan_guid_type(struct vmbus_channel *chan)
2252 {
2253 return &chan->ch_guid_type;
2254 }
2255
2256 struct hyperv_guid *
vmbus_chan_guid_inst(struct vmbus_channel * chan)2257 vmbus_chan_guid_inst(struct vmbus_channel *chan)
2258 {
2259 return &chan->ch_guid_inst;
2260 }
2261
2262 int
vmbus_chan_prplist_nelem(int br_size,int prpcnt_max,int dlen_max)2263 vmbus_chan_prplist_nelem(int br_size, int prpcnt_max, int dlen_max)
2264 {
2265 int elem_size;
2266
2267 elem_size = __offsetof(struct vmbus_chanpkt_prplist,
2268 cp_range[0].gpa_page[prpcnt_max]);
2269 elem_size += dlen_max;
2270 elem_size = VMBUS_CHANPKT_TOTLEN(elem_size);
2271
2272 return (vmbus_br_nelem(br_size, elem_size));
2273 }
2274
2275 bool
vmbus_chan_tx_empty(const struct vmbus_channel * chan)2276 vmbus_chan_tx_empty(const struct vmbus_channel *chan)
2277 {
2278
2279 return (vmbus_txbr_empty(&chan->ch_txbr));
2280 }
2281
2282 bool
vmbus_chan_rx_empty(const struct vmbus_channel * chan)2283 vmbus_chan_rx_empty(const struct vmbus_channel *chan)
2284 {
2285
2286 return (vmbus_rxbr_empty(&chan->ch_rxbr));
2287 }
2288
2289 static int
vmbus_chan_printf(const struct vmbus_channel * chan,const char * fmt,...)2290 vmbus_chan_printf(const struct vmbus_channel *chan, const char *fmt, ...)
2291 {
2292 va_list ap;
2293 device_t dev;
2294 int retval;
2295
2296 if (chan->ch_dev == NULL || !device_is_alive(chan->ch_dev))
2297 dev = chan->ch_vmbus->vmbus_dev;
2298 else
2299 dev = chan->ch_dev;
2300
2301 retval = device_print_prettyname(dev);
2302 va_start(ap, fmt);
2303 retval += vprintf(fmt, ap);
2304 va_end(ap);
2305
2306 return (retval);
2307 }
2308
2309 void
vmbus_chan_run_task(struct vmbus_channel * chan,struct task * task)2310 vmbus_chan_run_task(struct vmbus_channel *chan, struct task *task)
2311 {
2312
2313 taskqueue_enqueue(chan->ch_tq, task);
2314 taskqueue_drain(chan->ch_tq, task);
2315 }
2316
2317 struct taskqueue *
vmbus_chan_mgmt_tq(const struct vmbus_channel * chan)2318 vmbus_chan_mgmt_tq(const struct vmbus_channel *chan)
2319 {
2320
2321 return (chan->ch_mgmt_tq);
2322 }
2323
2324 bool
vmbus_chan_is_revoked(const struct vmbus_channel * chan)2325 vmbus_chan_is_revoked(const struct vmbus_channel *chan)
2326 {
2327
2328 if (chan->ch_stflags & VMBUS_CHAN_ST_REVOKED)
2329 return (true);
2330 return (false);
2331 }
2332
2333 void
vmbus_chan_set_orphan(struct vmbus_channel * chan,struct vmbus_xact_ctx * xact)2334 vmbus_chan_set_orphan(struct vmbus_channel *chan, struct vmbus_xact_ctx *xact)
2335 {
2336
2337 sx_xlock(&chan->ch_orphan_lock);
2338 chan->ch_orphan_xact = xact;
2339 sx_xunlock(&chan->ch_orphan_lock);
2340 }
2341
2342 void
vmbus_chan_unset_orphan(struct vmbus_channel * chan)2343 vmbus_chan_unset_orphan(struct vmbus_channel *chan)
2344 {
2345
2346 sx_xlock(&chan->ch_orphan_lock);
2347 chan->ch_orphan_xact = NULL;
2348 sx_xunlock(&chan->ch_orphan_lock);
2349 }
2350
2351 const void *
vmbus_chan_xact_wait(const struct vmbus_channel * chan,struct vmbus_xact * xact,size_t * resp_len,bool can_sleep)2352 vmbus_chan_xact_wait(const struct vmbus_channel *chan,
2353 struct vmbus_xact *xact, size_t *resp_len, bool can_sleep)
2354 {
2355 const void *ret;
2356
2357 if (can_sleep)
2358 ret = vmbus_xact_wait(xact, resp_len);
2359 else
2360 ret = vmbus_xact_busywait(xact, resp_len);
2361 if (vmbus_chan_is_revoked(chan)) {
2362 /*
2363 * This xact probably is interrupted, and the
2364 * interruption can race the reply reception,
2365 * so we have to make sure that there are nothing
2366 * left on the RX bufring, i.e. this xact will
2367 * not be touched, once this function returns.
2368 *
2369 * Since the hypervisor will not put more data
2370 * onto the RX bufring once the channel is revoked,
2371 * the following loop will be terminated, once all
2372 * data are drained by the driver's channel
2373 * callback.
2374 */
2375 while (!vmbus_chan_rx_empty(chan)) {
2376 if (can_sleep)
2377 pause("chxact", 1);
2378 else
2379 DELAY(1000);
2380 }
2381 }
2382 return (ret);
2383 }
2384
2385 void
vmbus_chan_poll_enable(struct vmbus_channel * chan,u_int pollhz)2386 vmbus_chan_poll_enable(struct vmbus_channel *chan, u_int pollhz)
2387 {
2388 struct vmbus_chan_pollarg arg;
2389 struct task poll_cfg;
2390
2391 KASSERT(chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD,
2392 ("enable polling on non-batch chan%u", chan->ch_id));
2393 KASSERT(pollhz >= VMBUS_CHAN_POLLHZ_MIN &&
2394 pollhz <= VMBUS_CHAN_POLLHZ_MAX, ("invalid pollhz %u", pollhz));
2395
2396 arg.poll_chan = chan;
2397 arg.poll_hz = pollhz;
2398 TASK_INIT(&poll_cfg, 0, vmbus_chan_pollcfg_task, &arg);
2399 vmbus_chan_run_task(chan, &poll_cfg);
2400 }
2401
2402 void
vmbus_chan_poll_disable(struct vmbus_channel * chan)2403 vmbus_chan_poll_disable(struct vmbus_channel *chan)
2404 {
2405 struct task poll_dis;
2406
2407 KASSERT(chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD,
2408 ("disable polling on non-batch chan%u", chan->ch_id));
2409
2410 TASK_INIT(&poll_dis, 0, vmbus_chan_polldis_task, chan);
2411 vmbus_chan_run_task(chan, &poll_dis);
2412 }
2413