Deleted Added
full compact
vmbus.c (293874) vmbus.c (294886)
1/*-
2 * Copyright (c) 2009-2012 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

--- 16 unchanged lines hidden (view full) ---

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>
1/*-
2 * Copyright (c) 2009-2012 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

--- 16 unchanged lines hidden (view full) ---

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: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c 293874 2016-01-14 03:11:35Z sephe $");
33__FBSDID("$FreeBSD: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c 294886 2016-01-27 03:53:30Z 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/proc.h>

--- 130 unchanged lines hidden (view full) ---

172 page_addr = hv_vmbus_g_context.syn_ic_event_page[cpu];
173 event = (hv_vmbus_synic_event_flags*)
174 page_addr + HV_VMBUS_MESSAGE_SINT;
175
176 if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) ||
177 (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) {
178 /* Since we are a child, we only need to check bit 0 */
179 if (synch_test_and_clear_bit(0, &event->flags32[0])) {
34
35#include <sys/param.h>
36#include <sys/bus.h>
37#include <sys/kernel.h>
38#include <sys/lock.h>
39#include <sys/malloc.h>
40#include <sys/module.h>
41#include <sys/proc.h>

--- 130 unchanged lines hidden (view full) ---

172 page_addr = hv_vmbus_g_context.syn_ic_event_page[cpu];
173 event = (hv_vmbus_synic_event_flags*)
174 page_addr + HV_VMBUS_MESSAGE_SINT;
175
176 if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) ||
177 (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) {
178 /* Since we are a child, we only need to check bit 0 */
179 if (synch_test_and_clear_bit(0, &event->flags32[0])) {
180 swi_sched(hv_vmbus_g_context.event_swintr[cpu], 0);
180 hv_vmbus_on_events(cpu);
181 }
182 } else {
183 /*
184 * On host with Win8 or above, we can directly look at
185 * the event page. If bit n is set, we have an interrupt
186 * on the channel with id n.
187 * Directly schedule the event software interrupt on
188 * current cpu.
189 */
181 }
182 } else {
183 /*
184 * On host with Win8 or above, we can directly look at
185 * the event page. If bit n is set, we have an interrupt
186 * on the channel with id n.
187 * Directly schedule the event software interrupt on
188 * current cpu.
189 */
190 swi_sched(hv_vmbus_g_context.event_swintr[cpu], 0);
190 hv_vmbus_on_events(cpu);
191 }
192
193 /* Check if there are actual msgs to be process */
194 page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu];
195 msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT;
196
197 /* we call eventtimer process the message */
198 if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) {

--- 21 unchanged lines hidden (view full) ---

220
221 if (msg->header.message_type != HV_MESSAGE_TYPE_NONE) {
222 swi_sched(hv_vmbus_g_context.msg_swintr[cpu], 0);
223 }
224
225 return (FILTER_HANDLED);
226}
227
191 }
192
193 /* Check if there are actual msgs to be process */
194 page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu];
195 msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT;
196
197 /* we call eventtimer process the message */
198 if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) {

--- 21 unchanged lines hidden (view full) ---

220
221 if (msg->header.message_type != HV_MESSAGE_TYPE_NONE) {
222 swi_sched(hv_vmbus_g_context.msg_swintr[cpu], 0);
223 }
224
225 return (FILTER_HANDLED);
226}
227
228uint32_t hv_vmbus_swintr_event_cpu[MAXCPU];
229u_long *hv_vmbus_intr_cpu[MAXCPU];
230
231void
232hv_vector_handler(struct trapframe *trap_frame)
233{
234 int cpu;
235
236 /*

--- 230 unchanged lines hidden (view full) ---

467 * - setup the vmbus root device
468 * - retrieve the channel offers
469 */
470static int
471vmbus_bus_init(void)
472{
473 int i, j, n, ret;
474 char buf[MAXCOMLEN + 1];
228u_long *hv_vmbus_intr_cpu[MAXCPU];
229
230void
231hv_vector_handler(struct trapframe *trap_frame)
232{
233 int cpu;
234
235 /*

--- 230 unchanged lines hidden (view full) ---

466 * - setup the vmbus root device
467 * - retrieve the channel offers
468 */
469static int
470vmbus_bus_init(void)
471{
472 int i, j, n, ret;
473 char buf[MAXCOMLEN + 1];
474 cpuset_t cpu_mask;
475
476 if (vmbus_inited)
477 return (0);
478
479 vmbus_inited = 1;
480
481 ret = hv_vmbus_init();
482

--- 20 unchanged lines hidden (view full) ---

503 hv_vmbus_g_context.hv_cb_vector);
504
505 /*
506 * Notify the hypervisor of our vector.
507 */
508 setup_args.vector = hv_vmbus_g_context.hv_cb_vector;
509
510 CPU_FOREACH(j) {
475
476 if (vmbus_inited)
477 return (0);
478
479 vmbus_inited = 1;
480
481 ret = hv_vmbus_init();
482

--- 20 unchanged lines hidden (view full) ---

503 hv_vmbus_g_context.hv_cb_vector);
504
505 /*
506 * Notify the hypervisor of our vector.
507 */
508 setup_args.vector = hv_vmbus_g_context.hv_cb_vector;
509
510 CPU_FOREACH(j) {
511 hv_vmbus_swintr_event_cpu[j] = 0;
512 hv_vmbus_g_context.hv_event_intr_event[j] = NULL;
513 hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
511 hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
514 hv_vmbus_g_context.event_swintr[j] = NULL;
515 hv_vmbus_g_context.msg_swintr[j] = NULL;
516
517 snprintf(buf, sizeof(buf), "cpu%d:hyperv", j);
518 intrcnt_add(buf, &hv_vmbus_intr_cpu[j]);
519
520 for (i = 0; i < 2; i++)
521 setup_args.page_buffers[2 * j + i] = NULL;
522 }
523
524 /*
525 * Per cpu setup.
526 */
527 CPU_FOREACH(j) {
528 /*
512 hv_vmbus_g_context.msg_swintr[j] = NULL;
513
514 snprintf(buf, sizeof(buf), "cpu%d:hyperv", j);
515 intrcnt_add(buf, &hv_vmbus_intr_cpu[j]);
516
517 for (i = 0; i < 2; i++)
518 setup_args.page_buffers[2 * j + i] = NULL;
519 }
520
521 /*
522 * Per cpu setup.
523 */
524 CPU_FOREACH(j) {
525 /*
526 * Setup taskqueue to handle events
527 */
528 hv_vmbus_g_context.hv_event_queue[j] = taskqueue_create_fast("hyperv event", M_WAITOK,
529 taskqueue_thread_enqueue, &hv_vmbus_g_context.hv_event_queue[j]);
530 if (hv_vmbus_g_context.hv_event_queue[j] == NULL) {
531 if (bootverbose)
532 printf("VMBUS: failed to setup taskqueue\n");
533 goto cleanup1;
534 }
535 CPU_SETOF(j, &cpu_mask);
536 taskqueue_start_threads_cpuset(&hv_vmbus_g_context.hv_event_queue[j], 1, PI_NET, &cpu_mask,
537 "hvevent%d", j);
538
539 /*
529 * Setup software interrupt thread and handler for msg handling.
530 */
531 ret = swi_add(&hv_vmbus_g_context.hv_msg_intr_event[j],
532 "hv_msg", vmbus_msg_swintr, (void *)(long)j, SWI_CLOCK, 0,
533 &hv_vmbus_g_context.msg_swintr[j]);
534 if (ret) {
535 if(bootverbose)
536 printf("VMBUS: failed to setup msg swi for "
537 "cpu %d\n", j);
538 goto cleanup1;
539 }
540
541 /*
542 * Bind the swi thread to the cpu.
543 */
544 ret = intr_event_bind(hv_vmbus_g_context.hv_msg_intr_event[j],
545 j);
540 * Setup software interrupt thread and handler for msg handling.
541 */
542 ret = swi_add(&hv_vmbus_g_context.hv_msg_intr_event[j],
543 "hv_msg", vmbus_msg_swintr, (void *)(long)j, SWI_CLOCK, 0,
544 &hv_vmbus_g_context.msg_swintr[j]);
545 if (ret) {
546 if(bootverbose)
547 printf("VMBUS: failed to setup msg swi for "
548 "cpu %d\n", j);
549 goto cleanup1;
550 }
551
552 /*
553 * Bind the swi thread to the cpu.
554 */
555 ret = intr_event_bind(hv_vmbus_g_context.hv_msg_intr_event[j],
556 j);
546 if (ret) {
557 if (ret) {
547 if(bootverbose)
548 printf("VMBUS: failed to bind msg swi thread "
549 "to cpu %d\n", j);
550 goto cleanup1;
551 }
552
553 /*
558 if(bootverbose)
559 printf("VMBUS: failed to bind msg swi thread "
560 "to cpu %d\n", j);
561 goto cleanup1;
562 }
563
564 /*
554 * Setup software interrupt thread and handler for
555 * event handling.
556 */
557 ret = swi_add(&hv_vmbus_g_context.hv_event_intr_event[j],
558 "hv_event", hv_vmbus_on_events, (void *)(long)j,
559 SWI_CLOCK, 0, &hv_vmbus_g_context.event_swintr[j]);
560 if (ret) {
561 if(bootverbose)
562 printf("VMBUS: failed to setup event swi for "
563 "cpu %d\n", j);
564 goto cleanup1;
565 }
566
567 /*
568 * Prepare the per cpu msg and event pages to be called on each cpu.
569 */
570 for(i = 0; i < 2; i++) {
571 setup_args.page_buffers[2 * j + i] =
572 malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO);
573 if (setup_args.page_buffers[2 * j + i] == NULL) {
574 KASSERT(setup_args.page_buffers[2 * j + i] != NULL,
575 ("Error VMBUS: malloc failed!"));

--- 26 unchanged lines hidden (view full) ---

602 for (n = 0; n < 2 * MAXCPU; n++)
603 if (setup_args.page_buffers[n] != NULL)
604 free(setup_args.page_buffers[n], M_DEVBUF);
605
606 /*
607 * remove swi and vmbus callback vector;
608 */
609 CPU_FOREACH(j) {
565 * Prepare the per cpu msg and event pages to be called on each cpu.
566 */
567 for(i = 0; i < 2; i++) {
568 setup_args.page_buffers[2 * j + i] =
569 malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO);
570 if (setup_args.page_buffers[2 * j + i] == NULL) {
571 KASSERT(setup_args.page_buffers[2 * j + i] != NULL,
572 ("Error VMBUS: malloc failed!"));

--- 26 unchanged lines hidden (view full) ---

599 for (n = 0; n < 2 * MAXCPU; n++)
600 if (setup_args.page_buffers[n] != NULL)
601 free(setup_args.page_buffers[n], M_DEVBUF);
602
603 /*
604 * remove swi and vmbus callback vector;
605 */
606 CPU_FOREACH(j) {
607 if (hv_vmbus_g_context.hv_event_queue[j] != NULL)
608 taskqueue_free(hv_vmbus_g_context.hv_event_queue[j]);
610 if (hv_vmbus_g_context.msg_swintr[j] != NULL)
611 swi_remove(hv_vmbus_g_context.msg_swintr[j]);
609 if (hv_vmbus_g_context.msg_swintr[j] != NULL)
610 swi_remove(hv_vmbus_g_context.msg_swintr[j]);
612 if (hv_vmbus_g_context.event_swintr[j] != NULL)
613 swi_remove(hv_vmbus_g_context.event_swintr[j]);
614 hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
611 hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
615 hv_vmbus_g_context.hv_event_intr_event[j] = NULL;
616 }
617
618 vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector);
619
620 cleanup:
621 hv_vmbus_cleanup();
622
623 return (ret);

--- 48 unchanged lines hidden (view full) ---

672 if (setup_args.page_buffers[i] != 0)
673 free(setup_args.page_buffers[i], M_DEVBUF);
674 }
675
676 hv_vmbus_cleanup();
677
678 /* remove swi */
679 CPU_FOREACH(i) {
612 }
613
614 vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector);
615
616 cleanup:
617 hv_vmbus_cleanup();
618
619 return (ret);

--- 48 unchanged lines hidden (view full) ---

668 if (setup_args.page_buffers[i] != 0)
669 free(setup_args.page_buffers[i], M_DEVBUF);
670 }
671
672 hv_vmbus_cleanup();
673
674 /* remove swi */
675 CPU_FOREACH(i) {
676 if (hv_vmbus_g_context.hv_event_queue[i] != NULL)
677 taskqueue_free(hv_vmbus_g_context.hv_event_queue[i]);
680 if (hv_vmbus_g_context.msg_swintr[i] != NULL)
681 swi_remove(hv_vmbus_g_context.msg_swintr[i]);
678 if (hv_vmbus_g_context.msg_swintr[i] != NULL)
679 swi_remove(hv_vmbus_g_context.msg_swintr[i]);
682 if (hv_vmbus_g_context.event_swintr[i] != NULL)
683 swi_remove(hv_vmbus_g_context.event_swintr[i]);
684 hv_vmbus_g_context.hv_msg_intr_event[i] = NULL;
680 hv_vmbus_g_context.hv_msg_intr_event[i] = NULL;
685 hv_vmbus_g_context.hv_event_intr_event[i] = NULL;
686 }
687
688 vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector);
689
690 return;
691}
692
693static void

--- 72 unchanged lines hidden ---
681 }
682
683 vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector);
684
685 return;
686}
687
688static void

--- 72 unchanged lines hidden ---