Centralize the detection logic for the Hyper-V hypervisor.
Submitted by: Roger Pau Monné Sponsored by: Citrix Systems R&D Reviewed by: gibbs, grehan Approved by: re (gjb) sys/sys/systm.h: * Add a new VM_GUEST type, VM_GUEST_HV (HyperV guest). sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c: sys/dev/hyperv/vmbus/hv_hv.c: sys/dev/hyperv/stordisengage/hv_ata_pci_disengage.c: * Set vm_guest to VM_GUEST_HV and use that on other HyperV related devices instead of cloning the cpuid hypervisor check. * Cleanup the vmbus_identify function.
This commit is contained in:
parent
7a5016ea2d
commit
c8b87aac87
@ -75,17 +75,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/ata/ata-pci.h>
|
||||
#include <ata_if.h>
|
||||
|
||||
#define HV_X64_MSR_GUEST_OS_ID 0x40000000
|
||||
#define HV_X64_CPUID_MIN 0x40000005
|
||||
#define HV_X64_CPUID_MAX 0x4000ffff
|
||||
|
||||
/* prototypes */
|
||||
static int hv_ata_pci_probe(device_t dev);
|
||||
static int hv_ata_pci_attach(device_t dev);
|
||||
static int hv_ata_pci_detach(device_t dev);
|
||||
|
||||
static int hv_check_for_hyper_v(void);
|
||||
|
||||
/*
|
||||
* generic PCI ATA device probe
|
||||
*/
|
||||
@ -100,7 +94,7 @@ hv_ata_pci_probe(device_t dev)
|
||||
/*
|
||||
* Don't probe if not running in a Hyper-V environment
|
||||
*/
|
||||
if (!hv_check_for_hyper_v())
|
||||
if (vm_guest != VM_GUEST_HV)
|
||||
return (ENXIO);
|
||||
|
||||
if (device_get_unit(parent) != 0 || device_get_ivars(dev) != 0)
|
||||
@ -139,33 +133,6 @@ hv_ata_pci_detach(device_t dev)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect Hyper-V and enable fast IDE
|
||||
* via enlighted storage driver
|
||||
*/
|
||||
static int
|
||||
hv_check_for_hyper_v(void)
|
||||
{
|
||||
u_int regs[4];
|
||||
int hyper_v_detected;
|
||||
|
||||
hyper_v_detected = 0;
|
||||
do_cpuid(1, regs);
|
||||
if (regs[2] & 0x80000000) {
|
||||
/*
|
||||
* if(a hypervisor is detected)
|
||||
* make sure this really is Hyper-V
|
||||
*/
|
||||
do_cpuid(HV_X64_MSR_GUEST_OS_ID, regs);
|
||||
hyper_v_detected =
|
||||
regs[0] >= HV_X64_CPUID_MIN &&
|
||||
regs[0] <= HV_X64_CPUID_MAX &&
|
||||
!memcmp("Microsoft Hv", ®s[1], 12);
|
||||
}
|
||||
|
||||
return (hyper_v_detected);
|
||||
}
|
||||
|
||||
static device_method_t hv_ata_pci_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, hv_ata_pci_probe),
|
||||
|
@ -218,7 +218,7 @@ hv_vmbus_init(void)
|
||||
0,
|
||||
sizeof(hv_vmbus_handle) * MAXCPU);
|
||||
|
||||
if (!hv_vmbus_query_hypervisor_presence())
|
||||
if (vm_guest != VM_GUEST_HV)
|
||||
goto cleanup;
|
||||
|
||||
max_leaf = hv_vmbus_get_hypervisor_version();
|
||||
|
@ -295,11 +295,15 @@ hv_vmbus_child_device_unregister(struct hv_device *child_dev)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static void vmbus_identify(driver_t *driver, device_t parent) {
|
||||
static void
|
||||
vmbus_identify(driver_t *driver, device_t parent)
|
||||
{
|
||||
if (!hv_vmbus_query_hypervisor_presence())
|
||||
return;
|
||||
|
||||
vm_guest = VM_GUEST_HV;
|
||||
|
||||
BUS_ADD_CHILD(parent, 0, "vmbus", 0);
|
||||
if (device_find_child(parent, "vmbus", 0) == NULL) {
|
||||
BUS_ADD_CHILD(parent, 0, "vmbus", 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@ -307,9 +311,6 @@ vmbus_probe(device_t dev) {
|
||||
if(bootverbose)
|
||||
device_printf(dev, "VMBUS: probe\n");
|
||||
|
||||
if (!hv_vmbus_query_hypervisor_presence())
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "Vmbus Devices");
|
||||
|
||||
return (0);
|
||||
@ -491,10 +492,13 @@ vmbus_attach(device_t dev)
|
||||
static void
|
||||
vmbus_init(void)
|
||||
{
|
||||
if (vm_guest != VM_GUEST_HV)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the system has already booted and thread
|
||||
* scheduling is possible indicated by the global
|
||||
* cold set to zero, we just call the driver
|
||||
* scheduling is possible, as indicated by the
|
||||
* global cold set to zero, we just call the driver
|
||||
* initialization directly.
|
||||
*/
|
||||
if (!cold)
|
||||
|
@ -71,7 +71,7 @@ extern int vm_guest; /* Running as virtual machine guest? */
|
||||
* and/or add to the VM_GUEST_VM type if specific VM functionality is
|
||||
* ever implemented (e.g. vendor-specific paravirtualization features).
|
||||
*/
|
||||
enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN };
|
||||
enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN, VM_GUEST_HV };
|
||||
|
||||
#if defined(WITNESS) || defined(INVARIANTS)
|
||||
void kassert_panic(const char *fmt, ...) __printflike(1, 2);
|
||||
|
Loading…
Reference in New Issue
Block a user