Index: stable/10/include/Makefile =================================================================== --- stable/10/include/Makefile (revision 311222) +++ stable/10/include/Makefile (revision 311223) @@ -1,376 +1,384 @@ # @(#)Makefile 8.2 (Berkeley) 1/4/94 # $FreeBSD$ # # Doing a "make install" builds /usr/include. .include CLEANFILES= osreldate.h version vers.c SUBDIR= arpa protocols rpcsvc rpc xlocale SUBDIR_PARALLEL= INCS= a.out.h ar.h assert.h bitstring.h complex.h cpio.h _ctype.h ctype.h \ db.h \ dirent.h dlfcn.h elf.h elf-hints.h err.h fmtmsg.h fnmatch.h fstab.h \ fts.h ftw.h getopt.h glob.h grp.h \ ieeefp.h ifaddrs.h \ inttypes.h iso646.h kenv.h langinfo.h libgen.h limits.h link.h \ locale.h malloc.h malloc_np.h memory.h monetary.h mpool.h mqueue.h \ ndbm.h netconfig.h \ netdb.h nl_types.h nlist.h nss.h nsswitch.h paths.h \ printf.h proc_service.h pthread.h \ pthread_np.h pwd.h ranlib.h readpassphrase.h regex.h \ res_update.h resolv.h runetype.h search.h semaphore.h setjmp.h \ signal.h spawn.h stab.h stdalign.h stdbool.h stddef.h \ stdnoreturn.h stdio.h stdlib.h string.h stringlist.h \ strings.h sysexits.h tar.h termios.h tgmath.h \ time.h timeconv.h timers.h ttyent.h \ uchar.h ulimit.h unistd.h utime.h utmpx.h uuid.h varargs.h \ wchar.h wctype.h wordexp.h xlocale.h .PATH: ${.CURDIR}/../contrib/libc-vis INCS+= vis.h MHDRS= float.h floatingpoint.h stdarg.h PHDRS= sched.h _semaphore.h LHDRS= aio.h errno.h fcntl.h linker_set.h poll.h stdatomic.h stdint.h \ syslog.h ucontext.h LDIRS= bsm cam geom net net80211 netatalk netgraph netinet netinet6 \ netipsec ${_netipx} netnatm netsmb \ nfs nfsclient nfsserver \ sys vm LSUBDIRS= cam/ata cam/scsi \ dev/acpica dev/agp dev/an dev/bktr dev/ciss dev/filemon dev/firewire \ dev/hwpmc dev/hyperv \ dev/ic dev/iicbus ${_dev_ieee488} dev/io dev/lmc dev/mfi dev/nvme \ dev/ofw dev/pbio dev/pci ${_dev_powermac_nvram} dev/ppbus dev/smbus \ dev/speaker dev/utopia dev/vkbd dev/wi \ fs/devfs fs/fdescfs fs/msdosfs fs/nandfs fs/nfs fs/nullfs \ fs/procfs fs/smbfs fs/udf fs/unionfs \ geom/cache geom/concat geom/eli geom/gate geom/journal geom/label \ geom/mirror geom/mountver geom/multipath geom/nop \ geom/raid geom/raid3 geom/shsec geom/stripe geom/virstor \ netgraph/atm netgraph/netflow \ security/audit \ security/mac_biba security/mac_bsdextended security/mac_lomac \ security/mac_mls security/mac_partition \ ufs/ffs ufs/ufs LSUBSUBDIRS= dev/mpt/mpilib .if ${MK_BLUETOOTH} != "no" LSUBSUBDIRS+= netgraph/bluetooth/include .endif .if ${MK_GPIB} != "no" _dev_ieee488= dev/ieee488 .endif .if ${MK_GSSAPI} != "no" SUBDIR+= gssapi INCS+= gssapi.h .endif .if ${MK_HESIOD} != "no" INCS+= hesiod.h .endif # XXX unconditionally needed by #.if ${MK_IPX} != "no" _netipx= netipx #.endif # Handle the #define aliases for libiconv .if ${MK_ICONV} == "yes" INCS+= iconv.h .endif .if ${MK_USB} != "no" LSUBDIRS+= dev/usb .endif .if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64" _dev_powermac_nvram= dev/powermac_nvram .endif # Define SHARED to indicate whether you want symbolic links to the system # source (``symlinks''), or a separate copy (``copies''). ``symlinks'' is # probably only useful for developers and should be avoided if you do not # wish to tie your /usr/include and /usr/src together. #SHARED= symlinks SHARED?= copies INCS+= osreldate.h SYSDIR= ${.CURDIR}/../sys NEWVERS_SH= ${SYSDIR}/conf/newvers.sh PARAM_H= ${SYSDIR}/sys/param.h MK_OSRELDATE_SH= ${.CURDIR}/mk-osreldate.sh osreldate.h vers.c: ${NEWVERS_SH} ${PARAM_H} ${MK_OSRELDATE_SH} env ECHO="${ECHO}" \ MAKE="${MAKE}" \ NEWVERS_SH=${NEWVERS_SH} \ PARAM_H=${PARAM_H} \ SYSDIR=${SYSDIR} \ sh ${MK_OSRELDATE_SH} .for i in ${LHDRS} INCSLINKS+= sys/$i ${INCLUDEDIR}/$i .endfor .for i in ${MHDRS} INCSLINKS+= machine/$i ${INCLUDEDIR}/$i .endfor .for i in ${PHDRS} INCSLINKS+= sys/$i ${INCLUDEDIR}/$i .endfor .if ${MACHINE} != ${MACHINE_CPUARCH} _MARCHS= ${MACHINE_CPUARCH} .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _MARCHS+= x86 .endif .include installincludes: ${SHARED} ${SHARED}: compat # Take care of stale directory-level symlinks. compat: .for i in ${LDIRS} ${LSUBDIRS} machine ${_MARCHS} crypto if [ -L ${DESTDIR}${INCLUDEDIR}/$i ]; then \ rm -f ${DESTDIR}${INCLUDEDIR}/$i; \ fi .endfor mtree -deU ${MTREE_FOLLOWS_SYMLINKS} \ -f ${.CURDIR}/../etc/mtree/BSD.include.dist \ -p ${DESTDIR}${INCLUDEDIR} copies: .for i in ${LDIRS} ${LSUBDIRS} ${LSUBSUBDIRS} altq crypto machine machine/pc \ ${_MARCHS} .if exists(${DESTDIR}${INCLUDEDIR}/$i) cd ${DESTDIR}${INCLUDEDIR}/$i; \ for h in *.h; do \ if [ -L $$h ]; then rm -f $$h; fi; \ done .endif .endfor .for i in ${LDIRS} ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/bktr:Ndev/hyperv:Ndev/nand:Ndev/pci} ${LSUBSUBDIRS} cd ${.CURDIR}/../sys; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 $i/*.h \ ${DESTDIR}${INCLUDEDIR}/$i .endfor cd ${.CURDIR}/../sys/dev/acpica; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 acpiio.h \ ${DESTDIR}${INCLUDEDIR}/dev/acpica; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 acpi_hpet.h \ ${DESTDIR}${INCLUDEDIR}/dev/acpica cd ${.CURDIR}/../sys/dev/agp; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 agpreg.h \ ${DESTDIR}${INCLUDEDIR}/dev/agp cd ${.CURDIR}/../sys/dev/bktr; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ioctl_*.h \ ${DESTDIR}${INCLUDEDIR}/dev/bktr .if ${MK_NAND} != "no" cd ${.CURDIR}/../sys/dev/nand; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 nandsim.h \ ${DESTDIR}${INCLUDEDIR}/dev/nand; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 nand_dev.h \ ${DESTDIR}${INCLUDEDIR}/dev/nand .endif + cd ${.CURDIR}/../sys/dev/hyperv/include; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 hyperv.h \ + ${DESTDIR}${INCLUDEDIR}/dev/hyperv cd ${.CURDIR}/../sys/dev/hyperv/utilities; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 hv_snapshot.h \ ${DESTDIR}${INCLUDEDIR}/dev/hyperv cd ${.CURDIR}/../sys/dev/pci; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 pcireg.h \ ${DESTDIR}${INCLUDEDIR}/dev/pci cd ${.CURDIR}/../sys/contrib/altq/altq; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}${INCLUDEDIR}/altq cd ${.CURDIR}/../sys/fs/cd9660/; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}${INCLUDEDIR}/isofs/cd9660 .if ${MK_IPFILTER} != "no" cd ${.CURDIR}/../sys/contrib/ipfilter/netinet; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}${INCLUDEDIR}/netinet .endif .if ${MK_PF} != "no" cd ${.CURDIR}/../sys/netpfil/pf; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}${INCLUDEDIR}/netpfil/pf .endif cd ${.CURDIR}/../sys/crypto; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 rijndael/rijndael.h \ ${DESTDIR}${INCLUDEDIR}/crypto cd ${.CURDIR}/../sys/opencrypto; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}${INCLUDEDIR}/crypto cd ${.CURDIR}/../sys/${MACHINE}/include; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}${INCLUDEDIR}/machine .if exists(${.CURDIR}/../sys/${MACHINE}/include/pc) cd ${.CURDIR}/../sys/${MACHINE}/include/pc; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}${INCLUDEDIR}/machine/pc .endif .for _MARCH in ${_MARCHS} .if exists(${.CURDIR}/../sys/${_MARCH}/include) ${INSTALL} -d -o ${BINOWN} -g ${BINGRP} -m 755 \ ${DESTDIR}${INCLUDEDIR}/${_MARCH}; \ cd ${.CURDIR}/../sys/${_MARCH}/include; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}${INCLUDEDIR}/${_MARCH} .if exists(${.CURDIR}/../sys/${_MARCH}/include/pc) ${INSTALL} -d -o ${BINOWN} -g ${BINGRP} -m 755 \ ${DESTDIR}${INCLUDEDIR}/${_MARCH}/pc; \ cd ${.CURDIR}/../sys/${_MARCH}/include/pc; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}${INCLUDEDIR}/${_MARCH}/pc .endif .endif .endfor cd ${.CURDIR}/../sys/rpc; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 types.h \ ${DESTDIR}${INCLUDEDIR}/rpc .if ${MK_CDDL} != "no" cd ${.CURDIR}/../cddl/contrib/opensolaris/lib/libzfs_core/common; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 libzfs_core.h \ ${DESTDIR}${INCLUDEDIR} cd ${.CURDIR}/../cddl/contrib/opensolaris/lib/libnvpair; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 libnvpair.h \ ${DESTDIR}${INCLUDEDIR} cd ${.CURDIR}/../sys/cddl/contrib/opensolaris/uts/common/sys; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 nvpair.h \ ${DESTDIR}${INCLUDEDIR}/sys .endif symlinks: @${ECHO} "Setting up symlinks to kernel source tree..." .for i in ${LDIRS} cd ${.CURDIR}/../sys/$i; \ for h in *.h; do \ ln -fs ../../../sys/$i/$$h ${DESTDIR}${INCLUDEDIR}/$i; \ done .endfor .for i in ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/bktr:Ndev/hyperv:Ndev/nand:Ndev/pci} cd ${.CURDIR}/../sys/$i; \ for h in *.h; do \ ln -fs ../../../../sys/$i/$$h ${DESTDIR}${INCLUDEDIR}/$i; \ done .endfor cd ${.CURDIR}/../sys/dev/acpica; \ for h in acpiio.h acpi_hpet.h; do \ ln -fs ../../../../sys/dev/acpica/$$h \ ${DESTDIR}${INCLUDEDIR}/dev/acpica; \ done cd ${.CURDIR}/../sys/dev/agp; \ for h in agpreg.h; do \ ln -fs ../../../../sys/dev/agp/$$h \ ${DESTDIR}${INCLUDEDIR}/dev/agp; \ done cd ${.CURDIR}/../sys/dev/bktr; \ for h in ioctl_*.h; do \ ln -fs ../../../../sys/dev/bktr/$$h \ ${DESTDIR}${INCLUDEDIR}/dev/bktr; \ done .if ${MK_NAND} != "no" cd ${.CURDIR}/../sys/dev/nand; \ for h in nandsim.h nand_dev.h; do \ ln -fs ../../../../sys/dev/nand/$$h \ ${DESTDIR}${INCLUDEDIR}/dev/nand; \ done .endif + cd ${.CURDIR}/../sys/dev/hyperv/include; \ + for h in hyperv.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/hyperv/include/$$h \ + ${DESTDIR}${INCLUDEDIR}/dev/hyperv; \ + done cd ${.CURDIR}/../sys/dev/hyperv/utilities; \ for h in hv_snapshot.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/hyperv/utilities/$$h \ ${DESTDIR}${INCLUDEDIR}/dev/hyperv; \ done cd ${.CURDIR}/../sys/dev/pci; \ for h in pcireg.h; do \ ln -fs ../../../../sys/dev/pci/$$h \ ${DESTDIR}${INCLUDEDIR}/dev/pci; \ done .for i in ${LSUBSUBDIRS} cd ${.CURDIR}/../sys/$i; \ for h in *.h; do \ ln -fs ../../../../../sys/$i/$$h ${DESTDIR}${INCLUDEDIR}/$i; \ done .endfor cd ${.CURDIR}/../sys/contrib/altq/altq; \ for h in *.h; do \ ln -fs ../../../sys/contrib/altq/altq/$$h \ ${DESTDIR}${INCLUDEDIR}/altq; \ done .if ${MK_IPFILTER} != "no" cd ${.CURDIR}/../sys/contrib/ipfilter/netinet; \ for h in *.h; do \ ln -fs ../../../sys/contrib/ipfilter/netinet/$$h \ ${DESTDIR}${INCLUDEDIR}/netinet; \ done .endif .if ${MK_PF} != "no" cd ${.CURDIR}/../sys/netpfil/pf; \ for h in *.h; do \ ln -fs ../../../../sys/netpfil/pf/$$h \ ${DESTDIR}${INCLUDEDIR}/netpfil/pf; \ done .endif cd ${.CURDIR}/../sys/crypto; \ for h in rijndael/rijndael.h; do \ ln -fs ../../../sys/crypto/$$h \ ${DESTDIR}${INCLUDEDIR}/crypto; \ done cd ${.CURDIR}/../sys/opencrypto; \ for h in *.h; do \ ln -fs ../../../sys/opencrypto/$$h \ ${DESTDIR}${INCLUDEDIR}/crypto; \ done cd ${.CURDIR}/../sys/${MACHINE}/include; \ for h in *.h; do \ ln -fs ../../../sys/${MACHINE}/include/$$h \ ${DESTDIR}${INCLUDEDIR}/machine; \ done .if exists(${.CURDIR}/../sys/${MACHINE}/include/pc) cd ${.CURDIR}/../sys/${MACHINE}/include/pc; \ for h in *.h; do \ ln -fs ../../../../sys/${MACHINE}/include/pc/$$h \ ${DESTDIR}${INCLUDEDIR}/machine/pc; \ done .endif .for _MARCH in ${_MARCHS} .if exists(${.CURDIR}/../sys/${_MARCH}/include) ${INSTALL} -d -o ${BINOWN} -g ${BINGRP} -m 755 \ ${DESTDIR}${INCLUDEDIR}/${_MARCH}; \ cd ${.CURDIR}/../sys/${_MARCH}/include; \ for h in *.h; do \ ln -fs ../../../sys/${_MARCH}/include/$$h \ ${DESTDIR}${INCLUDEDIR}/${_MARCH}; \ done .if exists(${.CURDIR}/../sys/${_MARCH}/include/pc) ${INSTALL} -d -o ${BINOWN} -g ${BINGRP} -m 755 \ ${DESTDIR}${INCLUDEDIR}/${_MARCH}/pc; \ cd ${.CURDIR}/../sys/${_MARCH}/include/pc; \ for h in *.h; do \ ln -fs ../../../../sys/${_MARCH}/include/pc/$$h \ ${DESTDIR}${INCLUDEDIR}/${_MARCH}/pc; \ done .endif .endif .endfor cd ${.CURDIR}/../sys/fs/cd9660; \ for h in *.h; do \ ln -fs ../../../../sys/fs/cd9660/$$h \ ${DESTDIR}${INCLUDEDIR}/isofs/cd9660; \ done cd ${.CURDIR}/../sys/rpc; \ for h in types.h; do \ ln -fs ../../../sys/rpc/$$h \ ${DESTDIR}${INCLUDEDIR}/rpc; \ done Index: stable/10/sys/dev/hyperv/include/hyperv.h =================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h (revision 311222) +++ stable/10/sys/dev/hyperv/include/hyperv.h (revision 311223) @@ -1,66 +1,88 @@ /*- * Copyright (c) 2009-2012,2016 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. * * $FreeBSD$ */ #ifndef _HYPERV_H_ #define _HYPERV_H_ +#ifdef _KERNEL + #include +#include -#include -#include - #define MSR_HV_TIME_REF_COUNT 0x40000020 #define CPUID_HV_MSR_TIME_REFCNT 0x0002 /* MSR_HV_TIME_REF_COUNT */ #define CPUID_HV_MSR_SYNIC 0x0004 /* MSRs for SynIC */ #define CPUID_HV_MSR_SYNTIMER 0x0008 /* MSRs for SynTimer */ #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_VP_INDEX 0x0040 /* MSR_HV_VP_INDEX */ +#define CPUID_HV_MSR_REFERENCE_TSC 0x0200 /* MSR_HV_REFERENCE_TSC */ #define CPUID_HV_MSR_GUEST_IDLE 0x0400 /* MSR_HV_GUEST_IDLE */ #ifndef NANOSEC #define NANOSEC 1000000000ULL #endif #define HYPERV_TIMER_NS_FACTOR 100ULL #define HYPERV_TIMER_FREQ (NANOSEC / HYPERV_TIMER_NS_FACTOR) +#endif /* _KERNEL */ + +#define HYPERV_REFTSC_DEVNAME "hv_tsc" + +/* + * Hyper-V Reference TSC + */ +struct hyperv_reftsc { + volatile uint32_t tsc_seq; + volatile uint32_t tsc_rsvd1; + volatile uint64_t tsc_scale; + volatile int64_t tsc_ofs; +} __packed __aligned(PAGE_SIZE); +#ifdef CTASSERT +CTASSERT(sizeof(struct hyperv_reftsc) == PAGE_SIZE); +#endif + +#ifdef _KERNEL + struct hyperv_guid { - uint8_t hv_guid[16]; + uint8_t hv_guid[16]; } __packed; -#define HYPERV_GUID_STRLEN 40 +#define HYPERV_GUID_STRLEN 40 int hyperv_guid2str(const struct hyperv_guid *, char *, size_t); extern u_int hyperv_features; /* CPUID_HV_MSR_ */ + +#endif /* _KERNEL */ #endif /* _HYPERV_H_ */ Index: stable/10/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c =================================================================== --- stable/10/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c (revision 311222) +++ stable/10/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c (revision 311223) @@ -1,43 +1,207 @@ /*- * 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. */ #include __FBSDID("$FreeBSD$"); #include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include #include +#include +#include +struct hyperv_reftsc_ctx { + struct hyperv_reftsc *tsc_ref; + struct hyperv_dma tsc_ref_dma; +}; + +static d_open_t hyperv_tsc_open; +static d_mmap_t hyperv_tsc_mmap; + +static struct timecounter hyperv_tsc_timecounter = { + .tc_get_timecount = NULL, /* based on CPU vendor. */ + .tc_poll_pps = NULL, + .tc_counter_mask = 0xffffffff, + .tc_frequency = HYPERV_TIMER_FREQ, + .tc_name = "Hyper-V-TSC", + .tc_quality = 3000, + .tc_flags = 0, + .tc_priv = NULL +}; + +static struct cdevsw hyperv_tsc_cdevsw = { + .d_version = D_VERSION, + .d_open = hyperv_tsc_open, + .d_mmap = hyperv_tsc_mmap, + .d_name = HYPERV_REFTSC_DEVNAME +}; + +static struct hyperv_reftsc_ctx hyperv_ref_tsc; + uint64_t hypercall_md(volatile void *hc_addr, uint64_t in_val, uint64_t in_paddr, uint64_t out_paddr) { uint64_t status; __asm__ __volatile__ ("mov %0, %%r8" : : "r" (out_paddr): "r8"); __asm__ __volatile__ ("call *%3" : "=a" (status) : "c" (in_val), "d" (in_paddr), "m" (hc_addr)); return (status); } + +static int +hyperv_tsc_open(struct cdev *dev __unused, int oflags, int devtype __unused, + struct thread *td __unused) +{ + + if (oflags & FWRITE) + return (EPERM); + return (0); +} + +static int +hyperv_tsc_mmap(struct cdev *dev __unused, vm_ooffset_t offset, + vm_paddr_t *paddr, int nprot __unused, vm_memattr_t *memattr __unused) +{ + + KASSERT(hyperv_ref_tsc.tsc_ref != NULL, ("reftsc has not been setup")); + + /* + * NOTE: + * 'nprot' does not contain information interested to us; + * WR-open is blocked by d_open. + */ + + if (offset != 0) + return (EOPNOTSUPP); + + *paddr = hyperv_ref_tsc.tsc_ref_dma.hv_paddr; + return (0); +} + +#define HYPERV_TSC_TIMECOUNT(fence) \ +static u_int \ +hyperv_tsc_timecount_##fence(struct timecounter *tc) \ +{ \ + struct hyperv_reftsc *tsc_ref = hyperv_ref_tsc.tsc_ref; \ + uint32_t seq; \ + \ + while ((seq = tsc_ref->tsc_seq) != 0) { \ + uint64_t disc, ret, tsc, scale; \ + int64_t ofs; \ + \ + __compiler_membar(); \ + scale = tsc_ref->tsc_scale; \ + ofs = tsc_ref->tsc_ofs; \ + \ + fence(); \ + tsc = rdtsc(); \ + \ + /* ret = ((tsc * scale) >> 64) + ofs */ \ + __asm__ __volatile__ ("mulq %3" : \ + "=d" (ret), "=a" (disc) : \ + "a" (tsc), "r" (scale)); \ + ret += ofs; \ + \ + __compiler_membar(); \ + if (tsc_ref->tsc_seq == seq) \ + return (ret); \ + \ + /* Sequence changed; re-sync. */ \ + } \ + /* Fallback to the generic timecounter, i.e. rdmsr. */ \ + return (rdmsr(MSR_HV_TIME_REF_COUNT)); \ +} \ +struct __hack + +HYPERV_TSC_TIMECOUNT(lfence); +HYPERV_TSC_TIMECOUNT(mfence); + +static void +hyperv_tsc_tcinit(void *dummy __unused) +{ + uint64_t val, orig; + + if ((hyperv_features & + (CPUID_HV_MSR_TIME_REFCNT | CPUID_HV_MSR_REFERENCE_TSC)) != + (CPUID_HV_MSR_TIME_REFCNT | CPUID_HV_MSR_REFERENCE_TSC) || + (cpu_feature & CPUID_SSE2) == 0) /* SSE2 for mfence/lfence */ + return; + + switch (cpu_vendor_id) { + case CPU_VENDOR_AMD: + hyperv_tsc_timecounter.tc_get_timecount = + hyperv_tsc_timecount_mfence; + break; + + case CPU_VENDOR_INTEL: + hyperv_tsc_timecounter.tc_get_timecount = + hyperv_tsc_timecount_lfence; + break; + + default: + /* Unsupport CPU vendors. */ + return; + } + + hyperv_ref_tsc.tsc_ref = hyperv_dmamem_alloc(NULL, PAGE_SIZE, 0, + sizeof(struct hyperv_reftsc), &hyperv_ref_tsc.tsc_ref_dma, + BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (hyperv_ref_tsc.tsc_ref == NULL) { + printf("hyperv: reftsc page allocation failed\n"); + return; + } + + orig = rdmsr(MSR_HV_REFERENCE_TSC); + val = MSR_HV_REFTSC_ENABLE | (orig & MSR_HV_REFTSC_RSVD_MASK) | + ((hyperv_ref_tsc.tsc_ref_dma.hv_paddr >> PAGE_SHIFT) << + MSR_HV_REFTSC_PGSHIFT); + wrmsr(MSR_HV_REFERENCE_TSC, val); + + /* Register "enlightened" timecounter. */ + tc_init(&hyperv_tsc_timecounter); + + /* Add device for mmap(2). */ + make_dev(&hyperv_tsc_cdevsw, 0, UID_ROOT, GID_WHEEL, 0444, + HYPERV_REFTSC_DEVNAME); +} +SYSINIT(hyperv_tsc_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, hyperv_tsc_tcinit, + NULL); Index: stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h =================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h (revision 311222) +++ stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h (revision 311223) @@ -1,188 +1,193 @@ /*- * 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_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_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_ */ Index: stable/10 =================================================================== --- stable/10 (revision 311222) +++ stable/10 (revision 311223) Property changes on: stable/10 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r310048,310101