Skip to content

Commit

Permalink
Initial networking support (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
Goldfish64 committed Sep 18, 2021
1 parent 532b6c6 commit 0fb421b
Show file tree
Hide file tree
Showing 33 changed files with 2,156 additions and 502 deletions.
8 changes: 8 additions & 0 deletions MacHyperVSupport.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
419B88C5263F1F85005A9977 /* VMBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 419B88C4263F1F85005A9977 /* VMBus.cpp */; };
41B41BDD26C74B4C00926A0D /* HyperVNetwork.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41B41BDB26C74B4C00926A0D /* HyperVNetwork.cpp */; };
41B41BDE26C74B4C00926A0D /* HyperVNetwork.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 41B41BDC26C74B4C00926A0D /* HyperVNetwork.hpp */; };
41B41BE426C84A9F00926A0D /* HyperVNetworkPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41B41BE326C84A9F00926A0D /* HyperVNetworkPrivate.cpp */; };
41B41BE726CDC42D00926A0D /* HyperVNetworkRNDIS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41B41BE626CDC42D00926A0D /* HyperVNetworkRNDIS.cpp */; };
41BE411A263EDFAF0018C52B /* HyperVVMBusController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41BE4118263EDFAF0018C52B /* HyperVVMBusController.cpp */; };
41BE411B263EDFAF0018C52B /* HyperVVMBusController.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 41BE4119263EDFAF0018C52B /* HyperVVMBusController.hpp */; };
41E2EC78263F894300BBE18F /* SynIC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E2EC77263F894300BBE18F /* SynIC.cpp */; };
Expand Down Expand Up @@ -114,6 +116,8 @@
41B41BDB26C74B4C00926A0D /* HyperVNetwork.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = HyperVNetwork.cpp; sourceTree = "<group>"; };
41B41BDC26C74B4C00926A0D /* HyperVNetwork.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = HyperVNetwork.hpp; sourceTree = "<group>"; };
41B41BE126C80DEC00926A0D /* HyperVNetworkRegs.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = HyperVNetworkRegs.hpp; sourceTree = "<group>"; };
41B41BE326C84A9F00926A0D /* HyperVNetworkPrivate.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = HyperVNetworkPrivate.cpp; sourceTree = "<group>"; };
41B41BE626CDC42D00926A0D /* HyperVNetworkRNDIS.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = HyperVNetworkRNDIS.cpp; sourceTree = "<group>"; };
41BE4104263EDE380018C52B /* MacHyperVSupport.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MacHyperVSupport.kext; sourceTree = BUILT_PRODUCTS_DIR; };
41BE410B263EDE380018C52B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
41BE4113263EDEA10018C52B /* libkmod.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libkmod.a; path = MacKernelSDK/Library/x86_64/libkmod.a; sourceTree = "<group>"; };
Expand Down Expand Up @@ -243,6 +247,8 @@
41B41BDB26C74B4C00926A0D /* HyperVNetwork.cpp */,
41B41BDC26C74B4C00926A0D /* HyperVNetwork.hpp */,
41B41BE126C80DEC00926A0D /* HyperVNetworkRegs.hpp */,
41B41BE626CDC42D00926A0D /* HyperVNetworkRNDIS.cpp */,
41B41BE326C84A9F00926A0D /* HyperVNetworkPrivate.cpp */,
);
path = Network;
sourceTree = "<group>";
Expand Down Expand Up @@ -572,8 +578,10 @@
41F2E44B2666F37B00CE26CE /* HyperVPCIProvider.cpp in Sources */,
418F843D2648BA38003F8520 /* HyperVStorage.cpp in Sources */,
41F2E42D2665B64D00CE26CE /* HyperVPlatformProvider.cpp in Sources */,
41B41BE426C84A9F00926A0D /* HyperVNetworkPrivate.cpp in Sources */,
41225F572644D98500574E86 /* HyperVHeartbeat.cpp in Sources */,
41B41BDD26C74B4C00926A0D /* HyperVNetwork.cpp in Sources */,
41B41BE726CDC42D00926A0D /* HyperVNetworkRNDIS.cpp in Sources */,
41078473264603F1005894D4 /* VMBusChannel.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
4 changes: 3 additions & 1 deletion MacHyperVSupport/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
</dict>
<key>HyperVMouse</key>
<dict>
<key>AbsoluteAxisBoundsRemovalPercentage</key>
<key>AbsoluteAxisBoundsRemovalPercentage</key>
<integer>0</integer>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
Expand Down Expand Up @@ -195,6 +195,8 @@
<string>1.0.0d1</string>
<key>com.apple.iokit.IOHIDFamily</key>
<string>1.1</string>
<key>com.apple.iokit.IONetworkingFamily</key>
<string>1.5.0</string>
<key>com.apple.iokit.IOPCIFamily</key>
<string>1.0.0b1</string>
<key>com.apple.iokit.IOSCSIParallelFamily</key>
Expand Down
43 changes: 21 additions & 22 deletions MacHyperVSupport/IntegrationComponents/HyperVHeartbeat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,54 +21,53 @@ bool HyperVHeartbeat::start(IOService *provider) {
return super::start(provider);
}

void HyperVHeartbeat::processMessage() {
bool HyperVHeartbeat::processMessage() {
VMBusICMessageHeartbeat heartbeatMsg;

HyperVVMBusDeviceRequest request = { 0 };
request.responseData = &heartbeatMsg;
request.responseDataLength = sizeof (heartbeatMsg);


//
// Ignore errors and the acknowledgement interrupt (no data to read).
//
if (hvDevice->doRequest(&request) != kIOReturnSuccess || request.responseDataLength == 0) {
return;
UInt32 pktDataLength;
if (!hvDevice->nextInbandPacketAvailable(&pktDataLength) || pktDataLength > sizeof (heartbeatMsg)) {
return false;
}

//
// Read and parse inbound inband packet.
//
if (hvDevice->readInbandCompletionPacket(&heartbeatMsg, sizeof (heartbeatMsg), NULL) != kIOReturnSuccess) {
return false;
}

switch (heartbeatMsg.header.type) {
case kVMBusICMessageTypeNegotiate:
firstHeartbeatReceived = false;
createNegotiationResponse(&heartbeatMsg.negotiate, 3, 3);
break;

case kVMBusICMessageTypeHeartbeat:
//
// Increment sequence.
// Host will increment this further before sending a message back.
//
//DBGLOG("Got heartbeat, seq = %u", heartbeatMsg.heartbeat.sequence);
heartbeatMsg.heartbeat.sequence++;

if (!firstHeartbeatReceived) {
firstHeartbeatReceived = true;
SYSLOG("Initialized Hyper-V Heartbeat");
}
break;

default:
DBGLOG("Unknown heartbeat message type %u", heartbeatMsg.header.type);
heartbeatMsg.header.status = kHyperVStatusFail;
break;
}


//
// Send response back to Hyper-V. The packet size will always be the same as the original inbound one.
//
heartbeatMsg.header.flags = kVMBusICFlagTransaction | kVMBusICFlagResponse;

UInt32 sendLength = request.responseDataLength;

request = { 0 };
request.sendData = &heartbeatMsg;
request.sendDataLength = sendLength;
request.sendPacketType = kVMBusPacketTypeDataInband;

hvDevice->doRequest(&request);
hvDevice->writeInbandPacket(&heartbeatMsg, pktDataLength, false);
return true;
}
8 changes: 4 additions & 4 deletions MacHyperVSupport/IntegrationComponents/HyperVHeartbeat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@

class HyperVHeartbeat : public HyperVICService {
OSDeclareDefaultStructors(HyperVHeartbeat);

private:
bool firstHeartbeatReceived;

protected:
void processMessage() APPLE_KEXT_OVERRIDE;
bool processMessage() APPLE_KEXT_OVERRIDE;

public:
//
// IOService overrides.
Expand Down
12 changes: 9 additions & 3 deletions MacHyperVSupport/IntegrationComponents/HyperVICService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,17 @@ bool HyperVICService::start(IOService *provider) {
}
hvDevice->retain();

//
// Configure interrupt.
//
interruptSource = IOInterruptEventSource::interruptEventSource(this, OSMemberFunctionCast(IOInterruptEventAction, this, &HyperVICService::handleInterrupt), provider, 0);
getWorkLoop()->addEventSource(interruptSource);
interruptSource->enable();

//
// Configure the channel.
//
if (!hvDevice->openChannel(kHyperVICBufferSize, kHyperVICBufferSize,
this, OSMemberFunctionCast(IOInterruptEventAction, this, &HyperVICService::handleInterrupt))) {
if (!hvDevice->openChannel(kHyperVICBufferSize, kHyperVICBufferSize)) {
super::stop(provider);
return false;
}
Expand Down Expand Up @@ -98,5 +104,5 @@ bool HyperVICService::createNegotiationResponse(VMBusICMessageNegotiate *negMsg,
}

void HyperVICService::handleInterrupt(OSObject *owner, IOInterruptEventSource *sender, int count) {
processMessage();
while (processMessage());
}
3 changes: 2 additions & 1 deletion MacHyperVSupport/IntegrationComponents/HyperVICService.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ class HyperVICService : public IOService {

private:
void handleInterrupt(OSObject *owner, IOInterruptEventSource *sender, int count);
IOInterruptEventSource *interruptSource;

protected:
HyperVVMBusDevice *hvDevice;

virtual void processMessage() = 0;
virtual bool processMessage() = 0;

bool createNegotiationResponse(VMBusICMessageNegotiate *negMsg, UInt32 fwVersion, UInt32 msgVersion);

Expand Down
52 changes: 27 additions & 25 deletions MacHyperVSupport/IntegrationComponents/HyperVShutdown.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,62 +19,64 @@ bool HyperVShutdown::start(IOService *provider) {
if (!super::start(provider)) {
return false;
}

SYSLOG("Initialized Hyper-V Guest Shutdown");
return true;
}

void HyperVShutdown::processMessage() {
bool HyperVShutdown::processMessage() {
VMBusICMessageShutdown shutdownMsg;

HyperVVMBusDeviceRequest request = { 0 };
request.responseData = &shutdownMsg;
request.responseDataLength = sizeof (shutdownMsg);


//
// Ignore errors and the acknowledgement interrupt (no data to read).
//
if (hvDevice->doRequest(&request) != kIOReturnSuccess || request.responseDataLength == 0) {
return;
UInt32 pktDataLength;
if (!hvDevice->nextInbandPacketAvailable(&pktDataLength) || pktDataLength > sizeof (shutdownMsg)) {
return false;
}

//
// Read and parse inbound inband packet.
//
if (hvDevice->readInbandCompletionPacket(&shutdownMsg, sizeof (shutdownMsg), NULL) != kIOReturnSuccess) {
return false;
}

bool doShutdown = false;

switch (shutdownMsg.header.type) {
case kVMBusICMessageTypeNegotiate:
createNegotiationResponse(&shutdownMsg.negotiate, 3, 3);
break;

case kVMBusICMessageTypeShutdown:
doShutdown = handleShutdown(&shutdownMsg.shutdown);
break;

default:
DBGLOG("Unknown shutdown message type %u", shutdownMsg.header.type);
shutdownMsg.header.status = kHyperVStatusFail;
break;
}


//
// Send response back to Hyper-V. The packet size will always be the same as the original inbound one.
//
shutdownMsg.header.flags = kVMBusICFlagTransaction | kVMBusICFlagResponse;

UInt32 sendLength = request.responseDataLength;

request = { 0 };
request.sendData = &shutdownMsg;
request.sendDataLength = sendLength;
request.sendPacketType = kVMBusPacketTypeDataInband;

hvDevice->doRequest(&request);
hvDevice->writeInbandPacket(&shutdownMsg, pktDataLength, false);

//
// Shutdown machine if requested. This should not return.
//
if (doShutdown) {
SYSLOG("Shutting down system");
HyperVPlatformProvider::getInstance()->shutdownSystem();
}
return true;
}

bool HyperVShutdown::handleShutdown(VMBusICMessageShutdownData *shutdownData) {
DBGLOG("Shutdown request received: flags 0x%X, reason 0x%X", shutdownData->flags, shutdownData->reason);

//
// Report back to Hyper-V if we can shutdown system.
//
Expand All @@ -83,7 +85,7 @@ bool HyperVShutdown::handleShutdown(VMBusICMessageShutdownData *shutdownData) {
if (provider != NULL) {
result = provider->canShutdownSystem();
}

shutdownData->header.status = result ? kHyperVStatusSuccess : kHyperVStatusFail;
if (!result) {
SYSLOG("Platform does not support shutdown");
Expand Down
8 changes: 4 additions & 4 deletions MacHyperVSupport/IntegrationComponents/HyperVShutdown.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@

class HyperVShutdown : public HyperVICService {
OSDeclareDefaultStructors(HyperVShutdown);

private:
bool handleShutdown(VMBusICMessageShutdownData *shutdownData);

protected:
void processMessage() APPLE_KEXT_OVERRIDE;
bool processMessage() APPLE_KEXT_OVERRIDE;

public:
//
// IOService overrides.
Expand Down
Loading

0 comments on commit 0fb421b

Please sign in to comment.