From 1001e6089fecaa1b13c4d91a162d956742c4134e Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Wed, 27 Feb 2019 15:02:38 +0100 Subject: [PATCH] [HDAUDBUS] Wait until the correct number of responses was received. CORE-15465 We previously only gave the device a hard-coded amount of time to respond, which could lead to interpreting the contents of uninitialized memory as a response. This would lead to an unreasonably large number of audio function groups being detected. A KSEMAPHORE mirrors what Haiku uses here, though it may not be the optimal synchronization primitive for this case under Windows. --- drivers/wdm/audio/hdaudbus/fdo.cpp | 16 +++++++++++----- drivers/wdm/audio/hdaudbus/hdaudbus.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/wdm/audio/hdaudbus/fdo.cpp b/drivers/wdm/audio/hdaudbus/fdo.cpp index a6d2ca8f114..8a08371fd2c 100644 --- a/drivers/wdm/audio/hdaudbus/fdo.cpp +++ b/drivers/wdm/audio/hdaudbus/fdo.cpp @@ -129,6 +129,7 @@ HDA_DpcForIsr( /* store response */ Codec->Responses[Codec->ResponseCount] = Response; Codec->ResponseCount++; + KeReleaseSemaphore(&Codec->ResponseSemaphore, IO_NO_INCREMENT, 1, FALSE); } } @@ -167,17 +168,21 @@ HDA_SendVerbs( DeviceExtension->CorbBase[WritePosition] = Verbs[Sent++]; DeviceExtension->CorbWritePos = WritePosition; - - // FIXME HACK - // do proper synchronization - WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_WRITE_POS), DeviceExtension->CorbWritePos); - KeStallExecutionProcessor(30); Queued++; } WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_WRITE_POS), DeviceExtension->CorbWritePos); } + while (Queued--) + { + KeWaitForSingleObject(&Codec->ResponseSemaphore, + Executive, + KernelMode, + FALSE, + NULL); + } + if (Responses != NULL) { memcpy(Responses, Codec->Responses, Codec->ResponseCount * sizeof(ULONG)); } @@ -207,6 +212,7 @@ HDA_InitCodec( /* init codec */ Entry->Addr = codecAddress; + KeInitializeSemaphore(&Entry->ResponseSemaphore, 0, MAX_CODEC_RESPONSES); /* get device extension */ DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; diff --git a/drivers/wdm/audio/hdaudbus/hdaudbus.h b/drivers/wdm/audio/hdaudbus/hdaudbus.h index 6bdbc542f44..3a957c15062 100644 --- a/drivers/wdm/audio/hdaudbus/hdaudbus.h +++ b/drivers/wdm/audio/hdaudbus/hdaudbus.h @@ -53,6 +53,7 @@ typedef struct ULONG Responses[MAX_CODEC_RESPONSES]; ULONG ResponseCount; + KSEMAPHORE ResponseSemaphore; PHDA_CODEC_AUDIO_GROUP AudioGroups[HDA_MAX_AUDIO_GROUPS]; ULONG AudioGroupCount;