Date: Mon, 9 Jan 2017 03:38:41 +0000 (UTC) From: Sepherosa Ziehau <sephe@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r311743 - in head/sys/dev/hyperv: include utilities vmbus vmbus/amd64 Message-ID: <201701090338.v093cf9t047600@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sephe Date: Mon Jan 9 03:38:41 2017 New Revision: 311743 URL: https://svnweb.freebsd.org/changeset/base/311743 Log: hyperv: Add method to read 64bit Hyper-V specific time value. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D9057 Modified: head/sys/dev/hyperv/include/hyperv.h head/sys/dev/hyperv/utilities/vmbus_timesync.c head/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c head/sys/dev/hyperv/vmbus/hyperv.c head/sys/dev/hyperv/vmbus/vmbus_et.c Modified: head/sys/dev/hyperv/include/hyperv.h ============================================================================== --- head/sys/dev/hyperv/include/hyperv.h Mon Jan 9 03:21:21 2017 (r311742) +++ head/sys/dev/hyperv/include/hyperv.h Mon Jan 9 03:38:41 2017 (r311743) @@ -79,9 +79,17 @@ struct hyperv_guid { #define HYPERV_GUID_STRLEN 40 -int hyperv_guid2str(const struct hyperv_guid *, char *, size_t); +typedef uint64_t (*hyperv_tc64_t)(void); -extern u_int hyperv_features; /* CPUID_HV_MSR_ */ +int hyperv_guid2str(const struct hyperv_guid *, char *, + size_t); + +/* + * hyperv_tc64 could be NULL, if there were no suitable Hyper-V + * specific timecounter. + */ +extern hyperv_tc64_t hyperv_tc64; +extern u_int hyperv_features; /* CPUID_HV_MSR_ */ #endif /* _KERNEL */ Modified: head/sys/dev/hyperv/utilities/vmbus_timesync.c ============================================================================== --- head/sys/dev/hyperv/utilities/vmbus_timesync.c Mon Jan 9 03:21:21 2017 (r311742) +++ head/sys/dev/hyperv/utilities/vmbus_timesync.c Mon Jan 9 03:38:41 2017 (r311743) @@ -52,8 +52,7 @@ __FBSDID("$FreeBSD$"); VMBUS_ICVER_LE(VMBUS_IC_VERSION(4, 0), (sc)->ic_msgver) #define VMBUS_TIMESYNC_DORTT(sc) \ - (VMBUS_TIMESYNC_MSGVER4((sc)) &&\ - (hyperv_features & CPUID_HV_MSR_TIME_REFCNT)) + (VMBUS_TIMESYNC_MSGVER4((sc)) && hyperv_tc64 != NULL) static int vmbus_timesync_probe(device_t); static int vmbus_timesync_attach(device_t); @@ -117,7 +116,7 @@ vmbus_timesync(struct vmbus_ic_softc *sc uint64_t hv_ns, vm_ns, rtt = 0; if (VMBUS_TIMESYNC_DORTT(sc)) - rtt = rdmsr(MSR_HV_TIME_REF_COUNT) - sent_tc; + rtt = hyperv_tc64() - sent_tc; hv_ns = (hvtime - VMBUS_ICMSG_TS_BASE + rtt) * HYPERV_TIMER_NS_FACTOR; nanotime(&vm_ts); Modified: head/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c ============================================================================== --- head/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c Mon Jan 9 03:21:21 2017 (r311742) +++ head/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c Mon Jan 9 03:38:41 2017 (r311743) @@ -133,8 +133,8 @@ hyperv_tsc_vdso_timehands(struct vdso_ti } #define HYPERV_TSC_TIMECOUNT(fence) \ -static u_int \ -hyperv_tsc_timecount_##fence(struct timecounter *tc) \ +static uint64_t \ +hyperv_tc64_tsc_##fence(void) \ { \ struct hyperv_reftsc *tsc_ref = hyperv_ref_tsc.tsc_ref; \ uint32_t seq; \ @@ -162,6 +162,13 @@ hyperv_tsc_timecount_##fence(struct time /* Fallback to the generic timecounter, i.e. rdmsr. */ \ return (rdmsr(MSR_HV_TIME_REF_COUNT)); \ } \ + \ +static u_int \ +hyperv_tsc_timecount_##fence(struct timecounter *tc __unused) \ +{ \ + \ + return (hyperv_tc64_tsc_##fence()); \ +} \ struct __hack HYPERV_TSC_TIMECOUNT(lfence); @@ -170,6 +177,7 @@ HYPERV_TSC_TIMECOUNT(mfence); static void hyperv_tsc_tcinit(void *dummy __unused) { + hyperv_tc64_t tc64 = NULL; uint64_t val, orig; if ((hyperv_features & @@ -182,11 +190,13 @@ hyperv_tsc_tcinit(void *dummy __unused) case CPU_VENDOR_AMD: hyperv_tsc_timecounter.tc_get_timecount = hyperv_tsc_timecount_mfence; + tc64 = hyperv_tc64_tsc_mfence; break; case CPU_VENDOR_INTEL: hyperv_tsc_timecounter.tc_get_timecount = hyperv_tsc_timecount_lfence; + tc64 = hyperv_tc64_tsc_lfence; break; default: @@ -211,6 +221,10 @@ hyperv_tsc_tcinit(void *dummy __unused) /* Register "enlightened" timecounter. */ tc_init(&hyperv_tsc_timecounter); + /* Install 64 bits timecounter method for other modules to use. */ + KASSERT(tc64 != NULL, ("tc64 is not set")); + hyperv_tc64 = tc64; + /* Add device for mmap(2). */ make_dev(&hyperv_tsc_cdevsw, 0, UID_ROOT, GID_WHEEL, 0444, HYPERV_REFTSC_DEVNAME); Modified: head/sys/dev/hyperv/vmbus/hyperv.c ============================================================================== --- head/sys/dev/hyperv/vmbus/hyperv.c Mon Jan 9 03:21:21 2017 (r311742) +++ head/sys/dev/hyperv/vmbus/hyperv.c Mon Jan 9 03:38:41 2017 (r311743) @@ -77,6 +77,8 @@ u_int hyperv_recommends; static u_int hyperv_pm_features; static u_int hyperv_features3; +hyperv_tc64_t hyperv_tc64; + static struct timecounter hyperv_timecounter = { .tc_get_timecount = hyperv_get_timecount, .tc_poll_pps = NULL, @@ -96,6 +98,13 @@ hyperv_get_timecount(struct timecounter return rdmsr(MSR_HV_TIME_REF_COUNT); } +static uint64_t +hyperv_tc64_rdmsr(void) +{ + + return (rdmsr(MSR_HV_TIME_REF_COUNT)); +} + uint64_t hypercall_post_message(bus_addr_t msg_paddr) { @@ -232,6 +241,12 @@ hyperv_init(void *dummy __unused) if (hyperv_features & CPUID_HV_MSR_TIME_REFCNT) { /* Register Hyper-V timecounter */ tc_init(&hyperv_timecounter); + + /* + * Install 64 bits timecounter method for other modules + * to use. + */ + hyperv_tc64 = hyperv_tc64_rdmsr; } } SYSINIT(hyperv_initialize, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, hyperv_init, Modified: head/sys/dev/hyperv/vmbus/vmbus_et.c ============================================================================== --- head/sys/dev/hyperv/vmbus/vmbus_et.c Mon Jan 9 03:21:21 2017 (r311742) +++ head/sys/dev/hyperv/vmbus/vmbus_et.c Mon Jan 9 03:38:41 2017 (r311743) @@ -48,13 +48,10 @@ __FBSDID("$FreeBSD$"); MSR_HV_STIMER_CFG_SINT_MASK) /* - * Two additionally required features: + * Additionally required feature: * - SynIC is needed for interrupt generation. - * - Time reference counter is needed to set ABS reference count to - * STIMER0_COUNT. */ -#define CPUID_HV_ET_MASK (CPUID_HV_MSR_TIME_REFCNT | \ - CPUID_HV_MSR_SYNIC | \ +#define CPUID_HV_ET_MASK (CPUID_HV_MSR_SYNIC | \ CPUID_HV_MSR_SYNTIMER) static void vmbus_et_identify(driver_t *, device_t); @@ -102,7 +99,7 @@ vmbus_et_start(struct eventtimer *et __u { uint64_t current; - current = rdmsr(MSR_HV_TIME_REF_COUNT); + current = hyperv_tc64(); current += hyperv_sbintime2count(first); wrmsr(MSR_HV_STIMER0_COUNT, current); @@ -131,7 +128,8 @@ vmbus_et_identify(driver_t *driver, devi { if (device_get_unit(parent) != 0 || device_find_child(parent, VMBUS_ET_NAME, -1) != NULL || - (hyperv_features & CPUID_HV_ET_MASK) != CPUID_HV_ET_MASK) + (hyperv_features & CPUID_HV_ET_MASK) != CPUID_HV_ET_MASK || + hyperv_tc64 == NULL) return; device_add_child(parent, VMBUS_ET_NAME, -1); @@ -187,9 +185,8 @@ vmbus_et_attach(device_t dev) vmbus_et.et_start = vmbus_et_start; /* - * Delay a bit to make sure that MSR_HV_TIME_REF_COUNT will - * not return 0, since writing 0 to STIMER0_COUNT will disable - * STIMER0. + * Delay a bit to make sure that hyperv_tc64 will not return 0, + * since writing 0 to STIMER0_COUNT will disable STIMER0. */ DELAY(100); smp_rendezvous(NULL, vmbus_et_config, NULL, NULL);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701090338.v093cf9t047600>