Index: include/Makefile =================================================================== --- include/Makefile +++ include/Makefile @@ -185,6 +185,9 @@ ${DESTDIR}${INCLUDEDIR}/dev/evdev; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 uinput.h \ ${DESTDIR}${INCLUDEDIR}/dev/evdev + 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 @@ -293,6 +296,11 @@ ln -fs ../../../../sys/dev/evdev/$$h \ ${DESTDIR}${INCLUDEDIR}/dev/evdev; \ done + 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 \ Index: sys/dev/hyperv/include/hyperv.h =================================================================== --- sys/dev/hyperv/include/hyperv.h +++ sys/dev/hyperv/include/hyperv.h @@ -31,10 +31,10 @@ #ifndef _HYPERV_H_ #define _HYPERV_H_ -#include +#ifdef _KERNEL -#include -#include +#include +#include #define MSR_HV_TIME_REF_COUNT 0x40000020 @@ -54,14 +54,35 @@ #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: sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c =================================================================== --- sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c +++ sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c @@ -28,6 +28,8 @@ __FBSDID("$FreeBSD$"); #include +#include +#include #include #include #include @@ -35,6 +37,9 @@ #include #include #include +#include + +#include #include #include @@ -47,6 +52,9 @@ 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, @@ -58,6 +66,13 @@ .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 @@ -72,6 +87,36 @@ 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) \ @@ -150,6 +195,10 @@ /* 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: sys/dev/hyperv/vmbus/hyperv_reg.h =================================================================== --- sys/dev/hyperv/vmbus/hyperv_reg.h +++ sys/dev/hyperv/vmbus/hyperv_reg.h @@ -129,17 +129,6 @@ #define CPUID_LEAF_HV_HWFEATURES 0x40000006 /* - * 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); -CTASSERT(sizeof(struct hyperv_reftsc) == PAGE_SIZE); - -/* * Hyper-V Monitor Notification Facility */ struct hyperv_mon_param {