]> xenbits.xensource.com Git - people/royger/freebsd.git/commitdiff
hyperv: Allow userland to ro-mmap reference TSC page github/projects/bsnmp-improved-ipv6-support
authorsephe <sephe@FreeBSD.org>
Thu, 15 Dec 2016 03:32:24 +0000 (03:32 +0000)
committersephe <sephe@FreeBSD.org>
Thu, 15 Dec 2016 03:32:24 +0000 (03:32 +0000)
This paves way to implement VDSO for the enlightened time counter.

Reviewed by: kib
MFC after: 1 week
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D8768

include/Makefile
sys/dev/hyperv/include/hyperv.h
sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c
sys/dev/hyperv/vmbus/hyperv_reg.h

index af291fa24b03337f254a4efc7c247251996af5d5..3032785e2543e6319fbdf59e777bdbc14d5023c2 100644 (file)
@@ -185,6 +185,9 @@ copies: .PHONY .META
            ${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 @@ symlinks: .PHONY .META
                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 44851444d26f785d188557a63251c3a1562ef70c..0eda9f0691a3640d892adea9c4a3700d79757d57 100644 (file)
 #ifndef _HYPERV_H_
 #define _HYPERV_H_
 
-#include <sys/param.h>
+#ifdef _KERNEL
 
-#include <vm/vm.h>
-#include <vm/pmap.h>
+#include <sys/param.h>
+#include <sys/systm.h>
 
 #define MSR_HV_TIME_REF_COUNT          0x40000020
 
 #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 712a6e22994bf2cd7b005192c67b99d0e9a0ce40..abf0372bb31efea59e8b9f3478e7c2b2a7fa236d 100644 (file)
@@ -28,6 +28,8 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/fcntl.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/timetc.h>
@@ -35,6 +37,9 @@ __FBSDID("$FreeBSD$");
 #include <machine/cpufunc.h>
 #include <machine/cputypes.h>
 #include <machine/md_var.h>
+#include <machine/specialreg.h>
+
+#include <vm/vm.h>
 
 #include <dev/hyperv/include/hyperv.h>
 #include <dev/hyperv/include/hyperv_busdma.h>
@@ -47,6 +52,9 @@ struct hyperv_reftsc_ctx {
        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 @@ static struct timecounter    hyperv_tsc_timecounter = {
        .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 @@ hypercall_md(volatile void *hc_addr, uint64_t in_val,
        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 @@ hyperv_tsc_tcinit(void *dummy __unused)
 
        /* 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 263a191fec235c120288696193dbbb06e7d63461..b3b133c8488193767de7010467351bbf71d62efd 100644 (file)
 #define CPUID_LEAF_HV_LIMITS           0x40000005
 #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
  */