hyperv: Add reference counter support
Adds support for the Hyper-V partition reference counter. Change-Id: Ie74b4d3af1b320b7b724776bdb6a22f643873f80 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10500 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Jérôme Duval <[email protected]>
This commit is contained in:
@@ -51,6 +51,7 @@ typedef struct hyperv_device_interface {
|
|||||||
driver_module_info info;
|
driver_module_info info;
|
||||||
|
|
||||||
uint32 (*get_bus_version)(hyperv_device cookie);
|
uint32 (*get_bus_version)(hyperv_device cookie);
|
||||||
|
status_t (*get_reference_counter)(hyperv_device cookie, uint64* _count);
|
||||||
status_t (*open)(hyperv_device cookie, uint32 txLength, uint32 rxLength,
|
status_t (*open)(hyperv_device cookie, uint32 txLength, uint32 rxLength,
|
||||||
hyperv_device_callback callback, void* callbackData);
|
hyperv_device_callback callback, void* callbackData);
|
||||||
void (*close)(hyperv_device cookie);
|
void (*close)(hyperv_device cookie);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ VMBusDevice::VMBusDevice(device_node* node)
|
|||||||
fNode(node),
|
fNode(node),
|
||||||
fStatus(B_NO_INIT),
|
fStatus(B_NO_INIT),
|
||||||
fChannelID(0),
|
fChannelID(0),
|
||||||
|
fReferenceCounterSupported(false),
|
||||||
fDPCHandle(NULL),
|
fDPCHandle(NULL),
|
||||||
fIsOpen(false),
|
fIsOpen(false),
|
||||||
fRingGPADL(0),
|
fRingGPADL(0),
|
||||||
@@ -41,6 +42,9 @@ VMBusDevice::VMBusDevice(device_node* node)
|
|||||||
mutex_init(&fLock, "vmbus device lock");
|
mutex_init(&fLock, "vmbus device lock");
|
||||||
B_INITIALIZE_SPINLOCK(&fTXLock);
|
B_INITIALIZE_SPINLOCK(&fTXLock);
|
||||||
B_INITIALIZE_SPINLOCK(&fRXLock);
|
B_INITIALIZE_SPINLOCK(&fRXLock);
|
||||||
|
|
||||||
|
fReferenceCounterSupported = _IsReferenceCounterSupported();
|
||||||
|
TRACE("Reference counter: %s\n", fReferenceCounterSupported ? "yes" : "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,15 @@ vmbus_device_get_bus_version(hyperv_device cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
vmbus_device_get_reference_counter(hyperv_device cookie, uint64* _count)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
VMBusDevice* device = reinterpret_cast<VMBusDevice*>(cookie);
|
||||||
|
return device->GetReferenceCounter(_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
vmbus_device_open(hyperv_device cookie, uint32 txLength, uint32 rxLength,
|
vmbus_device_open(hyperv_device cookie, uint32 txLength, uint32 rxLength,
|
||||||
hyperv_device_callback callback, void* callbackData)
|
hyperv_device_callback callback, void* callbackData)
|
||||||
@@ -153,6 +162,7 @@ hyperv_device_interface gVMBusDeviceModule = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
vmbus_device_get_bus_version,
|
vmbus_device_get_bus_version,
|
||||||
|
vmbus_device_get_reference_counter,
|
||||||
vmbus_device_open,
|
vmbus_device_open,
|
||||||
vmbus_device_close,
|
vmbus_device_close,
|
||||||
vmbus_device_read_packet,
|
vmbus_device_read_packet,
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ public:
|
|||||||
status_t InitCheck() const { return fStatus; }
|
status_t InitCheck() const { return fStatus; }
|
||||||
|
|
||||||
uint32 GetBusVersion();
|
uint32 GetBusVersion();
|
||||||
|
status_t GetReferenceCounter(uint64* _count);
|
||||||
status_t Open(uint32 txLength, uint32 rxLength,
|
status_t Open(uint32 txLength, uint32 rxLength,
|
||||||
hyperv_device_callback callback, void* callbackData);
|
hyperv_device_callback callback, void* callbackData);
|
||||||
void Close();
|
void Close();
|
||||||
@@ -64,6 +65,7 @@ public:
|
|||||||
status_t FreeGPADL(uint32 gpadl);
|
status_t FreeGPADL(uint32 gpadl);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _IsReferenceCounterSupported();
|
||||||
static void _CallbackHandler(void* arg);
|
static void _CallbackHandler(void* arg);
|
||||||
static void _DPCHandler(void* arg);
|
static void _DPCHandler(void* arg);
|
||||||
|
|
||||||
@@ -78,6 +80,7 @@ private:
|
|||||||
device_node* fNode;
|
device_node* fNode;
|
||||||
status_t fStatus;
|
status_t fStatus;
|
||||||
uint32 fChannelID;
|
uint32 fChannelID;
|
||||||
|
bool fReferenceCounterSupported;
|
||||||
mutex fLock;
|
mutex fLock;
|
||||||
void* fDPCHandle;
|
void* fDPCHandle;
|
||||||
bool fIsOpen;
|
bool fIsOpen;
|
||||||
|
|||||||
@@ -11,4 +11,5 @@ SubDirHdrs $(HAIKU_TOP) src add-ons kernel bus_managers acpi acpica include plat
|
|||||||
|
|
||||||
KernelStaticLibrary hyperv_arch_bus_manager :
|
KernelStaticLibrary hyperv_arch_bus_manager :
|
||||||
VMBus_x86.cpp
|
VMBus_x86.cpp
|
||||||
|
VMBusDevice_x86.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2026 John Davis
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <arch_cpu.h>
|
||||||
|
|
||||||
|
#include "hyperv_cpu.h"
|
||||||
|
#include "VMBusDevicePrivate.h"
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
VMBusDevice::GetReferenceCounter(uint64* _counter)
|
||||||
|
{
|
||||||
|
if (!fReferenceCounterSupported)
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
*_counter = x86_read_msr(IA32_MSR_HV_TIME_REF_COUNT);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
VMBusDevice::_IsReferenceCounterSupported()
|
||||||
|
{
|
||||||
|
cpuid_info cpuInfo;
|
||||||
|
get_cpuid(&cpuInfo, IA32_CPUID_LEAF_HV_FEAT_ID, 0);
|
||||||
|
return (cpuInfo.regs.eax & HV_CPUID_FEATURE_TIME_REF_COUNTER) != 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user