Skip to content

Commit b383eb8

Browse files
committed
TimeSync: Added reference counter adjustments
1 parent a7b9445 commit b383eb8

14 files changed

Lines changed: 48 additions & 67 deletions

Changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ MacHyperVSupport Changelog
88
- Fixed intermittent hangs in storage and network drivers
99
- Added support for storage disk addition and removal while VM is running
1010
- Added support for guest restart via Restart-VM
11+
- Renamed hvshutdown daemon to hvutil to support all userspace-side functions
12+
- Added guest time synchronization support
1113

1214
#### v0.9.1
1315
- Added initial PCI passthrough support

MacHyperVSupport/Controller/HyperV.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,6 @@ constexpr size_t ARRAY_SIZE(const T (&array)[N]) {
406406
//
407407
// Hyper-V CPUID feature support
408408
//
409-
#define MSR_HV_TIME_REF_COUNT 0x40000020
410-
411409
#define kHyperVCpuidMsrTimeRefCnt 0x0002
412410
#define kHyperVCpuidMsrSynIC 0x0004
413411
#define kHyperVCpuidMsrSynTimer 0x0008
@@ -423,7 +421,7 @@ constexpr size_t ARRAY_SIZE(const T (&array)[N]) {
423421
//
424422
// Hyper-V MSRs
425423
//
426-
#define kHyperVMsrGuestID 0x40000000
424+
#define kHyperVMsrGuestID 0x40000000
427425
#define kHyperVMsrGuestIDBuildMask 0xFFFFULL
428426
#define kHyperVMsrGuestIDServicePackMask 0x0000000000FF0000ULL
429427
#define kHyperVMsrGuestIDServicePackShift 16
@@ -444,6 +442,8 @@ constexpr size_t ARRAY_SIZE(const T (&array)[N]) {
444442

445443
#define kHyperVMsrVPIndex 0x40000002
446444

445+
#define kHyperVMsrTimeRefCount 0x40000020
446+
447447
#define kHyperVMsrReferenceTsc 0x40000021
448448
#define kHyperVMsrReferenceTscEnable 0x0001ULL
449449
#define kHyperVMsrReferenceTscRsvdMask 0x0FFEULL

MacHyperVSupport/Controller/HyperVController.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ class HyperVController : public IOService {
124124
void disableInterrupts();
125125
void sendSynICEOM(UInt32 cpu);
126126

127+
//
128+
// Time reference counter.
129+
//
130+
inline bool isTimeRefCounterSupported() { return (_hvFeatures & kHyperVCpuidMsrTimeRefCnt); }
131+
inline UInt64 readTimeRefCounter() { return isTimeRefCounterSupported() ? rdmsr64(kHyperVMsrTimeRefCount) : 0; }
132+
127133
//
128134
// Messages.
129135
//

MacHyperVSupport/IntegrationComponents/Shutdown/HyperVShutdown.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ bool HyperVShutdown::handleShutdown(VMBusICMessageShutdownData *shutdownData) {
9595
//
9696
// Send message to userclients to see if we can shutdown.
9797
//
98-
result = _hvDevice->checkUserClient();
98+
result = _hvDevice->getHvController()->checkUserClient();
9999
if (result) {
100100
result = performShutdown(shutdownData, false);
101101
if (!result) {
@@ -115,15 +115,15 @@ bool HyperVShutdown::performShutdown(VMBusICMessageShutdownData *shutdownData, b
115115
case kVMBusICShutdownFlagsShutdownForced:
116116
if (doShutdown) {
117117
HVDBGLOG("Performing shutdown");
118-
_hvDevice->notifyUserClient(kHyperVUserClientNotificationTypePerformShutdown, nullptr, 0);
118+
_hvDevice->getHvController()->notifyUserClient(kHyperVUserClientNotificationTypePerformShutdown, nullptr, 0);
119119
}
120120
break;
121121

122122
case kVMBusICShutdownFlagsRestart:
123123
case kVMBusICShutdownFlagsRestartForced:
124124
if (doShutdown) {
125125
HVDBGLOG("Performing restart");
126-
_hvDevice->notifyUserClient(kHyperVUserClientNotificationTypePerformRestart, nullptr, 0);
126+
_hvDevice->getHvController()->notifyUserClient(kHyperVUserClientNotificationTypePerformRestart, nullptr, 0);
127127
}
128128
break;
129129

MacHyperVSupport/IntegrationComponents/TimeSync/HyperVTimeSync.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,20 +91,29 @@ void HyperVTimeSync::handlePacket(VMBusPacketHeader *pktHeader, UInt32 pktHeader
9191

9292
void HyperVTimeSync::handleTimeAdjust(UInt64 hostTime, UInt64 referenceTime, VMBusICTimeSyncFlags flags) {
9393
UInt64 hvTimeNs;
94+
UInt64 hvRefTimeAdjust = 0;
9495
HyperVUserClientTimeData timeData;
9596

9697
HVDBGLOG("Time sync request %u received (host time: %llu, ref time: %llu)", flags, hostTime, referenceTime);
9798

9899
if (flags != kVMBusICTimeSyncFlagsSync) {
99100
return;
100101
}
102+
103+
//
104+
// Adjust time based on provided and current reference counter.
105+
//
106+
if (referenceTime != 0 && _hvDevice->getHvController()->isTimeRefCounterSupported()) {
107+
hvRefTimeAdjust = _hvDevice->getHvController()->readTimeRefCounter() - referenceTime;
108+
HVDBGLOG("Time sync will be adjusted by %llu", hvRefTimeAdjust);
109+
}
101110

102111
//
103112
// Calculate epoch and break out into seconds and microseconds remainder.
104113
//
105-
hvTimeNs = (hostTime - kHyperVTimeSyncTimeBase) * kHyperVTimerNanosecondFactor;
114+
hvTimeNs = (hostTime - kHyperVTimeSyncTimeBase + hvRefTimeAdjust) * kHyperVTimerNanosecondFactor;
106115
timeData.seconds = (clock_sec_t)(hvTimeNs / NSEC_PER_SEC);
107116
timeData.microseconds = (hvTimeNs % NSEC_PER_SEC) / NSEC_PER_USEC;
108117

109-
_hvDevice->notifyUserClient(kHyperVUserClientNotificationTypeTimeSync, &timeData, sizeof (timeData));
118+
_hvDevice->getHvController()->notifyUserClient(kHyperVUserClientNotificationTypeTimeSync, &timeData, sizeof (timeData));
110119
}

MacHyperVSupport/IntegrationComponents/TimeSync/HyperVTimeSync.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ class HyperVTimeSync : public HyperVICService {
1919
private:
2020
VMBusICVersion _timeSyncCurrentVersion = kHyperVTimeSyncVersionV1_0;
2121

22+
//
23+
void handleTimeAdjust(UInt64 hostTime, UInt64 referenceTime, VMBusICTimeSyncFlags flags);
24+
2225
protected:
2326
void handlePacket(VMBusPacketHeader *pktHeader, UInt32 pktHeaderLength, UInt8 *pktData, UInt32 pktDataLength) APPLE_KEXT_OVERRIDE;
24-
void handleTimeAdjust(UInt64 hostTime, UInt64 referenceTime, VMBusICTimeSyncFlags flags);
2527

2628
public:
2729
//

MacHyperVSupport/Network/HyperVNetworkPrivate.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ IOReturn HyperVNetwork::initSendReceiveBuffers() {
129129
//
130130
// Allocate receive and send buffers and create GPADLs for them.
131131
//
132-
if (!_hvDevice->allocateDmaBuffer(&_receiveBuffer, _receiveBufferSize)) {
132+
if (!_hvDevice->getHvController()->allocateDmaBuffer(&_receiveBuffer, _receiveBufferSize)) {
133133
HVSYSLOG("Failed to allocate receive buffer");
134134
freeSendReceiveBuffers();
135135
return kIOReturnNoResources;
@@ -139,7 +139,7 @@ IOReturn HyperVNetwork::initSendReceiveBuffers() {
139139
freeSendReceiveBuffers();
140140
return kIOReturnIOError;
141141
}
142-
if (!_hvDevice->allocateDmaBuffer(&_sendBuffer, _sendBufferSize)) {
142+
if (!_hvDevice->getHvController()->allocateDmaBuffer(&_sendBuffer, _sendBufferSize)) {
143143
HVSYSLOG("Failed to allocate send buffer");
144144
freeSendReceiveBuffers();
145145
return kIOReturnNoResources;
@@ -234,7 +234,7 @@ void HyperVNetwork::freeSendReceiveBuffers() {
234234
_hvDevice->freeGPADLBuffer(_receiveGpadlHandle);
235235
_receiveGpadlHandle = kHyperVGpadlNullHandle;
236236
}
237-
_hvDevice->freeDmaBuffer(&_receiveBuffer);
237+
_hvDevice->getHvController()->freeDmaBuffer(&_receiveBuffer);
238238

239239
//
240240
// Release and free send buffer.
@@ -243,7 +243,7 @@ void HyperVNetwork::freeSendReceiveBuffers() {
243243
_hvDevice->freeGPADLBuffer(_sendGpadlHandle);
244244
_sendGpadlHandle = kHyperVGpadlNullHandle;
245245
}
246-
_hvDevice->freeDmaBuffer(&_sendBuffer);
246+
_hvDevice->getHvController()->freeDmaBuffer(&_sendBuffer);
247247

248248
//
249249
// Free send section tracking bitmap.

MacHyperVSupport/Network/HyperVNetworkRNDIS.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ HyperVNetworkRNDISRequest* HyperVNetwork::allocateRNDISRequest(size_t additional
111111
//
112112
// Create DMA buffer with required specifications and get physical address.
113113
//
114-
if (!_hvDevice->allocateDmaBuffer(&dmaBuffer, sizeof (HyperVNetworkRNDISRequest) + additionalLength)) {
114+
if (!_hvDevice->getHvController()->allocateDmaBuffer(&dmaBuffer, sizeof (HyperVNetworkRNDISRequest) + additionalLength)) {
115115
HVSYSLOG("Failed to allocate buffer memory for RNDIS request");
116116
IOLockFree(lock);
117117
}
@@ -129,7 +129,7 @@ HyperVNetworkRNDISRequest* HyperVNetwork::allocateRNDISRequest(size_t additional
129129

130130
void HyperVNetwork::freeRNDISRequest(HyperVNetworkRNDISRequest *rndisRequest) {
131131
IOLockFree(rndisRequest->lock);
132-
_hvDevice->freeDmaBuffer(&rndisRequest->dmaBuffer);
132+
_hvDevice->getHvController()->freeDmaBuffer(&rndisRequest->dmaBuffer);
133133
}
134134

135135
UInt32 HyperVNetwork::getNextRNDISTransId() {

MacHyperVSupport/VMBus/HyperVVMBus.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -464,19 +464,3 @@ void HyperVVMBus::freeVMBusChannel(UInt32 channelId) {
464464
HVDBGLOG("Channel %u is now freed", channelId);
465465
channel->status = kVMBusChannelStatusNotPresent;
466466
}
467-
468-
bool HyperVVMBus::allocateDmaBuffer(HyperVDMABuffer *dmaBuf, size_t size) {
469-
return hvController->allocateDmaBuffer(dmaBuf, size);
470-
}
471-
472-
void HyperVVMBus::freeDmaBuffer(HyperVDMABuffer *dmaBuf) {
473-
hvController->freeDmaBuffer(dmaBuf);
474-
}
475-
476-
bool HyperVVMBus::checkUserClient() {
477-
return hvController->checkUserClient();
478-
}
479-
480-
IOReturn HyperVVMBus::notifyUserClient(HyperVUserClientNotificationType type, void *data, UInt32 dataLength) {
481-
return hvController->notifyUserClient(type, data, dataLength);
482-
}

MacHyperVSupport/VMBus/HyperVVMBus.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,7 @@ class HyperVVMBus : public IOService {
157157
//
158158
// Misc functions.
159159
//
160-
bool allocateDmaBuffer(HyperVDMABuffer *dmaBuf, size_t size);
161-
void freeDmaBuffer(HyperVDMABuffer *dmaBuf);
162-
bool checkUserClient();
163-
IOReturn notifyUserClient(HyperVUserClientNotificationType type, void *data, UInt32 dataLength);
160+
inline HyperVController *getHvController() { return hvController; }
164161

165162
//
166163
// VMBus channel management.

0 commit comments

Comments
 (0)