Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F132511535
D4676.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D4676.diff
View Options
Index: head/sys/conf/files.amd64
===================================================================
--- head/sys/conf/files.amd64
+++ head/sys/conf/files.amd64
@@ -273,6 +273,7 @@
dev/hyperv/vmbus/hv_channel_mgmt.c optional hyperv
dev/hyperv/vmbus/hv_connection.c optional hyperv
dev/hyperv/vmbus/hv_hv.c optional hyperv
+dev/hyperv/vmbus/hv_et.c optional hyperv
dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv
dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c optional hyperv
dev/nfe/if_nfe.c optional nfe pci
Index: head/sys/conf/files.i386
===================================================================
--- head/sys/conf/files.i386
+++ head/sys/conf/files.i386
@@ -247,6 +247,7 @@
dev/hyperv/vmbus/hv_channel_mgmt.c optional hyperv
dev/hyperv/vmbus/hv_connection.c optional hyperv
dev/hyperv/vmbus/hv_hv.c optional hyperv
+dev/hyperv/vmbus/hv_et.c optional hyperv
dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv
dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c optional hyperv
dev/ichwd/ichwd.c optional ichwd
Index: head/sys/dev/hyperv/vmbus/hv_et.c
===================================================================
--- head/sys/dev/hyperv/vmbus/hv_et.c
+++ head/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);
+}
+
Index: head/sys/dev/hyperv/vmbus/hv_hv.c
===================================================================
--- head/sys/dev/hyperv/vmbus/hv_hv.c
+++ head/sys/dev/hyperv/vmbus/hv_hv.c
@@ -45,12 +45,6 @@
#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
@@ -218,6 +212,8 @@
hv_vmbus_g_context.hypercall_page = virt_addr;
tc_init(&hv_timecounter); /* register virtual timecount */
+
+ hv_et_init();
return (0);
Index: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
===================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
@@ -38,6 +38,7 @@
#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>
@@ -153,7 +154,7 @@
* 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;
@@ -193,11 +194,35 @@
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
@@ -227,7 +252,7 @@
hv_intr_count++;
#endif
- hv_vmbus_isr(NULL);
+ hv_vmbus_isr(trap_frame);
/*
* Enable preemption.
Index: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
===================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -359,11 +359,6 @@
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 @@
} 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 @@
} 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 @@
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 @@
#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_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.
Index: head/sys/modules/hyperv/vmbus/Makefile
===================================================================
--- head/sys/modules/hyperv/vmbus/Makefile
+++ head/sys/modules/hyperv/vmbus/Makefile
@@ -7,6 +7,7 @@
SRCS= hv_channel.c \
hv_channel_mgmt.c \
hv_connection.c \
+ hv_et.c \
hv_hv.c \
hv_ring_buffer.c \
hv_vmbus_drv_freebsd.c \
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 18, 1:12 PM (2 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23881218
Default Alt Text
D4676.diff (10 KB)
Attached To
Mode
D4676: Eventtimer for Hyper-V
Attached
Detach File
Event Timeline
Log In to Comment