Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/hyperv/vmbus/vmbus.c
Show All 38 Lines | |||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/sbuf.h> | #include <sys/sbuf.h> | ||||
#include <sys/smp.h> | #include <sys/smp.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/taskqueue.h> | #include <sys/taskqueue.h> | ||||
#include <vm/vm.h> | |||||
#include <vm/vm_extern.h> | |||||
#include <vm/vm_param.h> | |||||
#include <vm/pmap.h> | |||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#if defined(__aarch64__) | #if defined(__aarch64__) | ||||
#include <dev/psci/smccc.h> | #include <dev/psci/smccc.h> | ||||
#include <dev/hyperv/vmbus/aarch64/hyperv_machdep.h> | #include <dev/hyperv/vmbus/aarch64/hyperv_machdep.h> | ||||
#include <dev/hyperv/vmbus/aarch64/hyperv_reg.h> | #include <dev/hyperv/vmbus/aarch64/hyperv_reg.h> | ||||
#else | #else | ||||
#include <dev/hyperv/vmbus/x86/hyperv_machdep.h> | #include <dev/hyperv/vmbus/x86/hyperv_machdep.h> | ||||
▲ Show 20 Lines • Show All 144 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
static driver_t vmbus_driver = { | static driver_t vmbus_driver = { | ||||
"vmbus", | "vmbus", | ||||
vmbus_methods, | vmbus_methods, | ||||
sizeof(struct vmbus_softc) | sizeof(struct vmbus_softc) | ||||
}; | }; | ||||
int hv_synic_done = 0; | |||||
uint32_t hv_max_vp_index; | |||||
DPCPU_DEFINE(void *, hv_pcpu_mem); | |||||
DRIVER_MODULE(vmbus, pcib, vmbus_driver, NULL, NULL); | DRIVER_MODULE(vmbus, pcib, vmbus_driver, NULL, NULL); | ||||
DRIVER_MODULE(vmbus, acpi_syscontainer, vmbus_driver, NULL, NULL); | DRIVER_MODULE(vmbus, acpi_syscontainer, vmbus_driver, NULL, NULL); | ||||
MODULE_DEPEND(vmbus, acpi, 1, 1, 1); | MODULE_DEPEND(vmbus, acpi, 1, 1, 1); | ||||
MODULE_DEPEND(vmbus, pci, 1, 1, 1); | MODULE_DEPEND(vmbus, pci, 1, 1, 1); | ||||
MODULE_VERSION(vmbus, 1); | MODULE_VERSION(vmbus, 1); | ||||
static __inline struct vmbus_softc * | static __inline struct vmbus_softc * | ||||
▲ Show 20 Lines • Show All 524 Lines • ▼ Show 20 Lines | vmbus_synic_setup(void *xsc) | ||||
if (hyperv_features & CPUID_HV_MSR_VP_INDEX) { | if (hyperv_features & CPUID_HV_MSR_VP_INDEX) { | ||||
/* Save virtual processor id. */ | /* Save virtual processor id. */ | ||||
VMBUS_PCPU_GET(sc, vcpuid, cpu) = RDMSR(MSR_HV_VP_INDEX); | VMBUS_PCPU_GET(sc, vcpuid, cpu) = RDMSR(MSR_HV_VP_INDEX); | ||||
} else { | } else { | ||||
/* Set virtual processor id to 0 for compatibility. */ | /* Set virtual processor id to 0 for compatibility. */ | ||||
VMBUS_PCPU_GET(sc, vcpuid, cpu) = 0; | VMBUS_PCPU_GET(sc, vcpuid, cpu) = 0; | ||||
} | } | ||||
if (VMBUS_PCPU_GET(sc, vcpuid, cpu) > hv_max_vp_index) | |||||
hv_max_vp_index = VMBUS_PCPU_GET(sc, vcpuid, cpu); | |||||
/* | /* | ||||
* Setup the SynIC message. | * Setup the SynIC message. | ||||
*/ | */ | ||||
orig = RDMSR(MSR_HV_SIMP); | orig = RDMSR(MSR_HV_SIMP); | ||||
val = pmap_kextract((vm_offset_t)VMBUS_PCPU_GET(sc, message, cpu)) & | val = pmap_kextract((vm_offset_t)VMBUS_PCPU_GET(sc, message, cpu)) & | ||||
MSR_HV_SIMP_PGMASK; | MSR_HV_SIMP_PGMASK; | ||||
val |= MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK); | val |= MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK); | ||||
WRMSR(MSR_HV_SIMP, val); | WRMSR(MSR_HV_SIMP, val); | ||||
Show All 20 Lines | vmbus_synic_setup(void *xsc) | ||||
*/ | */ | ||||
vmbus_synic_setup1(sc); | vmbus_synic_setup1(sc); | ||||
/* | /* | ||||
* All done; enable SynIC. | * All done; enable SynIC. | ||||
*/ | */ | ||||
orig = RDMSR(MSR_HV_SCONTROL); | orig = RDMSR(MSR_HV_SCONTROL); | ||||
val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK); | val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK); | ||||
WRMSR(MSR_HV_SCONTROL, val); | WRMSR(MSR_HV_SCONTROL, val); | ||||
hv_synic_done = 1; | |||||
} | } | ||||
#if defined(__x86_64__) | |||||
uint64_t | |||||
hv_vm_tlb_flush_dummy(pmap_t pmap, vm_offset_t addr1, vm_offset_t addr2, | |||||
cpuset_t mask, enum invl_op_codes op) | |||||
{ | |||||
struct vmbus_softc *sc = vmbus_get_softc(); | |||||
return(hv_vm_tlb_flush(pmap, addr1, addr2, mask, op, sc)); | |||||
} | |||||
#else | |||||
uint64_t | |||||
hv_vm_tlb_flush_dummy(pmap_t pmap, vm_offset_t addr1, vm_offset_t addr2, | |||||
cpuset_t mask, enum invl_op_codes op) | |||||
{ | |||||
return EINVAL; | |||||
} | |||||
#endif /*__x86_64__*/ | |||||
static void | static void | ||||
vmbus_synic_teardown(void *arg) | vmbus_synic_teardown(void *arg) | ||||
{ | { | ||||
uint64_t orig; | uint64_t orig; | ||||
uint32_t sint; | uint32_t sint; | ||||
/* | /* | ||||
* Disable SynIC. | * Disable SynIC. | ||||
▲ Show 20 Lines • Show All 571 Lines • ▼ Show 20 Lines | vmbus_probe(device_t dev) | ||||
if (device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV || | if (device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV || | ||||
(hyperv_features & CPUID_HV_MSR_SYNIC) == 0) | (hyperv_features & CPUID_HV_MSR_SYNIC) == 0) | ||||
return (ENXIO); | return (ENXIO); | ||||
device_set_desc(dev, "Hyper-V Vmbus"); | device_set_desc(dev, "Hyper-V Vmbus"); | ||||
return (BUS_PROBE_DEFAULT); | return (BUS_PROBE_DEFAULT); | ||||
} | } | ||||
static void alloc_pcpu_ptr(void) | |||||
{ | |||||
int cpu; | |||||
void **hv_cpu_mem; | |||||
CPU_FOREACH(cpu){ | |||||
hv_cpu_mem = DPCPU_ID_PTR(cpu, hv_pcpu_mem); | |||||
*hv_cpu_mem = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO); | |||||
} | |||||
} | |||||
static void free_pcpu_ptr(void) | |||||
{ | |||||
int cpu; | |||||
void **hv_cpu_mem; | |||||
CPU_FOREACH(cpu){ | |||||
hv_cpu_mem = DPCPU_ID_PTR(cpu, hv_pcpu_mem); | |||||
if(*hv_cpu_mem) | |||||
free(*hv_cpu_mem, M_DEVBUF); | |||||
} | |||||
} | |||||
/** | /** | ||||
* @brief Main vmbus driver initialization routine. | * @brief Main vmbus driver initialization routine. | ||||
* | * | ||||
* Here, we | * Here, we | ||||
* - initialize the vmbus driver context | * - initialize the vmbus driver context | ||||
* - setup various driver entry points | * - setup various driver entry points | ||||
* - invoke the vmbus hv main init routine | * - invoke the vmbus hv main init routine | ||||
* - get the irq resource | * - get the irq resource | ||||
* - invoke the vmbus to add the vmbus root device | * - invoke the vmbus to add the vmbus root device | ||||
* - setup the vmbus root device | * - setup the vmbus root device | ||||
* - retrieve the channel offers | * - retrieve the channel offers | ||||
*/ | */ | ||||
static int | static int | ||||
vmbus_doattach(struct vmbus_softc *sc) | vmbus_doattach(struct vmbus_softc *sc) | ||||
{ | { | ||||
struct sysctl_oid_list *child; | struct sysctl_oid_list *child; | ||||
struct sysctl_ctx_list *ctx; | struct sysctl_ctx_list *ctx; | ||||
int ret; | int ret; | ||||
device_t dev_res; | device_t dev_res; | ||||
ACPI_HANDLE handle; | ACPI_HANDLE handle; | ||||
unsigned int coherent = 0; | unsigned int coherent = 0; | ||||
alloc_pcpu_ptr(); | |||||
if (sc->vmbus_flags & VMBUS_FLAG_ATTACHED) | if (sc->vmbus_flags & VMBUS_FLAG_ATTACHED) | ||||
return (0); | return (0); | ||||
#ifdef NEW_PCIB | #ifdef NEW_PCIB | ||||
vmbus_get_mmio_res(sc->vmbus_dev); | vmbus_get_mmio_res(sc->vmbus_dev); | ||||
vmbus_fb_mmio_res(sc->vmbus_dev); | vmbus_fb_mmio_res(sc->vmbus_dev); | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | cleanup: | ||||
vmbus_scan_teardown(sc); | vmbus_scan_teardown(sc); | ||||
vmbus_intr_teardown(sc); | vmbus_intr_teardown(sc); | ||||
vmbus_dma_free(sc); | vmbus_dma_free(sc); | ||||
if (sc->vmbus_xc != NULL) { | if (sc->vmbus_xc != NULL) { | ||||
vmbus_xact_ctx_destroy(sc->vmbus_xc); | vmbus_xact_ctx_destroy(sc->vmbus_xc); | ||||
sc->vmbus_xc = NULL; | sc->vmbus_xc = NULL; | ||||
} | } | ||||
free(__DEVOLATILE(void *, sc->vmbus_chmap), M_DEVBUF); | free(__DEVOLATILE(void *, sc->vmbus_chmap), M_DEVBUF); | ||||
free_pcpu_ptr(); | |||||
mtx_destroy(&sc->vmbus_prichan_lock); | mtx_destroy(&sc->vmbus_prichan_lock); | ||||
mtx_destroy(&sc->vmbus_chan_lock); | mtx_destroy(&sc->vmbus_chan_lock); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
static void | static void | ||||
vmbus_event_proc_dummy(struct vmbus_softc *sc __unused, int cpu __unused) | vmbus_event_proc_dummy(struct vmbus_softc *sc __unused, int cpu __unused) | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | vmbus_detach(device_t dev) | ||||
vmbus_dma_free(sc); | vmbus_dma_free(sc); | ||||
if (sc->vmbus_xc != NULL) { | if (sc->vmbus_xc != NULL) { | ||||
vmbus_xact_ctx_destroy(sc->vmbus_xc); | vmbus_xact_ctx_destroy(sc->vmbus_xc); | ||||
sc->vmbus_xc = NULL; | sc->vmbus_xc = NULL; | ||||
} | } | ||||
free(__DEVOLATILE(void *, sc->vmbus_chmap), M_DEVBUF); | free(__DEVOLATILE(void *, sc->vmbus_chmap), M_DEVBUF); | ||||
free_pcpu_ptr(); | |||||
mtx_destroy(&sc->vmbus_prichan_lock); | mtx_destroy(&sc->vmbus_prichan_lock); | ||||
mtx_destroy(&sc->vmbus_chan_lock); | mtx_destroy(&sc->vmbus_chan_lock); | ||||
#ifdef NEW_PCIB | #ifdef NEW_PCIB | ||||
vmbus_free_mmio_res(dev); | vmbus_free_mmio_res(dev); | ||||
#endif | #endif | ||||
#if defined(__aarch64__) | #if defined(__aarch64__) | ||||
Show All 25 Lines |