Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
Show All 32 Lines | |||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/proc.h> | |||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/syslog.h> | #include <sys/syslog.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/rtprio.h> | #include <sys/rtprio.h> | ||||
#include <sys/interrupt.h> | #include <sys/interrupt.h> | ||||
#include <sys/sx.h> | #include <sys/sx.h> | ||||
#include <sys/taskqueue.h> | #include <sys/taskqueue.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
/** | /** | ||||
* @brief Interrupt filter routine for VMBUS. | * @brief Interrupt filter routine for VMBUS. | ||||
* | * | ||||
* The purpose of this routine is to determine the type of VMBUS protocol | * The purpose of this routine is to determine the type of VMBUS protocol | ||||
* message to process - an event or a channel message. | * message to process - an event or a channel message. | ||||
*/ | */ | ||||
static inline int | static inline int | ||||
hv_vmbus_isr(void *unused) | hv_vmbus_isr(struct trapframe *frame) | ||||
{ | { | ||||
int cpu; | int cpu; | ||||
hv_vmbus_message* msg; | hv_vmbus_message* msg; | ||||
hv_vmbus_synic_event_flags* event; | hv_vmbus_synic_event_flags* event; | ||||
void* page_addr; | void* page_addr; | ||||
cpu = PCPU_GET(cpuid); | cpu = PCPU_GET(cpuid); | ||||
Show All 23 Lines | if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) || | ||||
*/ | */ | ||||
swi_sched(hv_vmbus_g_context.event_swintr[cpu], 0); | swi_sched(hv_vmbus_g_context.event_swintr[cpu], 0); | ||||
} | } | ||||
/* Check if there are actual msgs to be process */ | /* Check if there are actual msgs to be process */ | ||||
page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu]; | page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu]; | ||||
msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT; | msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT; | ||||
/* we call eventtimer process the message */ | |||||
if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) { | |||||
msg->header.message_type = HV_MESSAGE_TYPE_NONE; | |||||
/* | |||||
* Make sure the write to message_type (ie set to | |||||
* HV_MESSAGE_TYPE_NONE) happens before we read the | |||||
* message_pending and EOMing. Otherwise, the EOMing will | |||||
* not deliver any more messages | |||||
* since there is no empty slot | |||||
*/ | |||||
wmb(); | |||||
if (msg->header.message_flags.u.message_pending) { | |||||
/* | |||||
* This will cause message queue rescan to possibly | |||||
* deliver another msg from the hypervisor | |||||
*/ | |||||
wrmsr(HV_X64_MSR_EOM, 0); | |||||
} | |||||
hv_et_intr(frame); | |||||
return (FILTER_HANDLED); | |||||
} | |||||
if (msg->header.message_type != HV_MESSAGE_TYPE_NONE) { | if (msg->header.message_type != HV_MESSAGE_TYPE_NONE) { | ||||
swi_sched(hv_vmbus_g_context.msg_swintr[cpu], 0); | swi_sched(hv_vmbus_g_context.msg_swintr[cpu], 0); | ||||
} | } | ||||
return FILTER_HANDLED; | return (FILTER_HANDLED); | ||||
} | } | ||||
#ifdef HV_DEBUG_INTR | #ifdef HV_DEBUG_INTR | ||||
uint32_t hv_intr_count = 0; | uint32_t hv_intr_count = 0; | ||||
#endif | #endif | ||||
uint32_t hv_vmbus_swintr_event_cpu[MAXCPU]; | uint32_t hv_vmbus_swintr_event_cpu[MAXCPU]; | ||||
uint32_t hv_vmbus_intr_cpu[MAXCPU]; | uint32_t hv_vmbus_intr_cpu[MAXCPU]; | ||||
Show All 13 Lines | #ifdef HV_DEBUG_INTR | ||||
/* | /* | ||||
* Do a little interrupt counting. | * Do a little interrupt counting. | ||||
*/ | */ | ||||
cpu = PCPU_GET(cpuid); | cpu = PCPU_GET(cpuid); | ||||
hv_vmbus_intr_cpu[cpu]++; | hv_vmbus_intr_cpu[cpu]++; | ||||
hv_intr_count++; | hv_intr_count++; | ||||
#endif | #endif | ||||
hv_vmbus_isr(NULL); | hv_vmbus_isr(trap_frame); | ||||
/* | /* | ||||
* Enable preemption. | * Enable preemption. | ||||
*/ | */ | ||||
critical_exit(); | critical_exit(); | ||||
} | } | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 507 Lines • Show Last 20 Lines |