Laszlo,

Thanks your suggestion. I will add the code in commit log.

Jeff

-----Original Message-----
From: Laszlo Ersek [mailto:[email protected]] 
Sent: Thursday, October 29, 2015 10:43 PM
To: Fan, Jeff; [email protected]
Cc: Kinney, Michael D
Subject: Re: [edk2] [Patch] UefiCpuPkg/PiSmmCpuDxeSmm: Shouldn't use 
gSmst->CurrentlyExecutingCpu

On 10/29/15 14:17, Fan, Jeff wrote:
> Laszlo,
> 
> SmmCoreEntry() is from the following code, and it is just PiSmmCore's 
> SmmEntryPoint(). 
>   //
>   // Invoke SMM Foundation EntryPoint with the processor information context.
>   //
>   gSmmCpuPrivate->SmmCoreEntry (&gSmmCpuPrivate->SmmCoreEntryContext);
> 
> Yes. gSmst->CurrentlyExecutingCpu is not set in PiSmmCpuDxeSmm driver. It is 
> set in PiSmmCore driver by the following code.
>   //
>   // Update SMST using the context
>   //
>   CopyMem (&gSmmCoreSmst.SmmStartupThisAp, SmmEntryContext, sizeof 
> (EFI_SMM_ENTRY_CONTEXT));

I don't understand how that CopyMem()  call is supposed to set 
gSmst->CurrentlyExecutingCpu.

- gSmst points to an EFI_SMM_SYSTEM_TABLE2 object.
- gSmmCoreSmst is an object of the same type.

In the EFI_SMM_SYSTEM_TABLE2 structure, "SmmStartupThisAp" and 
"CurrentlyExecutingCpu" are *sibling* fields. Neither of both is contained in 
the other.

Therefore I don't understand how the above CopyMem() can set the 
CurrentlyExecutingCpu field.

... OMG... The CopyMem() actually *overflows* the SmmStartupThisAp field. That 
field is only used as a start offset into gSmmCoreSmst. EFI_SMM_ENTRY_CONTEXT 
contains a *subset* of the EFI_SMM_SYSTEM_TABLE2 fields, in the same order, and 
with the same sizes:
- SmmStartupThisAp
- CurrentlyExecutingCpu
- NumberOfCpus
- CpuSaveStateSize
- ...

Which is why the CopyMem() works.

I'm sorry to say, but  I think this is one of the ugliest pieces of code I've 
seen in my life. :(

Anyway, what we have now is the following order:

  BSPHandler()
    gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu = CpuIndex;

    gSmmCpuPrivate->SmmCoreEntry (&gSmmCpuPrivate->SmmCoreEntryContext);

      CopyMem (&gSmmCoreSmst.SmmStartupThisAp, SmmEntryContext, sizeof 
(EFI_SMM_ENTRY_CONTEXT));

    PerformRemainingTasks()      [UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c]
      ConfigSmmCodeAccessCheck()
        ... gSmst->CurrentlyExecutingCpu ...

So, I don't understand how the bug is possible. In the commit message you say, 
"ConfigSmmCodeAccessCheck() maybe invoked before executing SmmCoreEntry()". How?

Ah! Now I understand, there is another ConfigSmmCodeAccessCheck() call in 
BSPHandler(), *before* SmmCoreEntry. It depends on 
"mRestoreSmmConfigurationInS3".

Can you please add the following to the commit message:

-----------
  BSPHandler()
    gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu =
      CpuIndex;

    //
    // when mRestoreSmmConfigurationInS3 is set:
    //
    ConfigSmmCodeAccessCheck()
      //
      // reads gSmst->CurrentlyExecutingCpu to early
      //

    gSmmCpuPrivate->SmmCoreEntry (
      &gSmmCpuPrivate->SmmCoreEntryContext)
      //
      // sets gSmst->CurrentlyExecutingCpu with CopyMem() too late
      //
      CopyMem (&gSmmCoreSmst.SmmStartupThisAp,
        SmmEntryContext, sizeof (EFI_SMM_ENTRY_CONTEXT));
-----------

With that change:

Reviewed-by: Laszlo Ersek <[email protected]>

Thanks
Laszlo


> 
> Thanks!
> Jeff
> -----Original Message-----
> From: Laszlo Ersek [mailto:[email protected]]
> Sent: Thursday, October 29, 2015 8:46 PM
> To: Fan, Jeff; [email protected]
> Cc: Kinney, Michael D
> Subject: Re: [edk2] [Patch] UefiCpuPkg/PiSmmCpuDxeSmm: Shouldn't use 
> gSmst->CurrentlyExecutingCpu
> 
> On 10/29/15 09:11, Jeff Fan wrote:
>> In ConfigSmmCodeAccessCheck(), we used gSmst->CurrentlyExecutingCpu 
>> to get the current SMM BSP. But ConfigSmmCodeAccessCheck() maybe 
>> invoked before executing
>> SmmCoreEntry() and gSmst->CurrentlyExecutingCpu hasn't been updated 
>> to the latest value. Instead, we should use
>> gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu directly.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Jeff Fan <[email protected]>
>> Cc: Michael Kinney <[email protected]>
>> Cc: Laszlo Ersek <[email protected]>
>> ---
>>  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>> b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>> index e210c8d..c351875 100644
>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>> @@ -1386,7 +1386,7 @@ ConfigSmmCodeAccessCheck (
>>    //
>>    // Check to see if the Feature Control MSR is supported on this CPU
>>    //
>> -  Index = gSmst->CurrentlyExecutingCpu;
>> +  Index = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu;
>>    if (!SmmCpuFeaturesIsSmmRegisterSupported (Index, SmmRegFeatureControl)) {
>>      mSmmCodeAccessCheckEnable = FALSE;
>>      return;
>> @@ -1428,7 +1428,7 @@ ConfigSmmCodeAccessCheck (
>>    // Enable SMM Code Access Check feature for the APs.
>>    //
>>    for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
>> -    if (Index != gSmst->CurrentlyExecutingCpu) {
>> +    if (Index !=
>> + gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) {
>>  
>>        //
>>        // Acquire Config SMM Code Access Check spin lock.  The AP 
>> will release the
>>
> 
> I found precisely one location in the entire codebase where 
> "gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu" is set. The call 
> tree is:
> 
> BSPHandler()                   [UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c]
>   // sets field
>   gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu = 
> CpuIndex;
> 
>   PerformRemainingTasks()      [UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c]
>     ConfigSmmCodeAccessCheck()
>       // reads the value here
> 
> From that aspect this patch looks correct.
> 
> However... I have also found that gSmst->CurrentlyExecutingCpu is *never* set.
> 
> Is that a correct observation?
> 
> And if it is, shouldn't we rather (or additionally) fix *that*?
> 
> The commit message references SmmCoreEntry(). That function doesn't seem to 
> exist in edk2.
> 
> A field called "SmmCoreEntry" does exist in SMM_CPU_PRIVATE_DATA, and (IIRC) 
> it does point to SmmEntryPoint() [MdeModulePkg/Core/PiSmmCore/PiSmmCore.c], 
> after registration. But even SmmEntryPoint() does not seem to set 
> gSmst->CurrentlyExecutingCpu.
> 
> Thanks
> Laszlo
> 

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to