2016-04-25 42 views
1

我有一个Windows VM的驱动程序,允许用户空间应用程序通过IOCTL进行通信。我需要将结构展示给主机(使用virtio),并且在使用VirtIODeviceInitialize函数初始化EvtDevicePrepareHardware中的virt设备后,我尝试使用virtqueue_add_buf。拨打virtqueue_add_buf时出现致命错误。windows kdmf驱动程序virtio调用virtqueue_add_buf导致系统致命错误

下面的代码

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); 
} 

片断我得到的错误是致命系统错误:0X000000D1(0x0000000000000014,0x0000000000000002,0x0000000000000000,0xFFFFF80109FC0637)

中断指令例外 - 代码80000003(第一次机会)

然后windbg无法加载符号和崩溃使我的调试会话无用。任何想法如何我可以调试这个或我可能会失踪?

+1

windbg版本10.0.10586.567,windows 8.1 x64 – Luis

回答

1

0x000000d1是DRIVER_IRQL_NOT_LESS_OR_EQUAL,它几乎总是意味着正在引用无效地址或在DPC IRQL或更高地址处寻址分页内存。

0x0000000000000000是对来自IRQL 2(DPC)的无效地址(0x0000000000000014)的读访问。

我还没有初始化队列。感谢Redhat的Vadim RozenFeld指出我的错误和他的确切解释。

我检查了virtio驱动程序,它使用以下函数来初始化virtio队列。

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; 
} 
相关问题