Exemplo n.º 1
0
static VOID
V4vVirqNotifyDpc(KDPC *dpc, VOID *dctx, PVOID sarg1, PVOID sarg2)
{
    XENV4V_EXTENSION  *pde = V4vGetDeviceExtension((DEVICE_OBJECT*)dctx);
    XENV4V_CONTEXT   **ctxList;
    ULONG              count = 0, i;
    KLOCK_QUEUE_HANDLE lqh;

    UNREFERENCED_PARAMETER(dpc);
    UNREFERENCED_PARAMETER(sarg1);
    UNREFERENCED_PARAMETER(sarg2);

    // In MP guests when not using VIRQs, have to lock the DPC processing
    KeAcquireInStackQueuedSpinLockAtDpcLevel(&pde->dpcLock, &lqh);

    // Get a list of active contexts and their rings
    ctxList = V4vGetAllContexts(pde, &count);

    // Loop over the contexts and process read IO for each.
    for (i = 0; ((ctxList != NULL)&&(i < count)); i++) {
        V4vProcessContextReads(pde, ctxList[i]);        
    }

    // Return the context list and drop the ref count
    V4vPutAllContexts(pde, ctxList, count);

    // Now process the notify and satisfy writes that are queued
    V4vProcessNotify(pde);

    KeReleaseInStackQueuedSpinLockFromDpcLevel(&lqh);
}
Exemplo n.º 2
0
// Buffer the log entry to the log buffer.
_Use_decl_annotations_ static NTSTATUS LogpBufferMessage(const char *message,
                                                         LogBufferInfo *info) {
  NT_ASSERT(info);

  // Acquire a spin lock to add the log safely.
  KLOCK_QUEUE_HANDLE lock_handle = {};
  const auto old_irql = KeGetCurrentIrql();
  if (old_irql < DISPATCH_LEVEL) {
    KeAcquireInStackQueuedSpinLock(&info->spin_lock, &lock_handle);
  } else {
    KeAcquireInStackQueuedSpinLockAtDpcLevel(&info->spin_lock, &lock_handle);
  }
  NT_ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);

  // Copy the current log to the buffer.
  SIZE_T used_buffer_size = info->log_buffer_tail - info->log_buffer_head;
  auto status =
      RtlStringCchCopyA(const_cast<char *>(info->log_buffer_tail),
                        kLogpBufferUsableSize - used_buffer_size, message);

  // Update info.log_max_usage if necessary.
  if (NT_SUCCESS(status)) {
    const auto message_length = strlen(message) + 1;
    info->log_buffer_tail += message_length;
    used_buffer_size += message_length;
    if (used_buffer_size > info->log_max_usage) {
      info->log_max_usage = used_buffer_size;  // Update
    }
  } else {
    info->log_max_usage = kLogpBufferSize;  // Indicates overflow
  }
  *info->log_buffer_tail = '\0';

  if (old_irql < DISPATCH_LEVEL) {
    KeReleaseInStackQueuedSpinLock(&lock_handle);
  } else {
    KeReleaseInStackQueuedSpinLockFromDpcLevel(&lock_handle);
  }
  return status;
}
Exemplo n.º 3
0
// Acquires a spin lock
ScopedSpinLockAtDpc::ScopedSpinLockAtDpc(_In_ PKSPIN_LOCK spin_lock) {
  KeAcquireInStackQueuedSpinLockAtDpcLevel(spin_lock, &lock_handle_);
}
Exemplo n.º 4
0
NTSTATUS
InsertNBs(
	_Inout_ KKDRV_QUEUE_DATA *queueData,
	_In_ NET_BUFFER_LIST *head
	)
{
	NTSTATUS status = STATUS_SUCCESS;
	KLOCK_QUEUE_HANDLE lockHandle;

	NET_BUFFER_LIST *nbl = head;
	NET_BUFFER *nb;

	while (nbl)
	{
		nb = NET_BUFFER_LIST_FIRST_NB(nbl);

		while (nb)
		{
			PVOID data;
			ULONG dataLength = NET_BUFFER_DATA_LENGTH(nb);
			PKKDRV_PACKET packet = (PKKDRV_PACKET)ExAllocatePoolWithTag(
				NonPagedPool,
				KKDRV_PACKET_SIZE + dataLength,
				KKDRV_TAG
				);
			if (packet == NULL)
			{
				return STATUS_INSUFFICIENT_RESOURCES;
			};

			packet->dataLength = dataLength;
			data = NdisGetDataBuffer(nb, dataLength, NULL, 1, 0);
			if (data == NULL)
			{
				NdisGetDataBuffer(nb, dataLength, &packet->data, 1, 0);
			}
			else
			{
				RtlCopyMemory(&(packet->data), data, dataLength);
			}

			KeAcquireInStackQueuedSpinLockAtDpcLevel(
				&queueData->queueLock,
				&lockHandle
				);

			InsertTailList(&queueData->queue, &packet->entry);
			queueData->queueLength++;

			if (queueData->queueLength > queueData->queueLengthMax)
			{
				PLIST_ENTRY entry = RemoveHeadList(&queueData->queue);
				ExFreePoolWithTag(entry, KKDRV_TAG);
				queueData->queueLength--;
			}

			KeReleaseInStackQueuedSpinLockFromDpcLevel(
				&lockHandle
				);

			nb = nb->Next;
		}

		nbl = nbl->Next;
	}

	return status;
}