mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-04 12:52:15 +00:00
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
This commit is contained in:
parent
1de8c69de7
commit
9622c93ae8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=310101
@ -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 \
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
|
@ -128,17 +128,6 @@
|
||||
#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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user