From owner-svn-src-all@freebsd.org Thu Jun 23 05:35:10 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 39C54B729AD; Thu, 23 Jun 2016 05:35:10 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id F25642FF8; Thu, 23 Jun 2016 05:35:09 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u5N5Z9MT082715; Thu, 23 Jun 2016 05:35:09 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u5N5Z83I082710; Thu, 23 Jun 2016 05:35:08 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201606230535.u5N5Z83I082710@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 23 Jun 2016 05:35:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r302116 - stable/10/sys/dev/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Jun 2016 05:35:10 -0000 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 -#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 {