From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 90FD7AC09D9 for ; Mon, 18 Mar 2024 02:20:29 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=4ru5yG0KCLBqN4s84X4i18ahtkTrddH05O9bYq1/3Sk=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20240206; t=1710728428; v=1; b=dH40C4zzrsuhp/WDxNUAu+MG3hZnthzGPZrTBQeziaAE37ja3E8ZURNF1/0Igt+rvVVND6aP vJhcCizarlvPZYqhPy0psVWpqbeDvt8/4sACDqwht/ptXo9lENi8wavXVsD3NUWA4NcRyfUtKDS 2HnZIng0myz1oBSkUjCmatkcWLKCQpeep4t7txf3hgOlol+rIQNEtwNHq+5U21PhksEViI5E6kp UFk1Mu/PraGj021a4QYYcgbKyZQiF0J9cO6ocrWWgpILhvyH4pi6A49Q+SHVVjWvq6mDZ15DjCN EO8KxJ1Dc23vyvTNVkOnZVKp/GHb9QXEvHXDpEF+QWBpw== X-Received: by 127.0.0.2 with SMTP id 9evmYY7687511x0D37068cEX; Sun, 17 Mar 2024 19:20:28 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.18]) by mx.groups.io with SMTP id smtpd.web11.34038.1710728416304381805 for ; Sun, 17 Mar 2024 19:20:27 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,11016"; a="5363131" X-IronPort-AV: E=Sophos;i="6.07,133,1708416000"; d="scan'208";a="5363131" X-Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa112.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2024 19:20:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,133,1708416000"; d="scan'208";a="13356227" X-Received: from shwdesfp01.ccr.corp.intel.com ([10.239.158.151]) by orviesa009-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2024 19:20:25 -0700 From: "Zhiguang Liu" To: devel@edk2.groups.io Cc: Zhiguang Liu , Liming Gao , Jiaxin Wu , Ray Ni , Laszlo Ersek Subject: [edk2-devel] [PATCH 5/6] MdeModulePkg/SMM: Support to unregister SMI handler in SMI handlers Date: Mon, 18 Mar 2024 10:19:55 +0800 Message-Id: <20240318021956.2787-6-zhiguang.liu@intel.com> In-Reply-To: <20240318021956.2787-1-zhiguang.liu@intel.com> References: <20240318021956.2787-1-zhiguang.liu@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Sun, 17 Mar 2024 19:20:27 -0700 Reply-To: devel@edk2.groups.io,zhiguang.liu@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: hUGRT3gVA04cue9ZNTX4CxtUx7686176AA= Content-Transfer-Encoding: 8bit X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=dH40C4zz; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io Unregistering SMI handler will free the SMI_HANDLER. However, the SmiManage() may be using the link node from SMI_HANDLER for loop if the unregistering happens in SMI handlers. To avoid that, the idea is to inform SmiHandlerUnRegister() whether it's running or not running on the stack of SmiManage(), and to postpone SMI_HANDLER deletion before SmiManage() returns. Noted SmiManage() may be called recursively, the SmiHandlerUnRegister() won't take effect until the root SmiManage() returns. Cc: Liming Gao Cc: Jiaxin Wu Cc: Ray Ni Cc: Laszlo Ersek Cc: Ray Ni Cc: Laszlo Ersek Signed-off-by: Zhiguang Liu --- MdeModulePkg/Core/PiSmmCore/PiSmmCore.h | 1 + MdeModulePkg/Core/PiSmmCore/Smi.c | 105 ++++++++++++++++++++++-- 2 files changed, 100 insertions(+), 6 deletions(-) diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h index b8a490a8c3..6cc32e94d8 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h @@ -93,6 +93,7 @@ typedef struct { SMI_ENTRY *SmiEntry; VOID *Context; // for profile UINTN ContextSize; // for profile + BOOLEAN NeedDeleted; // To delete this SMI_HANDLER later } SMI_HANDLER; // diff --git a/MdeModulePkg/Core/PiSmmCore/Smi.c b/MdeModulePkg/Core/PiSmmCore/Smi.c index 2985f989c3..b76aaf67e4 100644 --- a/MdeModulePkg/Core/PiSmmCore/Smi.c +++ b/MdeModulePkg/Core/PiSmmCore/Smi.c @@ -8,6 +8,11 @@ #include "PiSmmCore.h" +// +// mSmiManageCallingDepth is used to track the depth of recursive calls of SmiManage. +// +UINTN mSmiManageCallingDepth = 0; + LIST_ENTRY mSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mSmiEntryList); SMI_ENTRY mRootSmiEntry = { @@ -104,13 +109,15 @@ SmiManage ( { LIST_ENTRY *Link; LIST_ENTRY *Head; + LIST_ENTRY *EntryLink; SMI_ENTRY *SmiEntry; SMI_HANDLER *SmiHandler; BOOLEAN SuccessReturn; + BOOLEAN CanReturn; EFI_STATUS Status; PERF_FUNCTION_BEGIN (); - + mSmiManageCallingDepth++; Status = EFI_NOT_FOUND; SuccessReturn = FALSE; if (HandlerType == NULL) { @@ -152,7 +159,12 @@ SmiManage ( // if (HandlerType != NULL) { PERF_FUNCTION_END (); - return EFI_INTERRUPT_PENDING; + // + // Won't go to next Handler, and will return with EFI_INTERRUPT_PENDING later + // + SuccessReturn = FALSE; + Status = EFI_INTERRUPT_PENDING; + CanReturn = TRUE; } break; @@ -165,7 +177,10 @@ SmiManage ( // if (HandlerType != NULL) { PERF_FUNCTION_END (); - return EFI_SUCCESS; + // + // Won't go to next Handler, and return with EFI_SUCCESS + // + CanReturn = TRUE; } SuccessReturn = TRUE; @@ -193,12 +208,79 @@ SmiManage ( ASSERT (FALSE); break; } + + if (CanReturn) { + break; + } } if (SuccessReturn) { Status = EFI_SUCCESS; } + ASSERT (mSmiManageCallingDepth > 0); + mSmiManageCallingDepth--; + + // + // The SmiHandlerUnRegister won't take effect inside SmiManage. + // Before returned from SmiManage, delete the SmiHandler which is + // marked as NeedDeleted. + // Note that SmiManage can be called recursively. + // + if (mSmiManageCallingDepth == 0) { + // + // Go through all SmiHandler in root SMI handlers + // + SmiHandler = NULL; + for ( Link = GetFirstNode (&mRootSmiEntry.SmiHandlers) + ; !IsNull (&mRootSmiEntry.SmiHandlers, Link); + ) + { + SmiHandler = CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE); + Link = GetNextNode (&mRootSmiEntry.SmiHandlers, Link); + if (SmiHandler->NeedDeleted) { + // + // Remove SmiHandler if the NeedDeleted is set. + // + RemoveEntryList (&SmiHandler->Link); + FreePool (SmiHandler); + } + } + + // + // Go through all SmiHandler in non-root SMI handlers + // + for ( EntryLink = GetFirstNode (&mSmiEntryList) + ; !IsNull (&mSmiEntryList, EntryLink); + ) + { + SmiEntry = CR (EntryLink, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE); + EntryLink = GetNextNode (&mSmiEntryList, EntryLink); + for ( Link = GetFirstNode (&SmiEntry->SmiHandlers) + ; !IsNull (&SmiEntry->SmiHandlers, Link); + ) + { + SmiHandler = CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE); + Link = GetNextNode (&SmiEntry->SmiHandlers, Link); + if (SmiHandler->NeedDeleted) { + // + // Remove SmiHandler if the NeedDeleted is set. + // + RemoveEntryList (&SmiHandler->Link); + FreePool (SmiHandler); + } + } + + if (IsListEmpty (&SmiEntry->SmiHandlers)) { + // + // No handler registered for this SmiEntry now, remove the SMI_ENTRY + // + RemoveEntryList (&SmiEntry->AllEntries); + FreePool (SmiEntry); + } + } + } + PERF_FUNCTION_END (); return Status; } @@ -235,9 +317,10 @@ SmiHandlerRegister ( return EFI_OUT_OF_RESOURCES; } - SmiHandler->Signature = SMI_HANDLER_SIGNATURE; - SmiHandler->Handler = Handler; - SmiHandler->CallerAddr = (UINTN)RETURN_ADDRESS (0); + SmiHandler->Signature = SMI_HANDLER_SIGNATURE; + SmiHandler->Handler = Handler; + SmiHandler->CallerAddr = (UINTN)RETURN_ADDRESS (0); + SmiHandler->NeedDeleted = FALSE; if (HandlerType == NULL) { // @@ -324,6 +407,16 @@ SmiHandlerUnRegister ( SmiEntry = SmiHandler->SmiEntry; + if (mSmiManageCallingDepth > 0) { + // + // This function is called from SmiManage() + // Do not delete or remove SmiHandler or SmiEntry now. + // Set the NeedDeleted field in SmiHandler so that SmiManage will delete it later + // + SmiHandler->NeedDeleted = TRUE; + return EFI_SUCCESS; + } + RemoveEntryList (&SmiHandler->Link); FreePool (SmiHandler); -- 2.31.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116831): https://edk2.groups.io/g/devel/message/116831 Mute This Topic: https://groups.io/mt/104996185/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-