From 4d9139667c6f31eb790d7dee4c81d177674d307c Mon Sep 17 00:00:00 2001 From: Patrick Wildt Date: Tue, 31 Aug 2021 15:52:11 +0000 Subject: When running on Hyper-V, make use of its timecounter as delay func in case we're still using the i8254 for that. On Hyper-V Gen 2 VMs there is no i8254 we can trust, so we need some kind of fallback, especially if there is no TSC either. Discussed with the hackroom ok kettenis@ --- sys/dev/pv/hyperv.c | 12 ++++++++++++ sys/dev/pv/pvbus.c | 13 ++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/dev/pv/hyperv.c b/sys/dev/pv/hyperv.c index de753ccbfc9..dcebd3ae681 100644 --- a/sys/dev/pv/hyperv.c +++ b/sys/dev/pv/hyperv.c @@ -349,6 +349,18 @@ hv_gettime(struct timecounter *tc) return (now); } +void +hv_delay(int usecs) +{ + uint64_t interval, start; + + /* 10 MHz fixed frequency */ + interval = (uint64_t)usecs * 10; + start = rdmsr(MSR_HV_TIME_REF_COUNT); + while (rdmsr(MSR_HV_TIME_REF_COUNT) - start < interval) + CPU_BUSY_CYCLE(); +} + int hv_init_hypercall(struct hv_softc *sc) { diff --git a/sys/dev/pv/pvbus.c b/sys/dev/pv/pvbus.c index 19098a28d2f..b7bbe91ee33 100644 --- a/sys/dev/pv/pvbus.c +++ b/sys/dev/pv/pvbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pvbus.c,v 1.22 2020/08/26 03:29:06 visa Exp $ */ +/* $OpenBSD: pvbus.c,v 1.23 2021/08/31 15:52:10 patrick Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -40,6 +40,9 @@ #include #include +#include + +#include "hyperv.h" int has_hv_cpuid = 0; @@ -297,6 +300,8 @@ pvbus_kvm(struct pvbus_hv *hv) hv->hv_features = regs[0]; } +extern void hv_delay(int usecs); + void pvbus_hyperv(struct pvbus_hv *hv) { @@ -312,6 +317,12 @@ pvbus_hyperv(struct pvbus_hv *hv) HYPERV_VERSION_EBX_MAJOR_S; hv->hv_minor = (regs[1] & HYPERV_VERSION_EBX_MINOR_M) >> HYPERV_VERSION_EBX_MINOR_S; + +#if NHYPERV > 0 + if (hv->hv_features & CPUID_HV_MSR_TIME_REFCNT && + delay_func == i8254_delay) + delay_func = hv_delay; +#endif } void -- cgit v1.2.3