From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1 with cipher CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 099BA1A1DFF for ; Wed, 26 Oct 2016 15:31:23 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP; 26 Oct 2016 15:31:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,551,1473145200"; d="scan'208";a="1059689967" Received: from mdkinney-mobl.amr.corp.intel.com ([10.232.96.18]) by fmsmga001.fm.intel.com with ESMTP; 26 Oct 2016 15:31:23 -0700 From: Michael Kinney To: edk2-devel@lists.01.org Cc: Ruiyu Ni Date: Wed, 26 Oct 2016 15:31:21 -0700 Message-Id: <1477521081-14264-1-git-send-email-michael.d.kinney@intel.com> X-Mailer: git-send-email 2.6.3.windows.1 Subject: [Patch] PcAtChipsetPkg/HpetTimerDxe: Fix race condition in SetTimerPeriod() X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Oct 2016 22:31:24 -0000 https://bugzilla.tianocore.org/show_bug.cgi?id=182 The function TimerDriverSetTimerPeriod() disables the HPET timer while the HPET timer HW is reprogrammed with a new timer period. However, the MMIO write to disable the HPET timer HW can be delayed and an HPET timer interrupt may be processed in the middle of reprogramming the HPET timer HW and this may produced unexpected results. The fix is to raise TPL to TPL_HIGH_LEVEL in TimerDriverSetTimerPeriod() during the time the HPET timer HW is reprogrammed. This guarantees that no timer interrupts are processed during reprogramming. The TimerDriverGenerateSoftInterrupt() function in this same driver also raises TPL to TPL_HIGH_LEVEL, so this fix matches the logic that is already used in another function for the same reason. Cc: Ruiyu Ni Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney --- PcAtChipsetPkg/HpetTimerDxe/HpetTimer.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/PcAtChipsetPkg/HpetTimerDxe/HpetTimer.c b/PcAtChipsetPkg/HpetTimerDxe/HpetTimer.c index 0ed8743..c62c3a9 100644 --- a/PcAtChipsetPkg/HpetTimerDxe/HpetTimer.c +++ b/PcAtChipsetPkg/HpetTimerDxe/HpetTimer.c @@ -492,11 +492,17 @@ TimerDriverSetTimerPeriod ( IN UINT64 TimerPeriod ) { + EFI_TPL Tpl; UINT64 MainCounter; UINT64 Delta; UINT64 CurrentComparator; HPET_TIMER_MSI_ROUTE_REGISTER HpetTimerMsiRoute; - + + // + // Disable interrupts + // + Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); + // // Disable HPET timer when adjusting the timer period // @@ -616,7 +622,12 @@ TimerDriverSetTimerPeriod ( // is disabled. // HpetEnable (TRUE); - + + // + // Restore interrupts + // + gBS->RestoreTPL (Tpl); + return EFI_SUCCESS; } -- 2.6.3.windows.1