From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: eric.dong@intel.com) Received: from mga06.intel.com (mga06.intel.com []) by groups.io with SMTP; Thu, 08 Aug 2019 23:12:31 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Aug 2019 23:12:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,364,1559545200"; d="scan'208";a="326540080" Received: from ydong10-win10.ccr.corp.intel.com ([10.239.158.133]) by orsmga004.jf.intel.com with ESMTP; 08 Aug 2019 23:12:30 -0700 From: "Dong, Eric" To: devel@edk2.groups.io Cc: Ray Ni , Laszlo Ersek Subject: [Patch 3/4] UefiCpuPkg/PiSmmCpuDxeSmm: Supports detect before set new value logic. Date: Fri, 9 Aug 2019 14:11:58 +0800 Message-Id: <20190809061159.40248-4-eric.dong@intel.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20190809061159.40248-1-eric.dong@intel.com> References: <20190809061159.40248-1-eric.dong@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2040 Supports new logic which detect current value before set new value. Only set new value when current value not same as new value. Signed-off-by: Eric Dong Cc: Ray Ni Cc: Laszlo Ersek --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 135 ++++++++++++++++++++---------- 1 file changed, 92 insertions(+), 43 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index d8c6b19ead..957f2896eb 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -159,6 +159,58 @@ S3WaitForSemaphore ( ) != Value); } +/** + Read / write CR value. + + @param[in] CrIndex The CR index which need to read/write. + @param[in] Read Read or write. TRUE is read. + @param[in,out] CrValue CR value. + + @retval EFI_SUCCESS means read/write success, else return EFI_UNSUPPORTED. +**/ +UINTN +ReadWriteCr ( + IN UINT32 CrIndex, + IN BOOLEAN Read, + IN OUT UINTN *CrValue + ) +{ + switch (CrIndex) { + case 0: + if (Read) { + *CrValue = AsmReadCr0 (); + } else { + AsmWriteCr0 (*CrValue); + } + break; + case 2: + if (Read) { + *CrValue = AsmReadCr2 (); + } else { + AsmWriteCr2 (*CrValue); + } + break; + case 3: + if (Read) { + *CrValue = AsmReadCr3 (); + } else { + AsmWriteCr3 (*CrValue); + } + break; + case 4: + if (Read) { + *CrValue = AsmReadCr4 (); + } else { + AsmWriteCr4 (*CrValue); + } + break; + default: + return EFI_UNSUPPORTED;; + } + + return EFI_SUCCESS; +} + /** Initialize the CPU registers from a register table. @@ -188,6 +240,8 @@ ProgramProcessorRegister ( UINTN ProcessorIndex; UINTN ValidThreadCount; UINT32 *ValidCoreCountPerPackage; + EFI_STATUS Status; + UINT64 CurrentValue; // // Traverse Register Table of this logical processor @@ -206,55 +260,50 @@ ProgramProcessorRegister ( // The specified register is Control Register // case ControlRegister: - switch (RegisterTableEntry->Index) { - case 0: - Value = AsmReadCr0 (); - Value = (UINTN) BitFieldWrite64 ( - Value, - RegisterTableEntry->ValidBitStart, - RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, - (UINTN) RegisterTableEntry->Value - ); - AsmWriteCr0 (Value); - break; - case 2: - Value = AsmReadCr2 (); - Value = (UINTN) BitFieldWrite64 ( - Value, - RegisterTableEntry->ValidBitStart, - RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, - (UINTN) RegisterTableEntry->Value - ); - AsmWriteCr2 (Value); - break; - case 3: - Value = AsmReadCr3 (); - Value = (UINTN) BitFieldWrite64 ( - Value, - RegisterTableEntry->ValidBitStart, - RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, - (UINTN) RegisterTableEntry->Value - ); - AsmWriteCr3 (Value); - break; - case 4: - Value = AsmReadCr4 (); - Value = (UINTN) BitFieldWrite64 ( - Value, - RegisterTableEntry->ValidBitStart, - RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, - (UINTN) RegisterTableEntry->Value - ); - AsmWriteCr4 (Value); - break; - default: - break; + Status = ReadWriteCr(RegisterTableEntry->Index, TRUE, &Value); + if (EFI_ERROR (Status)) { + return; + } + if (RegisterTableEntry->DetectIt) { + CurrentValue = BitFieldRead64( + Value, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1 + ); + if (CurrentValue == RegisterTableEntry->Value) { + return; + } } + Value = (UINTN) BitFieldWrite64 ( + Value, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, + RegisterTableEntry->Value + ); + ReadWriteCr (RegisterTableEntry->Index, FALSE, &Value); break; // // The specified register is Model Specific Register // case Msr: + if (RegisterTableEntry->DetectIt) { + Value = (UINTN)AsmReadMsr64 (RegisterTableEntry->Index); + if (RegisterTableEntry->ValidBitLength >= 64) { + if (Value == RegisterTableEntry->Value) { + return; + } + } else { + CurrentValue = BitFieldRead64( + Value, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1 + ); + if (CurrentValue == RegisterTableEntry->Value) { + return; + } + } + } + // // If this function is called to restore register setting after INIT signal, // there is no need to restore MSRs in register table. -- 2.21.0.windows.1