From ecdcee0674e19d97166a740fe724d6b340d47e28 Mon Sep 17 00:00:00 2001 From: gibbs Date: Fri, 18 Oct 2013 23:19:27 +0000 Subject: MFC r256425: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. ------------------------------------------------------------------------ --- .../hyperv/stordisengage/hv_ata_pci_disengage.c | 35 +--------------------- sys/dev/hyperv/vmbus/hv_hv.c | 2 +- sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c | 22 ++++++++------ sys/sys/systm.h | 2 +- 4 files changed, 16 insertions(+), 45 deletions(-) diff --git a/sys/dev/hyperv/stordisengage/hv_ata_pci_disengage.c b/sys/dev/hyperv/stordisengage/hv_ata_pci_disengage.c index 6ca0665..323b4e7 100644 --- a/sys/dev/hyperv/stordisengage/hv_ata_pci_disengage.c +++ b/sys/dev/hyperv/stordisengage/hv_ata_pci_disengage.c @@ -75,17 +75,11 @@ __FBSDID("$FreeBSD$"); #include #include -#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), diff --git a/sys/dev/hyperv/vmbus/hv_hv.c b/sys/dev/hyperv/vmbus/hv_hv.c index 77d3b0b..80a1f42 100644 --- a/sys/dev/hyperv/vmbus/hv_hv.c +++ b/sys/dev/hyperv/vmbus/hv_hv.c @@ -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(); diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c index fb9e147..7f1647b 100644 --- a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c +++ b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c @@ -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) diff --git a/sys/sys/systm.h b/sys/sys/systm.h index f097e83..2000e92 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -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); -- cgit v1.1