I have a driver for Windows VM that allows user space apps to communicate via IOCTL. I need to expose a structure to the host (using virtio) and I have tried using virtqueue_add_buf
after initializing the virt device in the EvtDevicePrepareHardware
using VirtIODeviceInitialize
function. I am getting a fatal error when calling virtqueue_add_buf
.
Below is a snippet of code
int TellHost(WDFOBJECT WdfDevice, VirtioQArg *virtioArg)
{
VIO_SG sg;
PDEVICE_CONTEXT context = GetDeviceContext(WdfDevice);
sg.physAddr = MmGetPhysicalAddress(virtioArg);
sg.length = sizeof(VirtioQCArg);
WdfSpinLockAcquire(context->VirtQueueLock);
error = virtqueue_add_buf(context->VirtQueue, &sg, 1, 0, virtioArg, NULL, 0);
// more code ....
WdfSpinLockRelease(context->VirtQueueLock);
}
The error I get is Fatal System Error: 0x000000d1 (0x0000000000000014,0x0000000000000002,0x0000000000000000,0xFFFFF80109FC0637)
Break instruction exception - code 80000003 (first chance)
and then windbg is unable to load symbols and crashes making my debugging session useless. Any ideas how I can debug this or what I might be missing?
0x000000d1 is DRIVER_IRQL_NOT_LESS_OR_EQUAL which almost always means invalid address is being referenced or addressing paged memory at DPC IRQL or higher.
0x0000000000000000 is a read access to invalid address (0x0000000000000014) from IRQL 2 (DPC).
I had not initialized the queue. Thanks to Vadim RozenFeld from Redhat for pointing out my mistake and his precise explanation.
I checked the balloon virtio driver which uses the following function for initialization of virtio queue.
PVIOQUEUE FindVirtualQueue(VIODEVICE *dev, ULONG index)
{
PVIOQUEUE pq = NULL;
PVOID p;
ULONG size, allocSize;
VirtIODeviceQueryQueueAllocation(dev, index, &size, &allocSize);
if (allocSize)
{
PHYSICAL_ADDRESS HighestAcceptable;
HighestAcceptable.QuadPart = 0xFFFFFFFFFF;
p = MmAllocateContiguousMemory(allocSize, HighestAcceptable);
if (p)
{
pq = VirtIODevicePrepareQueue(dev, index, MmGetPhysicalAddress(p), p, allocSize, p, FALSE);
}
}
return pq;
}
User contributions licensed under CC BY-SA 3.0