diff --git a/sys/dev/hyperv/vmbus/aarch64/hyperv_aarch64.c b/sys/dev/hyperv/vmbus/aarch64/hyperv_aarch64.c index ab2d9becc3c5..eb915131fb6f 100644 --- a/sys/dev/hyperv/vmbus/aarch64/hyperv_aarch64.c +++ b/sys/dev/hyperv/vmbus/aarch64/hyperv_aarch64.c @@ -1,95 +1,96 @@ /*- SPDX-License-Identifier: BSD-2-Clause-FreeBSD * Copyright (c) 2009-2012,2016-2017, 2022 Microsoft Corp. * Copyright (c) 2012 NetApp Inc. * Copyright (c) 2012 Citrix Inc. * 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 unmodified, 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 ``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 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. */ /** * Implements low-level interactions with Hyper-V/Azure */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include void hyperv_init_tc(void); int hypercall_page_setup(vm_paddr_t); void hypercall_disable(void); bool hyperv_identify_features(void); u_int hyperv_ver_major; u_int hyperv_features; u_int hyperv_recommends; hyperv_tc64_t hyperv_tc64; void hyperv_init_tc(void) { hyperv_tc64 = NULL; } int hypercall_page_setup(vm_paddr_t hc) { return (0); } void hypercall_disable(void) { return; } bool hyperv_identify_features(void) { struct hv_get_vp_registers_output result; vm_guest = VM_GUEST_HV; hv_get_vpreg_128(CPUID_LEAF_HV_FEATURES, &result); hyperv_features = result.as32.a; hv_get_vpreg_128(CPUID_LEAF_HV_IDENTITY, &result); hyperv_ver_major = result.as32.b >> 16; hv_get_vpreg_128(CPUID_LEAF_HV_RECOMMENDS, &result); hyperv_recommends = result.as32.a; return (true); } diff --git a/sys/dev/hyperv/vmbus/aarch64/hyperv_machdep.c b/sys/dev/hyperv/vmbus/aarch64/hyperv_machdep.c index 9bfe34044335..d3e0b0a32f1e 100644 --- a/sys/dev/hyperv/vmbus/aarch64/hyperv_machdep.c +++ b/sys/dev/hyperv/vmbus/aarch64/hyperv_machdep.c @@ -1,103 +1,104 @@ /*- SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2016-2017,2022 Microsoft Corp. * * 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 unmodified, 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 ``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 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include +#include #include #define HVCALL_SET_VP_REGISTERS 0x0051 #define HVCALL_GET_VP_REGISTERS 0x0050 #define BIT(A) (1 << (A)) #define HV_HYPERCALL_FAST_BIT BIT(16) #define BIT_ULL(a) (1ULL << (a)) #define HV_HYPERCALL_REP_COMP_1 BIT_ULL(32) #define HV_PARTITION_ID_SELF ((u64)-1) #define HV_VP_INDEX_SELF ((u32)-2) #define HV_SMCCC_FUNC_NUMBER 1 #define HV_FUNC_ID \ SMCCC_FUNC_ID(SMCCC_YIELDING_CALL, SMCCC_64BIT_CALL, \ SMCCC_VENDOR_HYP_SERVICE_CALLS, HV_SMCCC_FUNC_NUMBER) void arm_hv_set_vreg(u32 msr, u64 value) { arm_smccc_hvc(HV_FUNC_ID, HVCALL_SET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_REP_COMP_1, HV_PARTITION_ID_SELF, HV_VP_INDEX_SELF, msr, 0, value, 0, NULL); } void hv_get_vpreg_128(u32 msr, struct hv_get_vp_registers_output *result) { struct arm_smccc_1_2_regs args; struct arm_smccc_1_2_regs res; args.a0 = HV_FUNC_ID; args.a1 = HVCALL_GET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_REP_COMP_1; args.a2 = HV_PARTITION_ID_SELF; args.a3 = HV_VP_INDEX_SELF; args.a4 = msr; /* * Use the SMCCC 1.2 interface because the results are in registers * beyond X0-X3. */ arm_smccc_1_2_hvc(&args, &res); result->as64.low = res.a6; result->as64.high = res.a7; } u64 arm_hv_get_vreg(u32 msr) { struct hv_get_vp_registers_output output; hv_get_vpreg_128(msr, &output); return (output.as64.low); } uint64_t hypercall_md(volatile void *hc_addr, uint64_t in_val, uint64_t in_paddr, uint64_t out_paddr) { struct arm_smccc_res res; arm_smccc_hvc(HV_FUNC_ID, in_val, in_paddr, out_paddr, 0, 0, 0, 0, &res); return (res.a0); } diff --git a/sys/dev/hyperv/vmbus/aarch64/hyperv_reg.h b/sys/dev/hyperv/vmbus/aarch64/hyperv_reg.h index 85accc130b77..a0a6773dea67 100644 --- a/sys/dev/hyperv/vmbus/aarch64/hyperv_reg.h +++ b/sys/dev/hyperv/vmbus/aarch64/hyperv_reg.h @@ -1,193 +1,50 @@ /*- SPDX-License-Identifier: BSD-2-Clause-FreeBSD * Copyright (c) 2022 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 unmodified, 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 ``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 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. * * $FreeBSD$ */ #ifndef _HYPERV_REG_H_ #define _HYPERV_REG_H_ #include #include /* * Hyper-V Synthetic MSRs */ #define MSR_HV_GUEST_OS_ID 0x00090002 -#define MSR_HV_GUESTID_BUILD_MASK 0xffffULL -#define MSR_HV_GUESTID_VERSION_MASK 0x0000ffffffff0000ULL -#define MSR_HV_GUESTID_VERSION_SHIFT 16 -#define MSR_HV_GUESTID_OSID_MASK 0x00ff000000000000ULL -#define MSR_HV_GUESTID_OSID_SHIFT 48 -#define MSR_HV_GUESTID_OSTYPE_MASK 0x7f00000000000000ULL -#define MSR_HV_GUESTID_OSTYPE_SHIFT 56 -#define MSR_HV_GUESTID_OPENSRC 0x8000000000000000ULL -#define MSR_HV_GUESTID_OSTYPE_LINUX \ - ((0x01ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC) -#define MSR_HV_GUESTID_OSTYPE_FREEBSD \ - ((0x02ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC) - -#define MSR_HV_HYPERCALL 0x40000001 -#define MSR_HV_HYPERCALL_ENABLE 0x0001ULL -#define MSR_HV_HYPERCALL_RSVD_MASK 0x0ffeULL -#define MSR_HV_HYPERCALL_PGSHIFT 12 - #define MSR_HV_VP_INDEX 0x00090003 - -#define MSR_HV_REFERENCE_TSC 0x40000021 -#define MSR_HV_REFTSC_ENABLE 0x0001ULL -#define MSR_HV_REFTSC_RSVD_MASK 0x0ffeULL -#define MSR_HV_REFTSC_PGSHIFT 12 - #define MSR_HV_SCONTROL 0x000A0010 -#define MSR_HV_SCTRL_ENABLE 0x0001ULL -#define MSR_HV_SCTRL_RSVD_MASK 0xfffffffffffffffeULL - -#define MSR_HV_SIEFP 0x000A0012 -#define MSR_HV_SIEFP_ENABLE 0x0001ULL -#define MSR_HV_SIEFP_RSVD_MASK 0x0ffeULL -#define MSR_HV_SIEFP_PGSHIFT 12 - -#define MSR_HV_SIMP 0x000A0013 -#define MSR_HV_SIMP_ENABLE 0x0001ULL -#define MSR_HV_SIMP_RSVD_MASK 0x0ffeULL -#define MSR_HV_SIMP_PGSHIFT 12 - -#define MSR_HV_EOM 0x000A0014 - +#define MSR_HV_SIEFP 0x000A0012 +#define MSR_HV_SIMP 0x000A0013 #define MSR_HV_SINT0 0x000A0000 -#define MSR_HV_SINT_VECTOR_MASK 0x00ffULL -#define MSR_HV_SINT_RSVD1_MASK 0xff00ULL -#define MSR_HV_SINT_MASKED 0x00010000ULL #define MSR_HV_SINT_AUTOEOI 0x00000000ULL -#define MSR_HV_SINT_RSVD2_MASK 0xfffffffffffc0000ULL -#define MSR_HV_SINT_RSVD_MASK (MSR_HV_SINT_RSVD1_MASK | \ - MSR_HV_SINT_RSVD2_MASK) - -#define MSR_HV_STIMER0_CONFIG 0x400000b0 -#define MSR_HV_STIMER_CFG_ENABLE 0x0001ULL -#define MSR_HV_STIMER_CFG_PERIODIC 0x0002ULL -#define MSR_HV_STIMER_CFG_LAZY 0x0004ULL -#define MSR_HV_STIMER_CFG_AUTOEN 0x0008ULL -#define MSR_HV_STIMER_CFG_SINT_MASK 0x000f0000ULL -#define MSR_HV_STIMER_CFG_SINT_SHIFT 16 - -#define MSR_HV_STIMER0_COUNT 0x400000b1 - -/* - * CPUID leaves - */ - -#define CPUID_LEAF_HV_MAXLEAF 0x40000000 - -#define CPUID_LEAF_HV_INTERFACE 0x40000001 -#define CPUID_HV_IFACE_HYPERV 0x31237648 /* HV#1 */ - +#define MSR_HV_EOM 0x000A0014 #define CPUID_LEAF_HV_IDENTITY 0x00000100 - #define CPUID_LEAF_HV_FEATURES 0x00000200 -/* EAX: features include/hyperv.h CPUID_HV_MSR */ -/* ECX: power management features */ -#define CPUPM_HV_CSTATE_MASK 0x000f /* deepest C-state */ -#define CPUPM_HV_C3_HPET 0x0010 /* C3 requires HPET */ -#define CPUPM_HV_CSTATE(f) ((f) & CPUPM_HV_CSTATE_MASK) -/* EDX: features3 */ -#define CPUID3_HV_MWAIT 0x0001 /* MWAIT */ -#define CPUID3_HV_XMM_HYPERCALL 0x0010 /* Hypercall input through - * XMM regs */ -#define CPUID3_HV_GUEST_IDLE 0x0020 /* guest idle */ -#define CPUID3_HV_NUMA 0x0080 /* NUMA distance query */ -#define CPUID3_HV_TIME_FREQ 0x0100 /* timer frequency query - * (TSC, LAPIC) */ -#define CPUID3_HV_MSR_CRASH 0x0400 /* MSRs for guest crash */ - #define CPUID_LEAF_HV_RECOMMENDS 0x00000201 -#define CPUID_LEAF_HV_LIMITS 0x40000005 -#define CPUID_LEAF_HV_HWFEATURES 0x40000006 - -/* - * Hyper-V Monitor Notification Facility - */ -struct hyperv_mon_param { - uint32_t mp_connid; - uint16_t mp_evtflag_ofs; - uint16_t mp_rsvd; -} __packed; - -/* - * Hyper-V message types - */ -#define HYPERV_MSGTYPE_NONE 0 -#define HYPERV_MSGTYPE_CHANNEL 1 -#define HYPERV_MSGTYPE_TIMER_EXPIRED 0x80000010 - -/* - * Hypercall status codes - */ -#define HYPERCALL_STATUS_SUCCESS 0x0000 - -/* - * Hypercall input values - */ -#define HYPERCALL_POST_MESSAGE 0x005c -#define HYPERCALL_SIGNAL_EVENT 0x005d - -/* - * Hypercall input parameters - */ -#define HYPERCALL_PARAM_ALIGN 8 -#if 0 -/* - * XXX - * <> requires - * input parameters size to be multiple of 8, however, many post - * message input parameters do _not_ meet this requirement. - */ -#define HYPERCALL_PARAM_SIZE_ALIGN 8 -#endif - -/* - * HYPERCALL_POST_MESSAGE - */ -#define HYPERCALL_POSTMSGIN_DSIZE_MAX 240 -#define HYPERCALL_POSTMSGIN_SIZE 256 - -struct hypercall_postmsg_in { - uint32_t hc_connid; - uint32_t hc_rsvd; - uint32_t hc_msgtype; /* HYPERV_MSGTYPE_ */ - uint32_t hc_dsize; - uint8_t hc_data[HYPERCALL_POSTMSGIN_DSIZE_MAX]; -} __packed; -CTASSERT(sizeof(struct hypercall_postmsg_in) == HYPERCALL_POSTMSGIN_SIZE); - -/* - * HYPERCALL_SIGNAL_EVENT - * - * struct hyperv_mon_param. - */ - #endif /* !_HYPERV_REG_H_ */ diff --git a/sys/dev/hyperv/vmbus/aarch64/vmbus_aarch64.c b/sys/dev/hyperv/vmbus/aarch64/vmbus_aarch64.c index 861443c4a6ed..f899079d22bc 100644 --- a/sys/dev/hyperv/vmbus/aarch64/vmbus_aarch64.c +++ b/sys/dev/hyperv/vmbus/aarch64/vmbus_aarch64.c @@ -1,159 +1,160 @@ /*- SPDX-License-Identifier: BSD-2-Clause-FreeBSD * Copyright (c) 2009-2012,2016-2017, 2022 Microsoft Corp. * Copyright (c) 2012 NetApp Inc. * Copyright (c) 2012 Citrix Inc. * 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 unmodified, 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 ``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 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. */ /* * VM Bus Driver Implementation */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include "acpi_if.h" #include "pcib_if.h" #include "vmbus_if.h" static int vmbus_handle_intr_new(void *); void vmbus_handle_timer_intr1(struct vmbus_message *msg_base, struct trapframe *frame); void vmbus_synic_setup1(void *xsc); void vmbus_synic_teardown1(void); int vmbus_setup_intr1(struct vmbus_softc *sc); void vmbus_intr_teardown1(struct vmbus_softc *sc); void vmbus_handle_timer_intr1(struct vmbus_message *msg_base, struct trapframe *frame) { // do nothing for arm64, as we are using generic timer return; } static int vmbus_handle_intr_new(void *arg) { vmbus_handle_intr(NULL); return (FILTER_HANDLED); } void vmbus_synic_setup1(void *xsc) { return; } void vmbus_synic_teardown1(void) { return; } int vmbus_setup_intr1(struct vmbus_softc *sc) { int err; struct intr_map_data_acpi *irq_data; device_t dev; dev = devclass_get_device(devclass_find("vmbus_res"), 0); sc->ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->vector, RF_ACTIVE | RF_SHAREABLE); if (sc->ires == NULL) { device_printf(sc->vmbus_dev, "bus_alloc_resouce_any failed\n"); return (ENXIO); } else { device_printf(sc->vmbus_dev, "irq 0x%lx, vector %d end 0x%lx\n", (uint64_t)rman_get_start(sc->ires), sc->vector, (uint64_t)rman_get_end(sc->ires)); } err = bus_setup_intr(sc->vmbus_dev, sc->ires, INTR_TYPE_MISC, vmbus_handle_intr_new, NULL, sc, &sc->icookie); if (err) { device_printf(sc->vmbus_dev, "failed to setup IRQ %d\n", err); return (err); } irq_data = (struct intr_map_data_acpi *)rman_get_virtual(sc->ires); device_printf(sc->vmbus_dev, "the irq %u\n", irq_data->irq); sc->vmbus_idtvec = irq_data->irq; return 0; } void vmbus_intr_teardown1(struct vmbus_softc *sc) { int cpu; sc->vmbus_idtvec = -1; bus_teardown_intr(sc->vmbus_dev, sc->ires, sc->icookie); CPU_FOREACH(cpu) { if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) { taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu)); VMBUS_PCPU_GET(sc, event_tq, cpu) = NULL; } if (VMBUS_PCPU_GET(sc, message_tq, cpu) != NULL) { taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu), VMBUS_PCPU_PTR(sc, message_task, cpu)); taskqueue_free(VMBUS_PCPU_GET(sc, message_tq, cpu)); VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL; } } } diff --git a/sys/dev/hyperv/vmbus/x86/hyperv_reg.h b/sys/dev/hyperv/vmbus/hyperv_common_reg.h similarity index 91% copy from sys/dev/hyperv/vmbus/x86/hyperv_reg.h copy to sys/dev/hyperv/vmbus/hyperv_common_reg.h index f76d014b86f5..b151952158c7 100644 --- a/sys/dev/hyperv/vmbus/x86/hyperv_reg.h +++ b/sys/dev/hyperv/vmbus/hyperv_common_reg.h @@ -1,193 +1,175 @@ /*- SPDX-License-Identifier: BSD-2-Clause-FreeBSD * Copyright (c) 2022 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 unmodified, 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 ``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 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. * * $FreeBSD$ */ -#ifndef _HYPERV_REG_H_ -#define _HYPERV_REG_H_ +#ifndef _HYPERV_COMMON_REG_H_ +#define _HYPERV_COMMON_REG_H_ #include #include -/* - * Hyper-V Synthetic MSRs - */ - -#define MSR_HV_GUEST_OS_ID 0x40000000 #define MSR_HV_GUESTID_BUILD_MASK 0xffffULL #define MSR_HV_GUESTID_VERSION_MASK 0x0000ffffffff0000ULL #define MSR_HV_GUESTID_VERSION_SHIFT 16 #define MSR_HV_GUESTID_OSID_MASK 0x00ff000000000000ULL #define MSR_HV_GUESTID_OSID_SHIFT 48 #define MSR_HV_GUESTID_OSTYPE_MASK 0x7f00000000000000ULL #define MSR_HV_GUESTID_OSTYPE_SHIFT 56 #define MSR_HV_GUESTID_OPENSRC 0x8000000000000000ULL #define MSR_HV_GUESTID_OSTYPE_LINUX \ ((0x01ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC) #define MSR_HV_GUESTID_OSTYPE_FREEBSD \ ((0x02ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC) #define MSR_HV_HYPERCALL 0x40000001 #define MSR_HV_HYPERCALL_ENABLE 0x0001ULL #define MSR_HV_HYPERCALL_RSVD_MASK 0x0ffeULL #define MSR_HV_HYPERCALL_PGSHIFT 12 -#define MSR_HV_VP_INDEX 0x40000002 - #define MSR_HV_REFERENCE_TSC 0x40000021 #define MSR_HV_REFTSC_ENABLE 0x0001ULL #define MSR_HV_REFTSC_RSVD_MASK 0x0ffeULL #define MSR_HV_REFTSC_PGSHIFT 12 -#define MSR_HV_SCONTROL 0x40000080 #define MSR_HV_SCTRL_ENABLE 0x0001ULL #define MSR_HV_SCTRL_RSVD_MASK 0xfffffffffffffffeULL -#define MSR_HV_SIEFP 0x40000082 #define MSR_HV_SIEFP_ENABLE 0x0001ULL #define MSR_HV_SIEFP_RSVD_MASK 0x0ffeULL #define MSR_HV_SIEFP_PGSHIFT 12 -#define MSR_HV_SIMP 0x40000083 #define MSR_HV_SIMP_ENABLE 0x0001ULL #define MSR_HV_SIMP_RSVD_MASK 0x0ffeULL #define MSR_HV_SIMP_PGSHIFT 12 -#define MSR_HV_EOM 0x40000084 - -#define MSR_HV_SINT0 0x40000090 #define MSR_HV_SINT_VECTOR_MASK 0x00ffULL #define MSR_HV_SINT_RSVD1_MASK 0xff00ULL #define MSR_HV_SINT_MASKED 0x00010000ULL -#define MSR_HV_SINT_AUTOEOI 0x00020000ULL + #define MSR_HV_SINT_RSVD2_MASK 0xfffffffffffc0000ULL #define MSR_HV_SINT_RSVD_MASK (MSR_HV_SINT_RSVD1_MASK | \ MSR_HV_SINT_RSVD2_MASK) #define MSR_HV_STIMER0_CONFIG 0x400000b0 #define MSR_HV_STIMER_CFG_ENABLE 0x0001ULL #define MSR_HV_STIMER_CFG_PERIODIC 0x0002ULL #define MSR_HV_STIMER_CFG_LAZY 0x0004ULL #define MSR_HV_STIMER_CFG_AUTOEN 0x0008ULL #define MSR_HV_STIMER_CFG_SINT_MASK 0x000f0000ULL #define MSR_HV_STIMER_CFG_SINT_SHIFT 16 #define MSR_HV_STIMER0_COUNT 0x400000b1 /* * CPUID leaves */ #define CPUID_LEAF_HV_MAXLEAF 0x40000000 #define CPUID_LEAF_HV_INTERFACE 0x40000001 #define CPUID_HV_IFACE_HYPERV 0x31237648 /* HV#1 */ -#define CPUID_LEAF_HV_IDENTITY 0x40000002 - -#define CPUID_LEAF_HV_FEATURES 0x40000003 /* EAX: features include/hyperv.h CPUID_HV_MSR */ /* ECX: power management features */ #define CPUPM_HV_CSTATE_MASK 0x000f /* deepest C-state */ #define CPUPM_HV_C3_HPET 0x0010 /* C3 requires HPET */ #define CPUPM_HV_CSTATE(f) ((f) & CPUPM_HV_CSTATE_MASK) /* EDX: features3 */ #define CPUID3_HV_MWAIT 0x0001 /* MWAIT */ #define CPUID3_HV_XMM_HYPERCALL 0x0010 /* Hypercall input through * XMM regs */ #define CPUID3_HV_GUEST_IDLE 0x0020 /* guest idle */ #define CPUID3_HV_NUMA 0x0080 /* NUMA distance query */ #define CPUID3_HV_TIME_FREQ 0x0100 /* timer frequency query * (TSC, LAPIC) */ #define CPUID3_HV_MSR_CRASH 0x0400 /* MSRs for guest crash */ - -#define CPUID_LEAF_HV_RECOMMENDS 0x40000004 #define CPUID_LEAF_HV_LIMITS 0x40000005 #define CPUID_LEAF_HV_HWFEATURES 0x40000006 /* * Hyper-V Monitor Notification Facility */ struct hyperv_mon_param { uint32_t mp_connid; uint16_t mp_evtflag_ofs; uint16_t mp_rsvd; } __packed; /* * Hyper-V message types */ #define HYPERV_MSGTYPE_NONE 0 #define HYPERV_MSGTYPE_CHANNEL 1 #define HYPERV_MSGTYPE_TIMER_EXPIRED 0x80000010 /* * Hypercall status codes */ #define HYPERCALL_STATUS_SUCCESS 0x0000 /* * Hypercall input values */ #define HYPERCALL_POST_MESSAGE 0x005c #define HYPERCALL_SIGNAL_EVENT 0x005d /* * Hypercall input parameters */ #define HYPERCALL_PARAM_ALIGN 8 #if 0 /* * XXX * <> requires * input parameters size to be multiple of 8, however, many post * message input parameters do _not_ meet this requirement. */ #define HYPERCALL_PARAM_SIZE_ALIGN 8 #endif /* * HYPERCALL_POST_MESSAGE */ #define HYPERCALL_POSTMSGIN_DSIZE_MAX 240 #define HYPERCALL_POSTMSGIN_SIZE 256 struct hypercall_postmsg_in { uint32_t hc_connid; uint32_t hc_rsvd; uint32_t hc_msgtype; /* HYPERV_MSGTYPE_ */ uint32_t hc_dsize; uint8_t hc_data[HYPERCALL_POSTMSGIN_DSIZE_MAX]; } __packed; CTASSERT(sizeof(struct hypercall_postmsg_in) == HYPERCALL_POSTMSGIN_SIZE); /* * HYPERCALL_SIGNAL_EVENT * * struct hyperv_mon_param. */ -#endif /* !_HYPERV_REG_H_ */ +#endif /* i!__HYPERV_COMMON_REG_H__ */ diff --git a/sys/dev/hyperv/vmbus/x86/hyperv_reg.h b/sys/dev/hyperv/vmbus/x86/hyperv_reg.h index f76d014b86f5..fec2eda2d673 100644 --- a/sys/dev/hyperv/vmbus/x86/hyperv_reg.h +++ b/sys/dev/hyperv/vmbus/x86/hyperv_reg.h @@ -1,193 +1,50 @@ /*- SPDX-License-Identifier: BSD-2-Clause-FreeBSD * Copyright (c) 2022 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 unmodified, 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 ``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 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. * * $FreeBSD$ */ #ifndef _HYPERV_REG_H_ #define _HYPERV_REG_H_ #include #include /* * Hyper-V Synthetic MSRs */ #define MSR_HV_GUEST_OS_ID 0x40000000 -#define MSR_HV_GUESTID_BUILD_MASK 0xffffULL -#define MSR_HV_GUESTID_VERSION_MASK 0x0000ffffffff0000ULL -#define MSR_HV_GUESTID_VERSION_SHIFT 16 -#define MSR_HV_GUESTID_OSID_MASK 0x00ff000000000000ULL -#define MSR_HV_GUESTID_OSID_SHIFT 48 -#define MSR_HV_GUESTID_OSTYPE_MASK 0x7f00000000000000ULL -#define MSR_HV_GUESTID_OSTYPE_SHIFT 56 -#define MSR_HV_GUESTID_OPENSRC 0x8000000000000000ULL -#define MSR_HV_GUESTID_OSTYPE_LINUX \ - ((0x01ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC) -#define MSR_HV_GUESTID_OSTYPE_FREEBSD \ - ((0x02ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC) - -#define MSR_HV_HYPERCALL 0x40000001 -#define MSR_HV_HYPERCALL_ENABLE 0x0001ULL -#define MSR_HV_HYPERCALL_RSVD_MASK 0x0ffeULL -#define MSR_HV_HYPERCALL_PGSHIFT 12 - #define MSR_HV_VP_INDEX 0x40000002 - -#define MSR_HV_REFERENCE_TSC 0x40000021 -#define MSR_HV_REFTSC_ENABLE 0x0001ULL -#define MSR_HV_REFTSC_RSVD_MASK 0x0ffeULL -#define MSR_HV_REFTSC_PGSHIFT 12 - #define MSR_HV_SCONTROL 0x40000080 -#define MSR_HV_SCTRL_ENABLE 0x0001ULL -#define MSR_HV_SCTRL_RSVD_MASK 0xfffffffffffffffeULL - -#define MSR_HV_SIEFP 0x40000082 -#define MSR_HV_SIEFP_ENABLE 0x0001ULL -#define MSR_HV_SIEFP_RSVD_MASK 0x0ffeULL -#define MSR_HV_SIEFP_PGSHIFT 12 - -#define MSR_HV_SIMP 0x40000083 -#define MSR_HV_SIMP_ENABLE 0x0001ULL -#define MSR_HV_SIMP_RSVD_MASK 0x0ffeULL -#define MSR_HV_SIMP_PGSHIFT 12 - +#define MSR_HV_SIEFP 0x40000082 +#define MSR_HV_SIMP 0x40000083 #define MSR_HV_EOM 0x40000084 - #define MSR_HV_SINT0 0x40000090 -#define MSR_HV_SINT_VECTOR_MASK 0x00ffULL -#define MSR_HV_SINT_RSVD1_MASK 0xff00ULL -#define MSR_HV_SINT_MASKED 0x00010000ULL #define MSR_HV_SINT_AUTOEOI 0x00020000ULL -#define MSR_HV_SINT_RSVD2_MASK 0xfffffffffffc0000ULL -#define MSR_HV_SINT_RSVD_MASK (MSR_HV_SINT_RSVD1_MASK | \ - MSR_HV_SINT_RSVD2_MASK) - -#define MSR_HV_STIMER0_CONFIG 0x400000b0 -#define MSR_HV_STIMER_CFG_ENABLE 0x0001ULL -#define MSR_HV_STIMER_CFG_PERIODIC 0x0002ULL -#define MSR_HV_STIMER_CFG_LAZY 0x0004ULL -#define MSR_HV_STIMER_CFG_AUTOEN 0x0008ULL -#define MSR_HV_STIMER_CFG_SINT_MASK 0x000f0000ULL -#define MSR_HV_STIMER_CFG_SINT_SHIFT 16 - -#define MSR_HV_STIMER0_COUNT 0x400000b1 - -/* - * CPUID leaves - */ - -#define CPUID_LEAF_HV_MAXLEAF 0x40000000 - -#define CPUID_LEAF_HV_INTERFACE 0x40000001 -#define CPUID_HV_IFACE_HYPERV 0x31237648 /* HV#1 */ - #define CPUID_LEAF_HV_IDENTITY 0x40000002 - #define CPUID_LEAF_HV_FEATURES 0x40000003 -/* EAX: features include/hyperv.h CPUID_HV_MSR */ -/* ECX: power management features */ -#define CPUPM_HV_CSTATE_MASK 0x000f /* deepest C-state */ -#define CPUPM_HV_C3_HPET 0x0010 /* C3 requires HPET */ -#define CPUPM_HV_CSTATE(f) ((f) & CPUPM_HV_CSTATE_MASK) -/* EDX: features3 */ -#define CPUID3_HV_MWAIT 0x0001 /* MWAIT */ -#define CPUID3_HV_XMM_HYPERCALL 0x0010 /* Hypercall input through - * XMM regs */ -#define CPUID3_HV_GUEST_IDLE 0x0020 /* guest idle */ -#define CPUID3_HV_NUMA 0x0080 /* NUMA distance query */ -#define CPUID3_HV_TIME_FREQ 0x0100 /* timer frequency query - * (TSC, LAPIC) */ -#define CPUID3_HV_MSR_CRASH 0x0400 /* MSRs for guest crash */ - #define CPUID_LEAF_HV_RECOMMENDS 0x40000004 -#define CPUID_LEAF_HV_LIMITS 0x40000005 -#define CPUID_LEAF_HV_HWFEATURES 0x40000006 - -/* - * Hyper-V Monitor Notification Facility - */ -struct hyperv_mon_param { - uint32_t mp_connid; - uint16_t mp_evtflag_ofs; - uint16_t mp_rsvd; -} __packed; - -/* - * Hyper-V message types - */ -#define HYPERV_MSGTYPE_NONE 0 -#define HYPERV_MSGTYPE_CHANNEL 1 -#define HYPERV_MSGTYPE_TIMER_EXPIRED 0x80000010 - -/* - * Hypercall status codes - */ -#define HYPERCALL_STATUS_SUCCESS 0x0000 - -/* - * Hypercall input values - */ -#define HYPERCALL_POST_MESSAGE 0x005c -#define HYPERCALL_SIGNAL_EVENT 0x005d - -/* - * Hypercall input parameters - */ -#define HYPERCALL_PARAM_ALIGN 8 -#if 0 -/* - * XXX - * <> requires - * input parameters size to be multiple of 8, however, many post - * message input parameters do _not_ meet this requirement. - */ -#define HYPERCALL_PARAM_SIZE_ALIGN 8 -#endif - -/* - * HYPERCALL_POST_MESSAGE - */ -#define HYPERCALL_POSTMSGIN_DSIZE_MAX 240 -#define HYPERCALL_POSTMSGIN_SIZE 256 - -struct hypercall_postmsg_in { - uint32_t hc_connid; - uint32_t hc_rsvd; - uint32_t hc_msgtype; /* HYPERV_MSGTYPE_ */ - uint32_t hc_dsize; - uint8_t hc_data[HYPERCALL_POSTMSGIN_DSIZE_MAX]; -} __packed; -CTASSERT(sizeof(struct hypercall_postmsg_in) == HYPERCALL_POSTMSGIN_SIZE); - -/* - * HYPERCALL_SIGNAL_EVENT - * - * struct hyperv_mon_param. - */ - #endif /* !_HYPERV_REG_H_ */ diff --git a/sys/dev/hyperv/vmbus/x86/hyperv_x86.c b/sys/dev/hyperv/vmbus/x86/hyperv_x86.c index 17cb45d81f41..bb7f14e29ef0 100644 --- a/sys/dev/hyperv/vmbus/x86/hyperv_x86.c +++ b/sys/dev/hyperv/vmbus/x86/hyperv_x86.c @@ -1,241 +1,242 @@ /*- SPDX-License-Identifier: BSD-2-Clause-FreeBSD * Copyright (c) 2009-2012,2016-2017, 2022 Microsoft Corp. * Copyright (c) 2012 NetApp Inc. * Copyright (c) 2012 Citrix Inc. * 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 unmodified, 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 ``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 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. */ /** * Implements low-level interactions with Hyper-V/Azure */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #define HYPERV_FREEBSD_BUILD 0ULL #define HYPERV_FREEBSD_VERSION ((uint64_t)__FreeBSD_version) #define HYPERV_FREEBSD_OSID 0ULL void hyperv_init_tc(void); int hypercall_page_setup(vm_paddr_t); void hypercall_disable(void); bool hyperv_identify_features(void); u_int hyperv_ver_major; u_int hyperv_features; u_int hyperv_recommends; hyperv_tc64_t hyperv_tc64; static u_int hyperv_pm_features; static u_int hyperv_features3; static u_int hyperv_get_timecount(struct timecounter *); static struct timecounter hyperv_timecounter = { .tc_get_timecount = hyperv_get_timecount, .tc_poll_pps = NULL, .tc_counter_mask = 0xffffffff, .tc_frequency = HYPERV_TIMER_FREQ, .tc_name = "Hyper-V", .tc_quality = 2000, .tc_flags = 0, .tc_priv = NULL }; static u_int hyperv_get_timecount(struct timecounter *tc __unused) { return rdmsr(MSR_HV_TIME_REF_COUNT); } static uint64_t hyperv_tc64_rdmsr(void) { return (rdmsr(MSR_HV_TIME_REF_COUNT)); } void hyperv_init_tc(void) { if (hyperv_features & CPUID_HV_MSR_TIME_REFCNT) { /* * Register Hyper-V timecounter. This should be done as early * as possible to let DELAY() work, since the 8254 PIT is not * reliably emulated or even available. */ tc_init(&hyperv_timecounter); /* * Install 64 bits timecounter method for other modules * to use. */ hyperv_tc64 = hyperv_tc64_rdmsr; } } int hypercall_page_setup(vm_paddr_t paddr) { uint64_t hc, hc_orig; hc_orig = rdmsr(MSR_HV_HYPERCALL); /* * Setup the Hypercall page. * * NOTE: 'reserved' bits MUST be preserved. */ hc = ((paddr >> PAGE_SHIFT) << MSR_HV_HYPERCALL_PGSHIFT) | (hc_orig & MSR_HV_HYPERCALL_RSVD_MASK) | MSR_HV_HYPERCALL_ENABLE; wrmsr(MSR_HV_HYPERCALL, hc); /* * Confirm that Hypercall page did get setup. */ hc = rdmsr(MSR_HV_HYPERCALL); if ((hc & MSR_HV_HYPERCALL_ENABLE) == 0) { printf("hyperv: Hypercall setup failed\n"); /* Can't perform any Hyper-V specific actions */ vm_guest = VM_GUEST_VM; return (-1); } return (0); } void hypercall_disable(void) { uint64_t hc; /* Disable Hypercall */ hc = rdmsr(MSR_HV_HYPERCALL); wrmsr(MSR_HV_HYPERCALL, (hc & MSR_HV_HYPERCALL_RSVD_MASK)); } bool hyperv_identify_features(void) { u_int regs[4]; unsigned int maxleaf; if (vm_guest != VM_GUEST_HV) return (false); do_cpuid(CPUID_LEAF_HV_MAXLEAF, regs); maxleaf = regs[0]; if (maxleaf < CPUID_LEAF_HV_LIMITS) return (false); do_cpuid(CPUID_LEAF_HV_INTERFACE, regs); if (regs[0] != CPUID_HV_IFACE_HYPERV) return (false); do_cpuid(CPUID_LEAF_HV_FEATURES, regs); if ((regs[0] & CPUID_HV_MSR_HYPERCALL) == 0) { /* * Hyper-V w/o Hypercall is impossible; someone * is faking Hyper-V. */ return (false); } hyperv_features = regs[0]; hyperv_pm_features = regs[2]; hyperv_features3 = regs[3]; do_cpuid(CPUID_LEAF_HV_IDENTITY, regs); hyperv_ver_major = regs[1] >> 16; printf("Hyper-V Version: %d.%d.%d [SP%d]\n", hyperv_ver_major, regs[1] & 0xffff, regs[0], regs[2]); printf(" Features=0x%b\n", hyperv_features, "\020" "\001VPRUNTIME" /* MSR_HV_VP_RUNTIME */ "\002TMREFCNT" /* MSR_HV_TIME_REF_COUNT */ "\003SYNIC" /* MSRs for SynIC */ "\004SYNTM" /* MSRs for SynTimer */ "\005APIC" /* MSR_HV_{EOI,ICR,TPR} */ "\006HYPERCALL" /* MSR_HV_{GUEST_OS_ID,HYPERCALL} */ "\007VPINDEX" /* MSR_HV_VP_INDEX */ "\010RESET" /* MSR_HV_RESET */ "\011STATS" /* MSR_HV_STATS_ */ "\012REFTSC" /* MSR_HV_REFERENCE_TSC */ "\013IDLE" /* MSR_HV_GUEST_IDLE */ "\014TMFREQ" /* MSR_HV_{TSC,APIC}_FREQUENCY */ "\015DEBUG"); /* MSR_HV_SYNTH_DEBUG_ */ printf(" PM Features=0x%b [C%u]\n", (hyperv_pm_features & ~CPUPM_HV_CSTATE_MASK), "\020" "\005C3HPET", /* HPET is required for C3 state */ CPUPM_HV_CSTATE(hyperv_pm_features)); printf(" Features3=0x%b\n", hyperv_features3, "\020" "\001MWAIT" /* MWAIT */ "\002DEBUG" /* guest debug support */ "\003PERFMON" /* performance monitor */ "\004PCPUDPE" /* physical CPU dynamic partition event */ "\005XMMHC" /* hypercall input through XMM regs */ "\006IDLE" /* guest idle support */ "\007SLEEP" /* hypervisor sleep support */ "\010NUMA" /* NUMA distance query support */ "\011TMFREQ" /* timer frequency query (TSC, LAPIC) */ "\012SYNCMC" /* inject synthetic machine checks */ "\013CRASH" /* MSRs for guest crash */ "\014DEBUGMSR" /* MSRs for guest debug */ "\015NPIEP" /* NPIEP */ "\016HVDIS"); /* disabling hypervisor */ do_cpuid(CPUID_LEAF_HV_RECOMMENDS, regs); hyperv_recommends = regs[0]; if (bootverbose) printf(" Recommends: %08x %08x\n", regs[0], regs[1]); do_cpuid(CPUID_LEAF_HV_LIMITS, regs); if (bootverbose) { printf(" Limits: Vcpu:%d Lcpu:%d Int:%d\n", regs[0], regs[1], regs[2]); } if (maxleaf >= CPUID_LEAF_HV_HWFEATURES) { do_cpuid(CPUID_LEAF_HV_HWFEATURES, regs); if (bootverbose) { printf(" HW Features: %08x, AMD: %08x\n", regs[0], regs[3]); } } return (true); } diff --git a/sys/dev/hyperv/vmbus/x86/vmbus_x86.c b/sys/dev/hyperv/vmbus/x86/vmbus_x86.c index 4569b9dffa07..828827f77c35 100644 --- a/sys/dev/hyperv/vmbus/x86/vmbus_x86.c +++ b/sys/dev/hyperv/vmbus/x86/vmbus_x86.c @@ -1,196 +1,197 @@ /*- SPDX-License-Identifier: BSD-2-Clause-FreeBSD * Copyright (c) 2009-2012,2016-2017, 2022 Microsoft Corp. * Copyright (c) 2012 NetApp Inc. * Copyright (c) 2012 Citrix Inc. * 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 unmodified, 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 ``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 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. */ /* * VM Bus Driver Implementation */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include "acpi_if.h" #include "pcib_if.h" #include "vmbus_if.h" extern inthand_t IDTVEC(vmbus_isr), IDTVEC(vmbus_isr_pti); #define VMBUS_ISR_ADDR trunc_page((uintptr_t)IDTVEC(vmbus_isr_pti)) void vmbus_handle_timer_intr1(struct vmbus_message *msg_base, struct trapframe *frame); void vmbus_synic_setup1(void *xsc); void vmbus_synic_teardown1(void); int vmbus_setup_intr1(struct vmbus_softc *sc); void vmbus_intr_teardown1(struct vmbus_softc *sc); void vmbus_handle_timer_intr1(struct vmbus_message *msg_base, struct trapframe *frame) { volatile struct vmbus_message *msg; msg = msg_base + VMBUS_SINT_TIMER; if (msg->msg_type == HYPERV_MSGTYPE_TIMER_EXPIRED) { msg->msg_type = HYPERV_MSGTYPE_NONE; vmbus_et_intr(frame); /* * Make sure the write to msg_type (i.e. set to * HYPERV_MSGTYPE_NONE) happens before we read the * msg_flags and EOMing. Otherwise, the EOMing will * not deliver any more messages since there is no * empty slot * * NOTE: * mb() is used here, since atomic_thread_fence_seq_cst() * will become compiler fence on UP kernel. */ mb(); if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) { /* * This will cause message queue rescan to possibly * deliver another msg from the hypervisor */ wrmsr(MSR_HV_EOM, 0); } } return; } void vmbus_synic_setup1(void *xsc) { struct vmbus_softc *sc = xsc; uint32_t sint; uint64_t val, orig; sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER; orig = RDMSR(sint); val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI | (orig & MSR_HV_SINT_RSVD_MASK); WRMSR(sint, val); return; } void vmbus_synic_teardown1(void) { uint64_t orig; uint32_t sint; sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER; orig = RDMSR(sint); WRMSR(sint, orig | MSR_HV_SINT_MASKED); return; } int vmbus_setup_intr1(struct vmbus_softc *sc) { #if defined(__amd64__) && defined(KLD_MODULE) pmap_pti_add_kva(VMBUS_ISR_ADDR, VMBUS_ISR_ADDR + PAGE_SIZE, true); #endif /* * All Hyper-V ISR required resources are setup, now let's find a * free IDT vector for Hyper-V ISR and set it up. */ sc->vmbus_idtvec = lapic_ipi_alloc( pti ? IDTVEC(vmbus_isr_pti) : IDTVEC(vmbus_isr)); if (sc->vmbus_idtvec < 0) { #if defined(__amd64__) && defined(KLD_MODULE) pmap_pti_remove_kva(VMBUS_ISR_ADDR, VMBUS_ISR_ADDR + PAGE_SIZE); #endif device_printf(sc->vmbus_dev, "cannot find free IDT vector\n"); return ENXIO; } if (bootverbose) { device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n", sc->vmbus_idtvec); } return 0; } void vmbus_intr_teardown1(struct vmbus_softc *sc) { int cpu; if (sc->vmbus_idtvec >= 0) { lapic_ipi_free(sc->vmbus_idtvec); sc->vmbus_idtvec = -1; } #if defined(__amd64__) && defined(KLD_MODULE) pmap_pti_remove_kva(VMBUS_ISR_ADDR, VMBUS_ISR_ADDR + PAGE_SIZE); #endif CPU_FOREACH(cpu) { if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) { taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu)); VMBUS_PCPU_GET(sc, event_tq, cpu) = NULL; } if (VMBUS_PCPU_GET(sc, message_tq, cpu) != NULL) { taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu), VMBUS_PCPU_PTR(sc, message_task, cpu)); taskqueue_free(VMBUS_PCPU_GET(sc, message_tq, cpu)); VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL; } } }