2016-04-25 10 views
1

Ich habe einen Treiber für Windows VM, die Benutzer Space-Apps über IOCTL kommunizieren können. Ich muss eine Struktur dem Wirt aussetzen (mit virtio) und ich habe versucht, virtqueue_add_buf nach der Initialisierung der Virt Gerät in der EvtDevicePrepareHardware mit VirtIODeviceInitialize Funktion. Beim Aufruf von virtqueue_add_buf wird ein schwerwiegender Fehler angezeigt.Windows kdmf Treiber Virtio aufrufen virtuqueue_add_buf verursacht System fataler Fehler

Unten finden Sie ein Code-Snippet

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

Der Fehler ich Fatal System Error bekommen ist: 0x000000d1 (0x0000000000000014,0x0000000000000002,0x0000000000000000,0xFFFFF80109FC0637)

Pause Anweisung Ausnahme - Code 80000003 (erste Chance)

und dann windbg ist nicht in der Lage Symbole und Abstürze zu laden, macht meine Debugging-Sitzung nutzlos. Irgendwelche Ideen, wie ich das debuggen kann oder was ich vielleicht vermisse?

+1

windbg Version 10.0.10586.567, Windows 8.1 x64 – Luis

Antwort

1

0x000000d1 ist DRIVER_IRQL_NOT_LESS_OR_EQUAL, was fast immer bedeutet, dass eine ungültige Adresse referenziert wird oder ausgelagerter Speicher bei DPC IRQL oder höher adressiert wird.

0x0000000000000000 ist ein Lesezugriff auf ungültige Adresse (0x0000000000000014) von IRQL 2 (DPC).

Ich hatte die Warteschlange nicht initialisiert. Danke an Vadim RozenFeld von Redhat für den Hinweis auf meinen Fehler und seine genaue Erklärung.

Ich überprüfte den Ballonvirtio-Treiber, der die folgende Funktion für die Initialisierung der Virtio-Warteschlange verwendet.

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