Module Name: src Committed By: yamaguchi Date: Thu Dec 23 04:06:51 UTC 2021
Modified Files: src/sys/arch/x86/x86: hyperv.c src/sys/dev/hyperv: hypervvar.h vmbus.c Log Message: hyper-v: move idt vector allocating to vmbus_init_interrupts_md() for refactoring And, the deallocating is also moved to vmbus_deinit_interrupts_md(). reviewed by nonaka@n.o. To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/sys/arch/x86/x86/hyperv.c cvs rdiff -u -r1.4 -r1.5 src/sys/dev/hyperv/hypervvar.h cvs rdiff -u -r1.14 -r1.15 src/sys/dev/hyperv/vmbus.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/x86/hyperv.c diff -u src/sys/arch/x86/x86/hyperv.c:1.13 src/sys/arch/x86/x86/hyperv.c:1.14 --- src/sys/arch/x86/x86/hyperv.c:1.13 Thu Jan 28 01:57:31 2021 +++ src/sys/arch/x86/x86/hyperv.c Thu Dec 23 04:06:51 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: hyperv.c,v 1.13 2021/01/28 01:57:31 jmcneill Exp $ */ +/* $NetBSD: hyperv.c,v 1.14 2021/12/23 04:06:51 yamaguchi Exp $ */ /*- * Copyright (c) 2009-2012,2016-2017 Microsoft Corp. @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> #ifdef __KERNEL_RCSID -__KERNEL_RCSID(0, "$NetBSD: hyperv.c,v 1.13 2021/01/28 01:57:31 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hyperv.c,v 1.14 2021/12/23 04:06:51 yamaguchi Exp $"); #endif #ifdef __FBSDID __FBSDID("$FreeBSD: head/sys/dev/hyperv/vmbus/hyperv.c 331757 2018-03-30 02:25:12Z emaste $"); @@ -755,52 +755,65 @@ hyperv_send_eom(void) } void -vmbus_init_interrupts_md(struct vmbus_softc *sc) +vmbus_init_interrupts_md(struct vmbus_softc *sc, cpuid_t cpu) { extern void Xintr_hyperv_hypercall(void); struct vmbus_percpu_data *pd; struct hyperv_percpu_data *hv_pd; - struct idt_vec *iv = &(cpu_info_primary.ci_idtvec); - cpuid_t cid; + struct cpu_info *ci; + struct idt_vec *iv; + int hyperv_idtvec; + cpuid_t cpu0; - if (idt_vec_is_pcpu()) - return; - /* - * All Hyper-V ISR required resources are setup, now let's find a - * free IDT vector for Hyper-V ISR and set it up. - */ - iv = &(cpu_info_primary.ci_idtvec); - cid = cpu_index(&cpu_info_primary); - pd = &sc->sc_percpu[cid]; + cpu0 = cpu_index(&cpu_info_primary); + + if (cpu == cpu0 || idt_vec_is_pcpu()) { + /* + * All Hyper-V ISR required resources are setup, now let's find a + * free IDT vector for Hyper-V ISR and set it up. + */ + ci = cpu_lookup(cpu); + iv = &ci->ci_idtvec; + mutex_enter(&cpu_lock); + hyperv_idtvec = idt_vec_alloc(iv, + APIC_LEVEL(NIPL), IDT_INTR_HIGH); + mutex_exit(&cpu_lock); + KASSERT(hyperv_idtvec > 0); + idt_vec_set(iv, hyperv_idtvec, Xintr_hyperv_hypercall); + } else { + pd = &sc->sc_percpu[cpu0]; + hv_pd = pd->md_cookie; + KASSERT(hv_pd != NULL && hv_pd->pd_idtvec > 0); + hyperv_idtvec = hv_pd->pd_idtvec; + } hv_pd = kmem_zalloc(sizeof(*hv_pd), KM_SLEEP); - mutex_enter(&cpu_lock); - hv_pd->pd_idtvec = idt_vec_alloc(iv, - APIC_LEVEL(NIPL), IDT_INTR_HIGH); - mutex_exit(&cpu_lock); - KASSERT(hv_pd->pd_idtvec > 0); - idt_vec_set(iv, hv_pd->pd_idtvec, Xintr_hyperv_hypercall); + hv_pd->pd_idtvec = hyperv_idtvec; + pd = &sc->sc_percpu[cpu]; pd->md_cookie = (void *)hv_pd; } void -vmbus_deinit_interrupts_md(struct vmbus_softc *sc) +vmbus_deinit_interrupts_md(struct vmbus_softc *sc, cpuid_t cpu) { struct vmbus_percpu_data *pd; struct hyperv_percpu_data *hv_pd; + struct cpu_info *ci; struct idt_vec *iv; - cpuid_t cid; - - if (idt_vec_is_pcpu()) - return; - iv = &(cpu_info_primary.ci_idtvec); - cid = cpu_index(&cpu_info_primary); - pd = &sc->sc_percpu[cid]; + pd = &sc->sc_percpu[cpu]; hv_pd = pd->md_cookie; + KASSERT(hv_pd != NULL); - if (hv_pd->pd_idtvec > 0) - idt_vec_free(iv, hv_pd->pd_idtvec); + if (cpu == cpu_index(&cpu_info_primary) || + idt_vec_is_pcpu()) { + ci = cpu_lookup(cpu); + iv = &ci->ci_idtvec; + + if (hv_pd->pd_idtvec > 0) { + idt_vec_free(iv, hv_pd->pd_idtvec); + } + } pd->md_cookie = NULL; kmem_free(hv_pd, sizeof(*hv_pd)); @@ -810,38 +823,15 @@ void vmbus_init_synic_md(struct vmbus_softc *sc, cpuid_t cpu) { extern void Xintr_hyperv_hypercall(void); - struct vmbus_percpu_data *pd, *pd0; + struct vmbus_percpu_data *pd; struct hyperv_percpu_data *hv_pd; - struct cpu_info *ci; - struct idt_vec *iv; uint64_t val, orig; uint32_t sint; int hyperv_idtvec; pd = &sc->sc_percpu[cpu]; - - hv_pd = kmem_alloc(sizeof(*hv_pd), KM_SLEEP); - pd->md_cookie = (void *)hv_pd; - - /* Allocate IDT vector for ISR and set it up. */ - if (idt_vec_is_pcpu()) { - ci = curcpu(); - iv = &ci->ci_idtvec; - - mutex_enter(&cpu_lock); - hyperv_idtvec = idt_vec_alloc(iv, APIC_LEVEL(NIPL), IDT_INTR_HIGH); - mutex_exit(&cpu_lock); - KASSERT(hyperv_idtvec > 0); - idt_vec_set(iv, hyperv_idtvec, Xintr_hyperv_hypercall); - - hv_pd = kmem_alloc(sizeof(*hv_pd), KM_SLEEP); - hv_pd->pd_idtvec = hyperv_idtvec; - pd->md_cookie = hv_pd; - } else { - pd0 = &sc->sc_percpu[cpu_index(&cpu_info_primary)]; - hv_pd = pd0->md_cookie; - hyperv_idtvec = hv_pd->pd_idtvec; - } + hv_pd = pd->md_cookie; + hyperv_idtvec = hv_pd->pd_idtvec; /* * Setup the SynIC message. @@ -888,10 +878,6 @@ vmbus_init_synic_md(struct vmbus_softc * void vmbus_deinit_synic_md(struct vmbus_softc *sc, cpuid_t cpu) { - struct vmbus_percpu_data *pd; - struct hyperv_percpu_data *hv_pd; - struct cpu_info *ci; - struct idt_vec *iv; uint64_t orig; uint32_t sint; @@ -926,22 +912,6 @@ vmbus_deinit_synic_md(struct vmbus_softc */ orig = rdmsr(MSR_HV_SIEFP); wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK)); - - /* - * Free IDT vector - */ - if (idt_vec_is_pcpu()) { - ci = curcpu(); - iv = &ci->ci_idtvec; - pd = &sc->sc_percpu[cpu_index(ci)]; - hv_pd = pd->md_cookie; - - if (hv_pd->pd_idtvec > 0) - idt_vec_free(iv, hv_pd->pd_idtvec); - - pd->md_cookie = NULL; - kmem_free(hv_pd, sizeof(*hv_pd)); - } } static int Index: src/sys/dev/hyperv/hypervvar.h diff -u src/sys/dev/hyperv/hypervvar.h:1.4 src/sys/dev/hyperv/hypervvar.h:1.5 --- src/sys/dev/hyperv/hypervvar.h:1.4 Tue Dec 10 12:20:20 2019 +++ src/sys/dev/hyperv/hypervvar.h Thu Dec 23 04:06:51 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: hypervvar.h,v 1.4 2019/12/10 12:20:20 nonaka Exp $ */ +/* $NetBSD: hypervvar.h,v 1.5 2021/12/23 04:06:51 yamaguchi Exp $ */ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD @@ -68,8 +68,8 @@ void hyperv_intr(void); uint32_t hyperv_get_vcpuid(cpuid_t); struct vmbus_softc; -void vmbus_init_interrupts_md(struct vmbus_softc *); -void vmbus_deinit_interrupts_md(struct vmbus_softc *); +void vmbus_init_interrupts_md(struct vmbus_softc *, cpuid_t); +void vmbus_deinit_interrupts_md(struct vmbus_softc *, cpuid_t); void vmbus_init_synic_md(struct vmbus_softc *, cpuid_t); void vmbus_deinit_synic_md(struct vmbus_softc *, cpuid_t); Index: src/sys/dev/hyperv/vmbus.c diff -u src/sys/dev/hyperv/vmbus.c:1.14 src/sys/dev/hyperv/vmbus.c:1.15 --- src/sys/dev/hyperv/vmbus.c:1.14 Sat Aug 7 16:19:11 2021 +++ src/sys/dev/hyperv/vmbus.c Thu Dec 23 04:06:51 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: vmbus.c,v 1.14 2021/08/07 16:19:11 thorpej Exp $ */ +/* $NetBSD: vmbus.c,v 1.15 2021/12/23 04:06:51 yamaguchi Exp $ */ /* $OpenBSD: hyperv.c,v 1.43 2017/06/27 13:56:15 mikeb Exp $ */ /*- @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vmbus.c,v 1.14 2021/08/07 16:19:11 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vmbus.c,v 1.15 2021/12/23 04:06:51 yamaguchi Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -68,8 +68,8 @@ static int vmbus_alloc_dma(struct vmbus_ static void vmbus_free_dma(struct vmbus_softc *); static int vmbus_init_interrupts(struct vmbus_softc *); static void vmbus_deinit_interrupts(struct vmbus_softc *); -static void vmbus_init_synic(void *, void *); -static void vmbus_deinit_synic(void *, void *); +static void vmbus_init_interrupts_pcpu(void *, void *); +static void vmbus_deinit_interrupts_pcpu(void *, void *); static int vmbus_connect(struct vmbus_softc *); static int vmbus_cmd(struct vmbus_softc *, void *, size_t, void *, size_t, @@ -313,8 +313,11 @@ static void vmbus_attach_deferred(device_t self) { struct vmbus_softc *sc = device_private(self); + uint64_t xc; - xc_wait(xc_broadcast(0, vmbus_init_synic, sc, NULL)); + xc = xc_broadcast(0, vmbus_init_interrupts_pcpu, + sc, NULL); + xc_wait(xc); } int @@ -404,6 +407,7 @@ vmbus_free_dma(struct vmbus_softc *sc) static int vmbus_init_interrupts(struct vmbus_softc *sc) { + uint64_t xc; TAILQ_INIT(&sc->sc_reqs); mutex_init(&sc->sc_req_lock, MUTEX_DEFAULT, IPL_NET); @@ -420,14 +424,15 @@ vmbus_init_interrupts(struct vmbus_softc if (sc->sc_msg_sih == NULL) return -1; - vmbus_init_interrupts_md(sc); - kcpuset_create(&sc->sc_intr_cpuset, true); if (cold) { /* Initialize other CPUs later. */ - vmbus_init_synic(sc, NULL); - } else - xc_wait(xc_broadcast(0, vmbus_init_synic, sc, NULL)); + vmbus_init_interrupts_pcpu(sc, NULL); + } else { + xc = xc_broadcast(0, vmbus_init_interrupts_pcpu, + sc, NULL); + xc_wait(xc); + } atomic_or_32(&sc->sc_flags, VMBUS_SCFLAG_SYNIC); return 0; @@ -436,14 +441,16 @@ vmbus_init_interrupts(struct vmbus_softc static void vmbus_deinit_interrupts(struct vmbus_softc *sc) { + uint64_t xc; - if (ISSET(sc->sc_flags, VMBUS_SCFLAG_SYNIC)) { - if (cold) - vmbus_deinit_synic(sc, NULL); - else - xc_wait(xc_broadcast(0, vmbus_deinit_synic, sc, NULL)); - atomic_and_32(&sc->sc_flags, (uint32_t)~VMBUS_SCFLAG_SYNIC); + if (cold) { + vmbus_deinit_interrupts_pcpu(sc, NULL); + } else { + xc = xc_broadcast(0, vmbus_deinit_interrupts_pcpu, + sc, NULL); + xc_wait(xc); } + atomic_and_32(&sc->sc_flags, (uint32_t)~VMBUS_SCFLAG_SYNIC); /* XXX event_tq */ @@ -451,12 +458,10 @@ vmbus_deinit_interrupts(struct vmbus_sof softint_disestablish(sc->sc_msg_sih); sc->sc_msg_sih = NULL; } - - vmbus_deinit_interrupts_md(sc); } static void -vmbus_init_synic(void *arg1, void *arg2) +vmbus_init_interrupts_pcpu(void *arg1, void *arg2 __unused) { struct vmbus_softc *sc = arg1; cpuid_t cpu; @@ -467,6 +472,7 @@ vmbus_init_synic(void *arg1, void *arg2) cpu = cpu_index(curcpu()); if (!kcpuset_isset(sc->sc_intr_cpuset, cpu)) { kcpuset_atomic_set(sc->sc_intr_cpuset, cpu); + vmbus_init_interrupts_md(sc, cpu); vmbus_init_synic_md(sc, cpu); } @@ -474,7 +480,7 @@ vmbus_init_synic(void *arg1, void *arg2) } static void -vmbus_deinit_synic(void *arg1, void *arg2) +vmbus_deinit_interrupts_pcpu(void *arg1, void *arg2 __unused) { struct vmbus_softc *sc = arg1; cpuid_t cpu; @@ -484,7 +490,9 @@ vmbus_deinit_synic(void *arg1, void *arg cpu = cpu_index(curcpu()); if (kcpuset_isset(sc->sc_intr_cpuset, cpu)) { - vmbus_deinit_synic_md(sc, cpu); + if (ISSET(sc->sc_flags, VMBUS_SCFLAG_SYNIC)) + vmbus_deinit_synic_md(sc, cpu); + vmbus_deinit_interrupts_md(sc, cpu); kcpuset_atomic_clear(sc->sc_intr_cpuset, cpu); }