summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv/vmbus
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-02-19 02:03:14 +0000
committersephe <sephe@FreeBSD.org>2016-02-19 02:03:14 +0000
commit427bb5d10fd29ef038c6a4f6df3160e9c77f1b24 (patch)
tree9dc5d5a4a2fc61ccf8579a3b76d30b2b1b3a99cd /sys/dev/hyperv/vmbus
parentbdaba1774dae36cadfb71e549a51d42677155f62 (diff)
downloadFreeBSD-src-427bb5d10fd29ef038c6a4f6df3160e9c77f1b24.zip
FreeBSD-src-427bb5d10fd29ef038c6a4f6df3160e9c77f1b24.tar.gz
MFC [Hyper-V]: r293719-r293722, r293869-r293871, r293873-r293875, r293877
r293719 hyperv/hn: Implement LRO r293720 hyperv/hn: Implement SIOC[SG]IFMEDIA support r293721 hyperv/hn: Avoid mbuf cluster allocation, if the packet is small. r293722 hyperv/hn: Removed unused netvsc_init() r293869 hyperv/hn: Unbreak LINT-NOIP r293870 hyperv: use x86 generic code to do the hypervisor detection r293871 hyperv: remove unused vmbus definitions r293873 hyperv: implement an event timer r293874 hyperv: add interrupt counters r293875 hyperv: set receive buffer size according to NVSP protocol version r293877 Unbreak `make depend` with sys/modules/hyperv/vmbus after r293870 Approved by: re (glebius), adrian (mentor) Sponsored by: Microsoft OSTC
Diffstat (limited to 'sys/dev/hyperv/vmbus')
-rw-r--r--sys/dev/hyperv/vmbus/hv_connection.c19
-rw-r--r--sys/dev/hyperv/vmbus/hv_et.c131
-rw-r--r--sys/dev/hyperv/vmbus/hv_hv.c61
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c78
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_priv.h57
5 files changed, 234 insertions, 112 deletions
diff --git a/sys/dev/hyperv/vmbus/hv_connection.c b/sys/dev/hyperv/vmbus/hv_connection.c
index cc83037..7496288 100644
--- a/sys/dev/hyperv/vmbus/hv_connection.c
+++ b/sys/dev/hyperv/vmbus/hv_connection.c
@@ -254,7 +254,7 @@ hv_vmbus_connect(void) {
hv_vmbus_protocal_version = version;
if (bootverbose)
- printf("VMBUS: Portocal Version: %d.%d\n",
+ printf("VMBUS: Protocol Version: %d.%d\n",
version >> 16, version & 0xFFFF);
sema_destroy(&msg_info->wait_sema);
@@ -426,12 +426,6 @@ VmbusProcessChannelEvent(uint32_t relid)
// mtx_unlock(&channel->inbound_lock);
}
-#ifdef HV_DEBUG_INTR
-extern uint32_t hv_intr_count;
-extern uint32_t hv_vmbus_swintr_event_cpu[MAXCPU];
-extern uint32_t hv_vmbus_intr_cpu[MAXCPU];
-#endif
-
/**
* Handler for events
*/
@@ -452,17 +446,6 @@ hv_vmbus_on_events(void *arg)
KASSERT(cpu <= mp_maxid, ("VMBUS: hv_vmbus_on_events: "
"cpu out of range!"));
-#ifdef HV_DEBUG_INTR
- int i;
- hv_vmbus_swintr_event_cpu[cpu]++;
- if (hv_intr_count % 10000 == 0) {
- printf("VMBUS: Total interrupt %d\n", hv_intr_count);
- for (i = 0; i < mp_ncpus; i++)
- printf("VMBUS: hw cpu[%d]: %d, event sw intr cpu[%d]: %d\n",
- i, hv_vmbus_intr_cpu[i], i, hv_vmbus_swintr_event_cpu[i]);
- }
-#endif
-
if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) ||
(hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) {
maxdword = HV_MAX_NUM_CHANNELS_SUPPORTED >> 5;
diff --git a/sys/dev/hyperv/vmbus/hv_et.c b/sys/dev/hyperv/vmbus/hv_et.c
new file mode 100644
index 0000000..d961486
--- /dev/null
+++ b/sys/dev/hyperv/vmbus/hv_et.c
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 2015 Microsoft Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/smp.h>
+#include <sys/time.h>
+#include <sys/timeet.h>
+
+#include "hv_vmbus_priv.h"
+
+#define HV_TIMER_FREQUENCY (10 * 1000 * 1000LL) /* 100ns period */
+#define HV_MAX_DELTA_TICKS 0xffffffffLL
+#define HV_MIN_DELTA_TICKS 1LL
+
+static struct eventtimer et;
+static uint64_t periodticks[MAXCPU];
+
+static inline uint64_t
+sbintime2tick(sbintime_t time)
+{
+ struct timespec val;
+
+ val = sbttots(time);
+ return val.tv_sec * HV_TIMER_FREQUENCY + val.tv_nsec / 100;
+}
+
+static int
+hv_et_start(struct eventtimer *et, sbintime_t firsttime, sbintime_t periodtime)
+{
+ union hv_timer_config timer_cfg;
+ uint64_t current;
+
+ timer_cfg.as_uint64 = 0;
+ timer_cfg.auto_enable = 1;
+ timer_cfg.sintx = HV_VMBUS_MESSAGE_SINT;
+
+ periodticks[curcpu] = sbintime2tick(periodtime);
+ if (firsttime == 0)
+ firsttime = periodtime;
+
+ current = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
+ current += sbintime2tick(firsttime);
+
+ wrmsr(HV_X64_MSR_STIMER0_CONFIG, timer_cfg.as_uint64);
+ wrmsr(HV_X64_MSR_STIMER0_COUNT, current);
+
+ return (0);
+}
+
+static int
+hv_et_stop(struct eventtimer *et)
+{
+ wrmsr(HV_X64_MSR_STIMER0_CONFIG, 0);
+ wrmsr(HV_X64_MSR_STIMER0_COUNT, 0);
+
+ return (0);
+}
+
+void
+hv_et_intr(struct trapframe *frame)
+{
+ union hv_timer_config timer_cfg;
+ struct trapframe *oldframe;
+ struct thread *td;
+
+ if (periodticks[curcpu] != 0) {
+ uint64_t tick = sbintime2tick(periodticks[curcpu]);
+ timer_cfg.as_uint64 = rdmsr(HV_X64_MSR_STIMER0_CONFIG);
+ timer_cfg.enable = 0;
+ timer_cfg.auto_enable = 1;
+ timer_cfg.periodic = 1;
+ periodticks[curcpu] = 0;
+
+ wrmsr(HV_X64_MSR_STIMER0_CONFIG, timer_cfg.as_uint64);
+ wrmsr(HV_X64_MSR_STIMER0_COUNT, tick);
+ }
+
+ if (et.et_active) {
+ td = curthread;
+ td->td_intr_nesting_level++;
+ oldframe = td->td_intr_frame;
+ td->td_intr_frame = frame;
+ et.et_event_cb(&et, et.et_arg);
+ td->td_intr_frame = oldframe;
+ td->td_intr_nesting_level--;
+ }
+}
+
+void
+hv_et_init(void)
+{
+ et.et_name = "HyperV";
+ et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERCPU | ET_FLAGS_PERIODIC;
+ et.et_quality = 1000;
+ et.et_frequency = HV_TIMER_FREQUENCY;
+ et.et_min_period = (1LL << 32) / HV_TIMER_FREQUENCY;
+ et.et_max_period = HV_MAX_DELTA_TICKS * ((1LL << 32) / HV_TIMER_FREQUENCY);
+ et.et_start = hv_et_start;
+ et.et_stop = hv_et_stop;
+ et.et_priv = &et;
+ et_register(&et);
+}
+
diff --git a/sys/dev/hyperv/vmbus/hv_hv.c b/sys/dev/hyperv/vmbus/hv_hv.c
index 84e2a5e..ca5641f 100644
--- a/sys/dev/hyperv/vmbus/hv_hv.c
+++ b/sys/dev/hyperv/vmbus/hv_hv.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/pcpu.h>
#include <sys/timetc.h>
#include <machine/bus.h>
+#include <machine/md_var.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
@@ -44,23 +45,11 @@ __FBSDID("$FreeBSD$");
#include "hv_vmbus_priv.h"
-#define HV_X64_MSR_GUEST_OS_ID 0x40000000
-
-#define HV_X64_CPUID_MIN 0x40000005
-#define HV_X64_CPUID_MAX 0x4000ffff
-#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
-
#define HV_NANOSECONDS_PER_SEC 1000000000L
static u_int hv_get_timecount(struct timecounter *tc);
-static inline void do_cpuid_inline(unsigned int op, unsigned int *eax,
- unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
- __asm__ __volatile__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx),
- "=d" (*edx) : "0" (op), "c" (ecx));
-}
-
/**
* Globals
*/
@@ -86,27 +75,10 @@ hv_get_timecount(struct timecounter *tc)
int
hv_vmbus_query_hypervisor_presence(void)
{
- u_int regs[4];
- int hyper_v_detected = 0;
-
- /*
- * When Xen is detected and native Xen PV support is enabled,
- * ignore Xen's HyperV emulation.
- */
- if (vm_guest == VM_GUEST_XEN)
+ if (vm_guest != VM_GUEST_HV)
return (0);
- do_cpuid(1, regs);
- if (regs[2] & 0x80000000) { /* if(a hypervisor is detected) */
- /* make sure this really is Hyper-V */
- /* we look at the CPUID info */
- do_cpuid(HV_X64_MSR_GUEST_OS_ID, regs);
- hyper_v_detected =
- regs[0] >= HV_X64_CPUID_MIN &&
- regs[0] <= HV_X64_CPUID_MAX &&
- !memcmp("Microsoft Hv", &regs[1], 12);
- }
- return (hyper_v_detected);
+ return (hv_high >= HV_X64_CPUID_MIN && hv_high <= HV_X64_CPUID_MAX);
}
/**
@@ -115,10 +87,7 @@ hv_vmbus_query_hypervisor_presence(void)
static int
hv_vmbus_get_hypervisor_version(void)
{
- unsigned int eax;
- unsigned int ebx;
- unsigned int ecx;
- unsigned int edx;
+ u_int regs[4];
unsigned int maxLeaf;
unsigned int op;
@@ -127,28 +96,16 @@ hv_vmbus_get_hypervisor_version(void)
* Viridian is present
* Query id and revision.
*/
- eax = 0;
- ebx = 0;
- ecx = 0;
- edx = 0;
op = HV_CPU_ID_FUNCTION_HV_VENDOR_AND_MAX_FUNCTION;
- do_cpuid_inline(op, &eax, &ebx, &ecx, &edx);
+ do_cpuid(op, regs);
- maxLeaf = eax;
- eax = 0;
- ebx = 0;
- ecx = 0;
- edx = 0;
+ maxLeaf = regs[0];
op = HV_CPU_ID_FUNCTION_HV_INTERFACE;
- do_cpuid_inline(op, &eax, &ebx, &ecx, &edx);
+ do_cpuid(op, regs);
if (maxLeaf >= HV_CPU_ID_FUNCTION_MS_HV_VERSION) {
- eax = 0;
- ebx = 0;
- ecx = 0;
- edx = 0;
op = HV_CPU_ID_FUNCTION_MS_HV_VERSION;
- do_cpuid_inline(op, &eax, &ebx, &ecx, &edx);
+ do_cpuid(op, regs);
}
return (maxLeaf);
}
@@ -255,6 +212,8 @@ hv_vmbus_init(void)
hv_vmbus_g_context.hypercall_page = virt_addr;
tc_init(&hv_timecounter); /* register virtual timecount */
+
+ hv_et_init();
return (0);
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
index f7eae26..66a3f39 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
+#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/systm.h>
@@ -60,13 +61,15 @@ __FBSDID("$FreeBSD$");
#include "hv_vmbus_priv.h"
-
-#define VMBUS_IRQ 0x5
+#include <contrib/dev/acpica/include/acpi.h>
+#include "acpi_if.h"
static device_t vmbus_devp;
static int vmbus_inited;
static hv_setup_args setup_args; /* only CPU 0 supported at this time */
+static char *vmbus_ids[] = { "VMBUS", NULL };
+
/**
* @brief Software interrupt thread routine to handle channel messages from
* the hypervisor.
@@ -151,7 +154,7 @@ handled:
* message to process - an event or a channel message.
*/
static inline int
-hv_vmbus_isr(void *unused)
+hv_vmbus_isr(struct trapframe *frame)
{
int cpu;
hv_vmbus_message* msg;
@@ -191,41 +194,57 @@ hv_vmbus_isr(void *unused)
page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu];
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) {
swi_sched(hv_vmbus_g_context.msg_swintr[cpu], 0);
}
- return FILTER_HANDLED;
+ return (FILTER_HANDLED);
}
-#ifdef HV_DEBUG_INTR
-uint32_t hv_intr_count = 0;
-#endif
uint32_t hv_vmbus_swintr_event_cpu[MAXCPU];
-uint32_t hv_vmbus_intr_cpu[MAXCPU];
+u_long *hv_vmbus_intr_cpu[MAXCPU];
void
hv_vector_handler(struct trapframe *trap_frame)
{
-#ifdef HV_DEBUG_INTR
int cpu;
-#endif
/*
* Disable preemption.
*/
critical_enter();
-#ifdef HV_DEBUG_INTR
/*
* Do a little interrupt counting.
*/
cpu = PCPU_GET(cpuid);
- hv_vmbus_intr_cpu[cpu]++;
- hv_intr_count++;
-#endif
+ (*hv_vmbus_intr_cpu[cpu])++;
- hv_vmbus_isr(NULL);
+ hv_vmbus_isr(trap_frame);
/*
* Enable preemption.
@@ -350,25 +369,15 @@ hv_vmbus_child_device_unregister(struct hv_device *child_dev)
return(ret);
}
-static void
-vmbus_identify(driver_t *driver, device_t parent)
-{
- if (!hv_vmbus_query_hypervisor_presence())
- return;
-
- vm_guest = VM_GUEST_HV;
-
- BUS_ADD_CHILD(parent, 0, "vmbus", 0);
-}
-
static int
vmbus_probe(device_t dev) {
- if(bootverbose)
- device_printf(dev, "VMBUS: probe\n");
+ if (ACPI_ID_PROBE(device_get_parent(dev), dev, vmbus_ids) == NULL ||
+ device_get_unit(dev) != 0)
+ return (ENXIO);
device_set_desc(dev, "Vmbus Devices");
- return (BUS_PROBE_NOWILDCARD);
+ return (BUS_PROBE_DEFAULT);
}
#ifdef HYPERV
@@ -462,6 +471,7 @@ static int
vmbus_bus_init(void)
{
int i, j, n, ret;
+ char buf[MAXCOMLEN + 1];
if (vmbus_inited)
return (0);
@@ -498,13 +508,15 @@ vmbus_bus_init(void)
setup_args.vector = hv_vmbus_g_context.hv_cb_vector;
CPU_FOREACH(j) {
- hv_vmbus_intr_cpu[j] = 0;
hv_vmbus_swintr_event_cpu[j] = 0;
hv_vmbus_g_context.hv_event_intr_event[j] = NULL;
hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
hv_vmbus_g_context.event_swintr[j] = NULL;
hv_vmbus_g_context.msg_swintr[j] = NULL;
+ snprintf(buf, sizeof(buf), "cpu%d:hyperv", j);
+ intrcnt_add(buf, &hv_vmbus_intr_cpu[j]);
+
for (i = 0; i < 2; i++)
setup_args.page_buffers[2 * j + i] = NULL;
}
@@ -723,7 +735,6 @@ vmbus_modevent(module_t mod, int what, void *arg)
static device_method_t vmbus_methods[] = {
/** Device interface */
- DEVMETHOD(device_identify, vmbus_identify),
DEVMETHOD(device_probe, vmbus_probe),
DEVMETHOD(device_attach, vmbus_attach),
DEVMETHOD(device_detach, vmbus_detach),
@@ -745,8 +756,9 @@ static driver_t vmbus_driver = { driver_name, vmbus_methods,0, };
devclass_t vmbus_devclass;
-DRIVER_MODULE(vmbus, nexus, vmbus_driver, vmbus_devclass, vmbus_modevent, 0);
-MODULE_VERSION(vmbus,1);
+DRIVER_MODULE(vmbus, acpi, vmbus_driver, vmbus_devclass, vmbus_modevent, 0);
+MODULE_DEPEND(vmbus, acpi, 1, 1, 1);
+MODULE_VERSION(vmbus, 1);
/* We want to be started after SMP is initialized */
SYSINIT(vmb_init, SI_SUB_SMP + 1, SI_ORDER_FIRST, vmbus_init, NULL);
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
index 0503d06..74fe824 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -359,11 +359,6 @@ typedef struct {
struct sema control_sema;
} hv_vmbus_connection;
-/*
- * Declare the MSR used to identify the guest OS
- */
-#define HV_X64_MSR_GUEST_OS_ID 0x40000000
-
typedef union {
uint64_t as_uint64_t;
struct {
@@ -380,10 +375,6 @@ typedef union {
} u;
} hv_vmbus_x64_msr_guest_os_id_contents;
-/*
- * Declare the MSR used to setup pages used to communicate with the hypervisor
- */
-#define HV_X64_MSR_HYPERCALL 0x40000001
typedef union {
uint64_t as_uint64_t;
@@ -513,6 +504,22 @@ typedef union {
} hv_vmbus_synic_sint;
/*
+ * Timer configuration register.
+ */
+union hv_timer_config {
+ uint64_t as_uint64;
+ struct {
+ uint64_t enable:1;
+ uint64_t periodic:1;
+ uint64_t lazy:1;
+ uint64_t auto_enable:1;
+ uint64_t reserved_z0:12;
+ uint64_t sintx:4;
+ uint64_t reserved_z1:44;
+ };
+};
+
+/*
* Define syn_ic control register
*/
typedef union _hv_vmbus_synic_scontrol {
@@ -542,8 +549,21 @@ typedef union {
uint32_t flags32[HV_EVENT_FLAGS_DWORD_COUNT];
} hv_vmbus_synic_event_flags;
+#define HV_X64_CPUID_MIN (0x40000005)
+#define HV_X64_CPUID_MAX (0x4000ffff)
+
+/*
+ * Declare the MSR used to identify the guest OS
+ */
+#define HV_X64_MSR_GUEST_OS_ID (0x40000000)
+/*
+ * Declare the MSR used to setup pages used to communicate with the hypervisor
+ */
+#define HV_X64_MSR_HYPERCALL (0x40000001)
/* MSR used to provide vcpu index */
-#define HV_X64_MSR_VP_INDEX (0x40000002)
+#define HV_X64_MSR_VP_INDEX (0x40000002)
+
+#define HV_X64_MSR_TIME_REF_COUNT (0x40000020)
/*
* Define synthetic interrupt controller model specific registers
@@ -572,6 +592,18 @@ typedef union {
#define HV_X64_MSR_SINT15 (0x4000009F)
/*
+ * Synthetic Timer MSRs. Four timers per vcpu.
+ */
+#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0
+#define HV_X64_MSR_STIMER0_COUNT 0x400000B1
+#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2
+#define HV_X64_MSR_STIMER1_COUNT 0x400000B3
+#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4
+#define HV_X64_MSR_STIMER2_COUNT 0x400000B5
+#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
+#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
+
+/*
* Declare the various hypercall operations
*/
typedef enum {
@@ -678,6 +710,11 @@ int hv_vmbus_post_message(void *buffer, size_t buf_size);
int hv_vmbus_set_event(hv_vmbus_channel *channel);
void hv_vmbus_on_events(void *);
+/**
+ * Event Timer interfaces
+ */
+void hv_et_init(void);
+void hv_et_intr(struct trapframe*);
/*
* The guest OS needs to register the guest ID with the hypervisor.
OpenPOWER on IntegriCloud