Index: sys/conf/files.amd64 =================================================================== --- sys/conf/files.amd64 +++ sys/conf/files.amd64 @@ -564,6 +564,7 @@ x86/x86/identcpu.c standard x86/x86/intr_machdep.c standard x86/x86/io_apic.c standard +x86/x86/kvm.c standard x86/x86/legacy.c standard x86/x86/local_apic.c standard x86/x86/mca.c standard Index: sys/conf/files.i386 =================================================================== --- sys/conf/files.i386 +++ sys/conf/files.i386 @@ -582,6 +582,7 @@ x86/x86/identcpu.c standard x86/x86/intr_machdep.c standard x86/x86/io_apic.c optional apic +x86/x86/kvm.c standard x86/x86/legacy.c optional native x86/x86/local_apic.c optional apic x86/x86/mca.c standard Index: sys/kern/subr_param.c =================================================================== --- sys/kern/subr_param.c +++ sys/kern/subr_param.c @@ -160,6 +160,7 @@ "hv", "vmware", "bhyve", + "kvm", NULL }; CTASSERT(nitems(vm_guest_sysctl_names) - 1 == VM_LAST); Index: sys/sys/systm.h =================================================================== --- sys/sys/systm.h +++ sys/sys/systm.h @@ -73,7 +73,7 @@ * Keep in sync with vm_guest_sysctl_names[]. */ enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN, VM_GUEST_HV, - VM_GUEST_VMWARE, VM_GUEST_BHYVE, VM_LAST }; + VM_GUEST_VMWARE, VM_GUEST_BHYVE, VM_GUEST_KVM, VM_LAST }; #if defined(WITNESS) || defined(INVARIANTS) void kassert_panic(const char *fmt, ...) __printflike(1, 2); Index: sys/x86/include/kvm.h =================================================================== --- /dev/null +++ sys/x86/include/kvm.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2014 Bryan Venteicher + * 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, 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 _X86_KVM_H_ +#define _X86_KVM_H_ + +#define KVM_CPUID_FEATURES_LEAF 0x40000001 + +int kvm_paravirt_supported(void); +uint32_t kvm_get_features(void); + +#endif /* !_X86_KVM_H_ */ Index: sys/x86/x86/kvm.c =================================================================== --- /dev/null +++ sys/x86/x86/kvm.c @@ -0,0 +1,83 @@ +/*- + * Copyright (c) 2014 Bryan Venteicher + * 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, 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 + +static int kvm_cpuid_identify(void); + +static uint32_t kvm_cpuid_base = -1; +static uint32_t kvm_cpuid_high = -1; + +static int +kvm_cpuid_identify(void) +{ + + if (kvm_cpuid_base == -1) { + hypervisor_cpuid_base("KVMKVMKVM\0\0", 0, &kvm_cpuid_base, + &kvm_cpuid_high); + } + + return (kvm_cpuid_base > 0); +} + +int +kvm_paravirt_supported(void) +{ + + return (kvm_cpuid_base > 0); +} + +uint32_t +kvm_get_features(void) +{ + u_int regs[4]; + + if (kvm_paravirt_supported()) + do_cpuid(kvm_cpuid_base | KVM_CPUID_FEATURES_LEAF, regs); + else + regs[0] = 0; + + return (regs[0]); +} + +static void +kvm_init(void) +{ + + if (kvm_cpuid_identify() != 0) + hypervisor_register("KVM", VM_GUEST_KVM, NULL); +} + +HYPERVISOR_SYSINIT(kvm, kvm_init);