hyperv: Test features before enabling optional functionalities

MFC after:	1 week
Sponsored by:	Microsoft OSTC
Differential Revision:	https://reviews.freebsd.org/D6571
This commit is contained in:
Sepherosa Ziehau 2016-05-27 07:29:31 +00:00
parent 63b3f62ab3
commit 5cb904dc2f
6 changed files with 69 additions and 10 deletions

View File

@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
#include <dev/hyperv/vmbus/hyperv_reg.h>
#include <dev/hyperv/vmbus/hyperv_var.h>
#define HV_TIMER_FREQUENCY (10 * 1000 * 1000LL) /* 100ns period */
#define HV_MAX_DELTA_TICKS 0xffffffffLL
@ -48,6 +49,16 @@ __FBSDID("$FreeBSD$");
((((uint64_t)HV_VMBUS_TIMER_SINT) << MSR_HV_STIMER_CFG_SINT_SHIFT) & \
MSR_HV_STIMER_CFG_SINT_MASK)
/*
* Two additionally required features:
* - SynIC is needed for interrupt generation.
* - Time reference counter is needed to set ABS reference count to
* STIMER0_COUNT.
*/
#define CPUID_HV_ET_MASK (CPUID_HV_MSR_TIME_REFCNT | \
CPUID_HV_MSR_SYNIC | \
CPUID_HV_MSR_SYNTIMER)
static struct eventtimer *et;
static inline uint64_t
@ -104,7 +115,8 @@ hv_et_intr(struct trapframe *frame)
static void
hv_et_identify(driver_t *driver, device_t parent)
{
if (device_find_child(parent, "hv_et", -1) != NULL)
if (device_find_child(parent, "hv_et", -1) != NULL ||
(hyperv_features & CPUID_HV_ET_MASK) != CPUID_HV_ET_MASK)
return;
device_add_child(parent, "hv_et", -1);

View File

@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <dev/hyperv/include/hyperv_busdma.h>
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
#include <dev/hyperv/vmbus/hyperv_reg.h>
#include <dev/hyperv/vmbus/hyperv_var.h>
#include <dev/hyperv/vmbus/vmbus_var.h>
#define HV_NANOSECONDS_PER_SEC 1000000000L

View File

@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
#include <dev/hyperv/vmbus/hyperv_reg.h>
#include <dev/hyperv/vmbus/hyperv_var.h>
#include <dev/hyperv/vmbus/vmbus_var.h>
#include <contrib/dev/acpica/include/acpi.h>
@ -215,10 +216,21 @@ vmbus_synic_setup(void *xsc)
uint64_t val, orig;
uint32_t sint;
/*
* Save virtual processor id.
*/
VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
if (hyperv_features & CPUID_HV_MSR_VP_INDEX) {
/*
* Save virtual processor id.
*/
VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
} else {
/*
* XXX
* Virtual processoor id is only used by a pretty broken
* channel selection code from storvsc. It's nothing
* critical even if CPUID_HV_MSR_VP_INDEX is not set; keep
* moving on.
*/
VMBUS_PCPU_GET(sc, vcpuid, cpu) = cpu;
}
/*
* Setup the SynIC message.
@ -557,7 +569,8 @@ static int
vmbus_probe(device_t dev)
{
if (ACPI_ID_PROBE(device_get_parent(dev), dev, vmbus_ids) == NULL ||
device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV)
device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV ||
(hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
return (ENXIO);
device_set_desc(dev, "Hyper-V Vmbus");

View File

@ -451,9 +451,6 @@ typedef enum {
extern hv_vmbus_connection hv_vmbus_g_connection;
extern u_int hyperv_features;
extern u_int hyperv_recommends;
typedef void (*vmbus_msg_handler)(hv_vmbus_channel_msg_header *msg);
typedef struct hv_vmbus_channel_msg_table_entry {

View File

@ -110,7 +110,8 @@
#define CPUID_HV_MSR_APIC 0x0010 /* MSR_HV_{EOI,ICR,TPR} */
#define CPUID_HV_MSR_HYPERCALL 0x0020 /* MSR_HV_GUEST_OS_ID
* MSR_HV_HYPERCALL */
#define CPUID_HV_MSR_GUEST_IDLE 0x0400 /* MSR_VH_GUEST_IDLE */
#define CPUID_HV_MSR_VP_INDEX 0x0040 /* MSR_HV_VP_INDEX */
#define CPUID_HV_MSR_GUEST_IDLE 0x0400 /* MSR_HV_GUEST_IDLE */
/* ECX: power management features */
#define CPUPM_HV_CSTATE_MASK 0x000f /* deepest C-state */
#define CPUPM_HV_C3_HPET 0x0010 /* C3 requires HPET */

View File

@ -0,0 +1,35 @@
/*-
* Copyright (c) 2016 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_VAR_H_
#define _HYPERV_VAR_H_
extern u_int hyperv_features;
extern u_int hyperv_recommends;
#endif /* !_HYPERV_VAR_H_ */