diff options
Diffstat (limited to 'sys/dev/hyperv/vmbus')
-rw-r--r-- | sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c | 18 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/hyperv.c | 15 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/vmbus_et.c | 17 |
3 files changed, 38 insertions, 12 deletions
diff --git a/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c b/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c index 9caed81..118178f 100644 --- a/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c +++ b/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c @@ -118,8 +118,8 @@ hyperv_tsc_mmap(struct cdev *dev __unused, vm_ooffset_t offset, } #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; \ @@ -150,6 +150,13 @@ hyperv_tsc_timecount_##fence(struct timecounter *tc) \ /* 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); @@ -158,6 +165,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 & @@ -170,11 +178,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: @@ -199,6 +209,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); diff --git a/sys/dev/hyperv/vmbus/hyperv.c b/sys/dev/hyperv/vmbus/hyperv.c index 2df313b..144bff5 100644 --- a/sys/dev/hyperv/vmbus/hyperv.c +++ b/sys/dev/hyperv/vmbus/hyperv.c @@ -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 *tc __unused) 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, diff --git a/sys/dev/hyperv/vmbus/vmbus_et.c b/sys/dev/hyperv/vmbus/vmbus_et.c index 1e0c746..93f2ffa 100644 --- a/sys/dev/hyperv/vmbus/vmbus_et.c +++ b/sys/dev/hyperv/vmbus/vmbus_et.c @@ -50,13 +50,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); @@ -104,7 +101,7 @@ vmbus_et_start(struct eventtimer *et __unused, sbintime_t first, { uint64_t current; - current = rdmsr(MSR_HV_TIME_REF_COUNT); + current = hyperv_tc64(); current += hyperv_sbintime2count(first); wrmsr(MSR_HV_STIMER0_COUNT, current); @@ -133,7 +130,8 @@ vmbus_et_identify(driver_t *driver, device_t parent) { 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); @@ -189,9 +187,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); |