NetKVM: Fix possible PF on ParaNdis6_CancelSendNetBufferLists path
NetKVM: Fix possible PF on ParaNdis6_CancelSendNetBufferLists path

Current implementation of CParaNdisTX::BuildCancelList may trigger page fault
and a bugcheck if m_SendQueue is already empty.

Trap:
2: kd> .trap ffffcc81`1b5d2520
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=0000000000000000 rbx=0000000000000000 rcx=00000000000019a4
rdx=00000000000019a5 rsi=0000000000000000 rdi=0000000000000000
rip=fffff80eae479edf rsp=ffffcc811b5d26b0 rbp=ffffa4873a248ee8
 r8=ffffa487392bae80  r9=0000000000000002 r10=ffffa487391f0c30
r11=0000000000000001 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei ng nz na po nc
netkvm!CNBL::MatchCancelID [inlined in
netkvm!CParaNdisTX::BuildCancelList+0x3f]:
fffff80e`ae479edf 488b4320        mov     rax,qword ptr [rbx+20h]
ds:00000000`00000020=????????????????
2: kd> r cr2
Last set context:
cr2=0000000000000020

Callstack:
2: kd> kc
  *** Stack trace for last set context - .thread/.cxr resets it
 # Call Site
00 netkvm!CNBL::MatchCancelID
01 netkvm!CParaNdisTX::BuildCancelList
02 netkvm!CParaNdisTX::CancelNBLs
03 netkvm!ParaNdis6_CancelSendNetBufferLists
04 NDIS!ndisMCancelSendNetBufferListsOnMiniport
05 nt!KeExpandKernelStackAndCalloutInternal
06 NDIS!ndisExpandStack
07 NDIS!ndisFilterCancelSendNetBufferLists
08 klim6
09 NDIS!ndisFInvokePause
0a NDIS!ndisPauseFilterInner
0b NDIS!ndisPauseFilter
0c NDIS!Ndis::BindEngine::Iterate
0d NDIS!Ndis::BindEngine::UpdateBindings
0e NDIS!Ndis::BindEngine::DispatchPendingWork
0f NDIS!Ndis::BindEngine::ApplyBindChanges
10 NDIS!ndisPnPRemoveDevice
11 NDIS!ndisPnPRemoveDeviceEx
12 NDIS!ndisPnPIrpRemoveDevice
13 NDIS!ndisPnPDispatch
14 nt!IopSynchronousCall
15 nt!IopRemoveDevice
16 nt!PnpRemoveLockedDeviceNode
17 nt!PnpDeleteLockedDeviceNode
18 nt!PnpDeleteLockedDeviceNodes
19 nt!PnpProcessQueryRemoveAndEject
1a nt!PnpProcessTargetDeviceEvent
1b nt!PnpDeviceEventWorker
1c nt!ExpWorkerThread
1d nt!PspSystemThreadStartup
1e nt!KiStartSystemThread

Queue state:
2: kd> dt netkvm!CLockFreeDynamicQueue<CNBL> 0xffffa4873a248ee8
   +0x000 m_Queue          : CLockFreeQueue<CNBL>
   +0x030 m_QueueFullList  :
CNdisList<CNBL,CRawAccess,CNonCountingObject>
   +0x048 m_QueueFullListLock : CNdisSpinLock
   +0x058 m_QueueFullListIsEmpty : 0n1
   +0x05c m_ElementCount   : 0n0
   +0x060 m_Size           : 0n8192

The fix is trivial: check if CNBL is empty before trying to access its fields.

Signed-off-by: Sergey Bykov <0dd3142d044dc802a25fdd6721c51e9eb7233049@nutanix.com>

vrozenfe/kvm-guest-drivers-windows,YanVugenfirer/kvm-guest-drivers-windows,vrozenfe/kvm-guest-drivers-windows,virtio-win/kvm-guest-drivers-windows,YanVugenfirer/kvm-guest-drivers-windows,vrozenfe/kvm-guest-drivers-windows,YanVugenfirer/kvm-guest-drivers-windows,daynix/kvm-guest-drivers-windows,virtio-win/kvm-guest-drivers-windows,virtio-win/kvm-guest-drivers-windows,vrozenfe/kvm-guest-drivers-windows,daynix/kvm-guest-drivers-windows,daynix/kvm-guest-drivers-windows,virtio-win/kvm-guest-drivers-windows,YanVugenfirer/kvm-guest-drivers-windows,daynix/kvm-guest-drivers-windows,YanVugenfirer/kvm-guest-drivers-windows,virtio-win/kvm-guest-drivers-windows,vrozenfe/kvm-guest-drivers-windows,daynix/kvm-guest-drivers-windows