diff options
Diffstat (limited to 'sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c')
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c | 98 |
1 files changed, 19 insertions, 79 deletions
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c index 669a532..8a07e45 100644 --- a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c +++ b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c @@ -117,8 +117,12 @@ handled: * message_pending and EOMing. Otherwise, the EOMing will * not deliver any more messages * since there is no empty slot + * + * NOTE: + * mb() is used here, since atomic_thread_fence_seq_cst() + * will become compiler fence on UP kernel. */ - atomic_thread_fence_seq_cst(); + mb(); if (msg->header.message_flags.u.message_pending) { /* @@ -190,8 +194,12 @@ hv_vmbus_isr(struct trapframe *frame) * message_pending and EOMing. Otherwise, the EOMing will * not deliver any more messages * since there is no empty slot + * + * NOTE: + * mb() is used here, since atomic_thread_fence_seq_cst() + * will become compiler fence on UP kernel. */ - atomic_thread_fence_seq_cst(); + mb(); if (msg->header.message_flags.u.message_pending) { /* @@ -383,80 +391,9 @@ vmbus_probe(device_t dev) { } #ifdef HYPERV -extern inthand_t IDTVEC(rsvd), IDTVEC(hv_vmbus_callback); - -/** - * @brief Find a free IDT slot and setup the interrupt handler. - */ -static int -vmbus_vector_alloc(void) -{ - int vector; - uintptr_t func; - struct gate_descriptor *ip; - - /* - * Search backwards form the highest IDT vector available for use - * as vmbus channel callback vector. We install 'hv_vmbus_callback' - * handler at that vector and use it to interrupt vcpus. - */ - vector = APIC_SPURIOUS_INT; - while (--vector >= APIC_IPI_INTS) { - ip = &idt[vector]; - func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset); - if (func == (uintptr_t)&IDTVEC(rsvd)) { -#ifdef __i386__ - setidt(vector , IDTVEC(hv_vmbus_callback), SDT_SYS386IGT, - SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); -#else - setidt(vector , IDTVEC(hv_vmbus_callback), SDT_SYSIGT, - SEL_KPL, 0); +extern inthand_t IDTVEC(hv_vmbus_callback); #endif - return (vector); - } - } - return (0); -} - -/** - * @brief Restore the IDT slot to rsvd. - */ -static void -vmbus_vector_free(int vector) -{ - uintptr_t func; - struct gate_descriptor *ip; - - if (vector == 0) - return; - - KASSERT(vector >= APIC_IPI_INTS && vector < APIC_SPURIOUS_INT, - ("invalid vector %d", vector)); - - ip = &idt[vector]; - func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset); - KASSERT(func == (uintptr_t)&IDTVEC(hv_vmbus_callback), - ("invalid vector %d", vector)); - - setidt(vector, IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0); -} - -#else /* HYPERV */ - -static int -vmbus_vector_alloc(void) -{ - return(0); -} - -static void -vmbus_vector_free(int vector) -{ -} - -#endif /* HYPERV */ - /** * @brief Main vmbus driver initialization routine. * @@ -489,12 +426,15 @@ vmbus_bus_init(void) return (ret); } +#ifdef HYPERV /* * Find a free IDT slot for vmbus callback. */ - hv_vmbus_g_context.hv_cb_vector = vmbus_vector_alloc(); - - if (hv_vmbus_g_context.hv_cb_vector == 0) { + hv_vmbus_g_context.hv_cb_vector = lapic_ipi_alloc(IDTVEC(hv_vmbus_callback)); +#else + hv_vmbus_g_context.hv_cb_vector = -1; +#endif + if (hv_vmbus_g_context.hv_cb_vector < 0) { if(bootverbose) printf("Error VMBUS: Cannot find free IDT slot for " "vmbus callback!\n"); @@ -587,7 +527,7 @@ vmbus_bus_init(void) } } - vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector); + lapic_ipi_free(hv_vmbus_g_context.hv_cb_vector); cleanup: hv_vmbus_cleanup(); @@ -655,7 +595,7 @@ vmbus_bus_exit(void) } } - vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector); + lapic_ipi_free(hv_vmbus_g_context.hv_cb_vector); return; } |