svn commit: r302116 - stable/10/sys/dev/hyperv/vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Thu Jun 23 05:35:10 UTC 2016
Author: sephe
Date: Thu Jun 23 05:35:08 2016
New Revision: 302116
URL: https://svnweb.freebsd.org/changeset/base/302116
Log:
MFC 300565,300567,300568,300570,300571
300565
hyperv/vmbus: Move vmbus interrupt counter into vmbus softc
MFC after: 1 week
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D6497
300567
hyperv/vmbus: Pass vmbus_softc and curcpu to hv_vmbus_isr()
MFC after: 1 week
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D6498
300568
hyperv/busdma: Take BUS_DMA_ZERO into account
MFC after: 1 week
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D6499
300570
hyperv/vmbus: Rename local variable and break long lines
No functional changes.
MFC after: 1 week
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D6500
300571
hyperv/vmbus: Move SynIC setup/teardown from hyperv file to vmbus file
Avoid unnecessary exposure.
MFC after: 1 week
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D6501
Modified:
stable/10/sys/dev/hyperv/vmbus/hv_hv.c
stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
stable/10/sys/dev/hyperv/vmbus/hyperv_busdma.c
stable/10/sys/dev/hyperv/vmbus/vmbus_var.h
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/hyperv/vmbus/hv_hv.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_hv.c Thu Jun 23 05:08:17 2016 (r302115)
+++ stable/10/sys/dev/hyperv/vmbus/hv_hv.c Thu Jun 23 05:35:08 2016 (r302116)
@@ -216,132 +216,6 @@ hv_vmbus_signal_event(void *con_id)
return (status);
}
-/**
- * @brief hv_vmbus_synic_init
- */
-void
-hv_vmbus_synic_init(void *arg)
-{
- struct vmbus_softc *sc = vmbus_get_softc();
- int cpu;
- uint64_t hv_vcpu_index;
- hv_vmbus_synic_simp simp;
- hv_vmbus_synic_siefp siefp;
- hv_vmbus_synic_scontrol sctrl;
- hv_vmbus_synic_sint shared_sint;
- uint64_t version;
- hv_setup_args* setup_args = (hv_setup_args *)arg;
-
- cpu = PCPU_GET(cpuid);
-
- /*
- * TODO: Check the version
- */
- version = rdmsr(HV_X64_MSR_SVERSION);
-
- hv_vmbus_g_context.syn_ic_msg_page[cpu] =
- setup_args->page_buffers[2 * cpu];
- hv_vmbus_g_context.syn_ic_event_page[cpu] =
- setup_args->page_buffers[2 * cpu + 1];
-
- /*
- * Setup the Synic's message page
- */
-
- simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
- simp.u.simp_enabled = 1;
- simp.u.base_simp_gpa = ((hv_get_phys_addr(
- hv_vmbus_g_context.syn_ic_msg_page[cpu])) >> PAGE_SHIFT);
-
- wrmsr(HV_X64_MSR_SIMP, simp.as_uint64_t);
-
- /*
- * Setup the Synic's event page
- */
- siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
- siefp.u.siefp_enabled = 1;
- siefp.u.base_siefp_gpa = ((hv_get_phys_addr(
- hv_vmbus_g_context.syn_ic_event_page[cpu])) >> PAGE_SHIFT);
-
- wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
-
- /*HV_SHARED_SINT_IDT_VECTOR + 0x20; */
- shared_sint.as_uint64_t = 0;
- shared_sint.u.vector = sc->vmbus_idtvec;
- shared_sint.u.masked = FALSE;
- shared_sint.u.auto_eoi = TRUE;
-
- wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
- shared_sint.as_uint64_t);
-
- wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT,
- shared_sint.as_uint64_t);
-
- /* Enable the global synic bit */
- sctrl.as_uint64_t = rdmsr(HV_X64_MSR_SCONTROL);
- sctrl.u.enable = 1;
-
- wrmsr(HV_X64_MSR_SCONTROL, sctrl.as_uint64_t);
-
- hv_vmbus_g_context.syn_ic_initialized = TRUE;
-
- /*
- * Set up the cpuid mapping from Hyper-V to FreeBSD.
- * The array is indexed using FreeBSD cpuid.
- */
- hv_vcpu_index = rdmsr(HV_X64_MSR_VP_INDEX);
- hv_vmbus_g_context.hv_vcpu_index[cpu] = (uint32_t)hv_vcpu_index;
-
- return;
-}
-
-/**
- * @brief Cleanup routine for hv_vmbus_synic_init()
- */
-void hv_vmbus_synic_cleanup(void *arg)
-{
- hv_vmbus_synic_sint shared_sint;
- hv_vmbus_synic_simp simp;
- hv_vmbus_synic_siefp siefp;
-
- if (!hv_vmbus_g_context.syn_ic_initialized)
- return;
-
- shared_sint.as_uint64_t = rdmsr(
- HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT);
-
- shared_sint.u.masked = 1;
-
- /*
- * Disable the interrupt 0
- */
- wrmsr(
- HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
- shared_sint.as_uint64_t);
-
- shared_sint.as_uint64_t = rdmsr(
- HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT);
-
- shared_sint.u.masked = 1;
-
- /*
- * Disable the interrupt 1
- */
- wrmsr(
- HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT,
- shared_sint.as_uint64_t);
- simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
- simp.u.simp_enabled = 0;
- simp.u.base_simp_gpa = 0;
-
- wrmsr(HV_X64_MSR_SIMP, simp.as_uint64_t);
-
- siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
- siefp.u.siefp_enabled = 0;
- siefp.u.base_siefp_gpa = 0;
-
- wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
-}
static bool
hyperv_identify(void)
Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c Thu Jun 23 05:08:17 2016 (r302115)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c Thu Jun 23 05:35:08 2016 (r302116)
@@ -131,11 +131,9 @@ handled:
* message to process - an event or a channel message.
*/
static inline int
-hv_vmbus_isr(struct trapframe *frame)
+hv_vmbus_isr(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
{
- struct vmbus_softc *sc = vmbus_get_softc();
hv_vmbus_message *msg, *msg_base;
- int cpu = curcpu;
/*
* The Windows team has advised that we check for events
@@ -186,12 +184,11 @@ hv_vmbus_isr(struct trapframe *frame)
return (FILTER_HANDLED);
}
-u_long *hv_vmbus_intr_cpu[MAXCPU];
-
void
hv_vector_handler(struct trapframe *trap_frame)
{
- int cpu;
+ struct vmbus_softc *sc = vmbus_get_softc();
+ int cpu = curcpu;
/*
* Disable preemption.
@@ -201,10 +198,9 @@ hv_vector_handler(struct trapframe *trap
/*
* Do a little interrupt counting.
*/
- cpu = PCPU_GET(cpuid);
- (*hv_vmbus_intr_cpu[cpu])++;
+ (*VMBUS_SC_PCPU_GET(sc, intr_cnt, cpu))++;
- hv_vmbus_isr(trap_frame);
+ hv_vmbus_isr(sc, trap_frame, cpu);
/*
* Enable preemption.
@@ -212,6 +208,126 @@ hv_vector_handler(struct trapframe *trap
critical_exit();
}
+static void
+vmbus_synic_setup(void *arg)
+{
+ struct vmbus_softc *sc = vmbus_get_softc();
+ int cpu;
+ uint64_t hv_vcpu_index;
+ hv_vmbus_synic_simp simp;
+ hv_vmbus_synic_siefp siefp;
+ hv_vmbus_synic_scontrol sctrl;
+ hv_vmbus_synic_sint shared_sint;
+ uint64_t version;
+ hv_setup_args* setup_args = (hv_setup_args *)arg;
+
+ cpu = PCPU_GET(cpuid);
+
+ /*
+ * TODO: Check the version
+ */
+ version = rdmsr(HV_X64_MSR_SVERSION);
+
+ hv_vmbus_g_context.syn_ic_msg_page[cpu] =
+ setup_args->page_buffers[2 * cpu];
+ hv_vmbus_g_context.syn_ic_event_page[cpu] =
+ setup_args->page_buffers[2 * cpu + 1];
+
+ /*
+ * Setup the Synic's message page
+ */
+
+ simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
+ simp.u.simp_enabled = 1;
+ simp.u.base_simp_gpa = ((hv_get_phys_addr(
+ hv_vmbus_g_context.syn_ic_msg_page[cpu])) >> PAGE_SHIFT);
+
+ wrmsr(HV_X64_MSR_SIMP, simp.as_uint64_t);
+
+ /*
+ * Setup the Synic's event page
+ */
+ siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
+ siefp.u.siefp_enabled = 1;
+ siefp.u.base_siefp_gpa = ((hv_get_phys_addr(
+ hv_vmbus_g_context.syn_ic_event_page[cpu])) >> PAGE_SHIFT);
+
+ wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
+
+ /*HV_SHARED_SINT_IDT_VECTOR + 0x20; */
+ shared_sint.as_uint64_t = 0;
+ shared_sint.u.vector = sc->vmbus_idtvec;
+ shared_sint.u.masked = FALSE;
+ shared_sint.u.auto_eoi = TRUE;
+
+ wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
+ shared_sint.as_uint64_t);
+
+ wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT,
+ shared_sint.as_uint64_t);
+
+ /* Enable the global synic bit */
+ sctrl.as_uint64_t = rdmsr(HV_X64_MSR_SCONTROL);
+ sctrl.u.enable = 1;
+
+ wrmsr(HV_X64_MSR_SCONTROL, sctrl.as_uint64_t);
+
+ hv_vmbus_g_context.syn_ic_initialized = TRUE;
+
+ /*
+ * Set up the cpuid mapping from Hyper-V to FreeBSD.
+ * The array is indexed using FreeBSD cpuid.
+ */
+ hv_vcpu_index = rdmsr(HV_X64_MSR_VP_INDEX);
+ hv_vmbus_g_context.hv_vcpu_index[cpu] = (uint32_t)hv_vcpu_index;
+}
+
+static void
+vmbus_synic_teardown(void *arg)
+{
+ hv_vmbus_synic_sint shared_sint;
+ hv_vmbus_synic_simp simp;
+ hv_vmbus_synic_siefp siefp;
+
+ if (!hv_vmbus_g_context.syn_ic_initialized)
+ return;
+
+ shared_sint.as_uint64_t = rdmsr(
+ HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT);
+
+ shared_sint.u.masked = 1;
+
+ /*
+ * Disable the interrupt 0
+ */
+ wrmsr(
+ HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
+ shared_sint.as_uint64_t);
+
+ shared_sint.as_uint64_t = rdmsr(
+ HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT);
+
+ shared_sint.u.masked = 1;
+
+ /*
+ * Disable the interrupt 1
+ */
+ wrmsr(
+ HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT,
+ shared_sint.as_uint64_t);
+ simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
+ simp.u.simp_enabled = 0;
+ simp.u.base_simp_gpa = 0;
+
+ wrmsr(HV_X64_MSR_SIMP, simp.as_uint64_t);
+
+ siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
+ siefp.u.siefp_enabled = 0;
+ siefp.u.base_siefp_gpa = 0;
+
+ wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
+}
+
static int
vmbus_read_ivar(
device_t dev,
@@ -444,7 +560,7 @@ static int
vmbus_bus_init(void)
{
struct vmbus_softc *sc;
- int i, j, n, ret;
+ int i, n, ret, cpu;
char buf[MAXCOMLEN + 1];
cpuset_t cpu_mask;
@@ -468,54 +584,63 @@ vmbus_bus_init(void)
sc->vmbus_idtvec);
}
- CPU_FOREACH(j) {
- snprintf(buf, sizeof(buf), "cpu%d:hyperv", j);
- intrcnt_add(buf, &hv_vmbus_intr_cpu[j]);
+ CPU_FOREACH(cpu) {
+ snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
+ intrcnt_add(buf, VMBUS_SC_PCPU_PTR(sc, intr_cnt, cpu));
for (i = 0; i < 2; i++)
- setup_args.page_buffers[2 * j + i] = NULL;
+ setup_args.page_buffers[2 * cpu + i] = NULL;
}
/*
* Per cpu setup.
*/
- CPU_FOREACH(j) {
+ CPU_FOREACH(cpu) {
struct task cpuset_task;
/*
* Setup taskqueue to handle events
*/
- hv_vmbus_g_context.hv_event_queue[j] = taskqueue_create_fast("hyperv event", M_WAITOK,
- taskqueue_thread_enqueue, &hv_vmbus_g_context.hv_event_queue[j]);
- taskqueue_start_threads(&hv_vmbus_g_context.hv_event_queue[j], 1, PI_NET,
- "hvevent%d", j);
-
- CPU_SETOF(j, &cpu_mask);
- TASK_INIT(&cpuset_task, 0, vmbus_cpuset_setthread_task, &cpu_mask);
- taskqueue_enqueue(hv_vmbus_g_context.hv_event_queue[j], &cpuset_task);
- taskqueue_drain(hv_vmbus_g_context.hv_event_queue[j], &cpuset_task);
+ hv_vmbus_g_context.hv_event_queue[cpu] =
+ taskqueue_create_fast("hyperv event", M_WAITOK,
+ taskqueue_thread_enqueue,
+ &hv_vmbus_g_context.hv_event_queue[cpu]);
+ taskqueue_start_threads(&hv_vmbus_g_context.hv_event_queue[cpu],
+ 1, PI_NET, "hvevent%d", cpu);
+
+ CPU_SETOF(cpu, &cpu_mask);
+ TASK_INIT(&cpuset_task, 0, vmbus_cpuset_setthread_task,
+ &cpu_mask);
+ taskqueue_enqueue(hv_vmbus_g_context.hv_event_queue[cpu],
+ &cpuset_task);
+ taskqueue_drain(hv_vmbus_g_context.hv_event_queue[cpu],
+ &cpuset_task);
/*
* Setup per-cpu tasks and taskqueues to handle msg.
*/
- hv_vmbus_g_context.hv_msg_tq[j] = taskqueue_create_fast(
+ hv_vmbus_g_context.hv_msg_tq[cpu] = taskqueue_create_fast(
"hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
- &hv_vmbus_g_context.hv_msg_tq[j]);
- taskqueue_start_threads(&hv_vmbus_g_context.hv_msg_tq[j], 1, PI_NET,
- "hvmsg%d", j);
- TASK_INIT(&hv_vmbus_g_context.hv_msg_task[j], 0,
+ &hv_vmbus_g_context.hv_msg_tq[cpu]);
+ taskqueue_start_threads(&hv_vmbus_g_context.hv_msg_tq[cpu], 1,
+ PI_NET, "hvmsg%d", cpu);
+ TASK_INIT(&hv_vmbus_g_context.hv_msg_task[cpu], 0,
vmbus_msg_task, NULL);
- CPU_SETOF(j, &cpu_mask);
- TASK_INIT(&cpuset_task, 0, vmbus_cpuset_setthread_task, &cpu_mask);
- taskqueue_enqueue(hv_vmbus_g_context.hv_msg_tq[j], &cpuset_task);
- taskqueue_drain(hv_vmbus_g_context.hv_msg_tq[j], &cpuset_task);
+ CPU_SETOF(cpu, &cpu_mask);
+ TASK_INIT(&cpuset_task, 0, vmbus_cpuset_setthread_task,
+ &cpu_mask);
+ taskqueue_enqueue(hv_vmbus_g_context.hv_msg_tq[cpu],
+ &cpuset_task);
+ taskqueue_drain(hv_vmbus_g_context.hv_msg_tq[cpu],
+ &cpuset_task);
/*
- * Prepare the per cpu msg and event pages to be called on each cpu.
+ * Prepare the per cpu msg and event pages to be called on
+ * each cpu.
*/
for(i = 0; i < 2; i++) {
- setup_args.page_buffers[2 * j + i] =
+ setup_args.page_buffers[2 * cpu + i] =
malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO);
}
}
@@ -524,7 +649,7 @@ vmbus_bus_init(void)
printf("VMBUS: Calling smp_rendezvous, smp_started = %d\n",
smp_started);
- smp_rendezvous(NULL, hv_vmbus_synic_init, NULL, &setup_args);
+ smp_rendezvous(NULL, vmbus_synic_setup, NULL, &setup_args);
/*
* Connect to VMBus in the root partition
@@ -559,10 +684,10 @@ vmbus_bus_init(void)
/*
* remove swi and vmbus callback vector;
*/
- CPU_FOREACH(j) {
- if (hv_vmbus_g_context.hv_event_queue[j] != NULL) {
- taskqueue_free(hv_vmbus_g_context.hv_event_queue[j]);
- hv_vmbus_g_context.hv_event_queue[j] = NULL;
+ CPU_FOREACH(cpu) {
+ if (hv_vmbus_g_context.hv_event_queue[cpu] != NULL) {
+ taskqueue_free(hv_vmbus_g_context.hv_event_queue[cpu]);
+ hv_vmbus_g_context.hv_event_queue[cpu] = NULL;
}
}
@@ -628,7 +753,7 @@ vmbus_detach(device_t dev)
hv_vmbus_release_unattached_channels();
hv_vmbus_disconnect();
- smp_rendezvous(NULL, hv_vmbus_synic_cleanup, NULL, NULL);
+ smp_rendezvous(NULL, vmbus_synic_teardown, NULL, NULL);
for(i = 0; i < 2 * MAXCPU; i++) {
if (setup_args.page_buffers[i] != NULL)
Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Thu Jun 23 05:08:17 2016 (r302115)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Thu Jun 23 05:35:08 2016 (r302116)
@@ -727,8 +727,6 @@ uint16_t hv_vmbus_post_msg_via_msg_ipc(
size_t payload_size);
uint16_t hv_vmbus_signal_event(void *con_id);
-void hv_vmbus_synic_init(void *irq_arg);
-void hv_vmbus_synic_cleanup(void *arg);
struct hv_device* hv_vmbus_child_device_create(
hv_guid device_type,
Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_busdma.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hyperv_busdma.c Thu Jun 23 05:08:17 2016 (r302115)
+++ stable/10/sys/dev/hyperv/vmbus/hyperv_busdma.c Thu Jun 23 05:35:08 2016 (r302116)
@@ -35,7 +35,7 @@ __FBSDID("$FreeBSD$");
#include <dev/hyperv/include/hyperv_busdma.h>
-#define HYPERV_DMA_WAITMASK (BUS_DMA_WAITOK | BUS_DMA_NOWAIT)
+#define HYPERV_DMA_MASK (BUS_DMA_WAITOK | BUS_DMA_NOWAIT | BUS_DMA_ZERO)
void
hyperv_dma_map_paddr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
@@ -73,7 +73,7 @@ hyperv_dmamem_alloc(bus_dma_tag_t parent
return NULL;
error = bus_dmamem_alloc(dma->hv_dtag, &ret,
- (flags & HYPERV_DMA_WAITMASK) | BUS_DMA_COHERENT, &dma->hv_dmap);
+ (flags & HYPERV_DMA_MASK) | BUS_DMA_COHERENT, &dma->hv_dmap);
if (error) {
bus_dma_tag_destroy(dma->hv_dtag);
return NULL;
Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Thu Jun 23 05:08:17 2016 (r302115)
+++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Thu Jun 23 05:35:08 2016 (r302116)
@@ -33,6 +33,7 @@
struct vmbus_pcpu_data {
int event_flag_cnt; /* # of event flags */
+ u_long *intr_cnt;
} __aligned(CACHE_LINE_SIZE);
struct vmbus_softc {
More information about the svn-src-all
mailing list