svn commit: r310101 - in head: include sys/dev/hyperv/include sys/dev/hyperv/vmbus sys/dev/hyperv/vmbus/amd64

Sepherosa Ziehau sephe at FreeBSD.org
Thu Dec 15 03:32:25 UTC 2016


Author: sephe
Date: Thu Dec 15 03:32:24 2016
New Revision: 310101
URL: https://svnweb.freebsd.org/changeset/base/310101

Log:
  hyperv: Allow userland to ro-mmap reference TSC page
  
  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

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

Modified: head/include/Makefile
==============================================================================
--- head/include/Makefile	Thu Dec 15 02:05:29 2016	(r310100)
+++ head/include/Makefile	Thu Dec 15 03:32:24 2016	(r310101)
@@ -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 \

Modified: head/sys/dev/hyperv/include/hyperv.h
==============================================================================
--- head/sys/dev/hyperv/include/hyperv.h	Thu Dec 15 02:05:29 2016	(r310100)
+++ head/sys/dev/hyperv/include/hyperv.h	Thu Dec 15 03:32:24 2016	(r310101)
@@ -31,10 +31,10 @@
 #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
 
@@ -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_ */

Modified: head/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c	Thu Dec 15 02:05:29 2016	(r310100)
+++ head/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c	Thu Dec 15 03:32:24 2016	(r310101)
@@ -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_tim
 	.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, uin
 	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);

Modified: head/sys/dev/hyperv/vmbus/hyperv_reg.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hyperv_reg.h	Thu Dec 15 02:05:29 2016	(r310100)
+++ head/sys/dev/hyperv/vmbus/hyperv_reg.h	Thu Dec 15 03:32:24 2016	(r310101)
@@ -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 {


More information about the svn-src-head mailing list