Hi Laszlo, Have sent out the formal patch for review.
Thanks, Star [EOM] > -----Original Message----- > From: Zeng, Star > Sent: Friday, August 7, 2015 9:36 AM > To: Zeng, Star; Laszlo Ersek; Paolo Bonzini > Cc: Justen, Jordan L; edk2-de...@ml01.01.org; Andrew Fish; Yao, Jiewen; > Chen Fan; Fan, Jeff > Subject: RE: [edk2] [PATCH] MdeModulePkg DxeIpl: Add stack NX support > > > -----Original Message----- > > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of > > Zeng, Star > > Sent: Friday, August 7, 2015 9:28 AM > > To: Laszlo Ersek; Paolo Bonzini > > Cc: Justen, Jordan L; edk2-de...@ml01.01.org; Andrew Fish; Yao, > > Jiewen; Chen Fan; Fan, Jeff > > Subject: Re: [edk2] [PATCH] MdeModulePkg DxeIpl: Add stack NX support > > > > > -----Original Message----- > > > From: Laszlo Ersek [mailto:ler...@redhat.com] > > > Sent: Thursday, August 6, 2015 9:43 PM > > > To: Zeng, Star; Paolo Bonzini > > > Cc: Andrew Fish; Justen, Jordan L; edk2-de...@ml01.01.org; Yao, > > > Jiewen; Chen Fan; Fan, Jeff > > > Subject: Re: [edk2] [PATCH] MdeModulePkg DxeIpl: Add stack NX > > > support > > > > > > Hi Star, > > > > > > On 08/06/15 11:44, Zeng, Star wrote: > > > > Hi Laszlo, > > > > > > > > Could you help take a try with the attached patch on your VM > > > > before I send > > > it for formal review? > > > > > > I got your patch via your first (public) message as well -- not the > > > one reflected by the list software, but on the direct route. So, I > > > can test it and even comment on it a little bit below (in > > > Thunderbird plaintext attachments are displayed inline, and if you > > > select the full contents of the "body" window before hitting Reply > > > All, then the entire selection will be quoted, including the inline > > > displayed text > > attachments). > > > > > > ** So, test results: > > > > > > - With X64 DXE, your patch solves the issue for me. > > > > > > - With Ia32 DXE, your patch also soves the issue. > > > > > > - With this patch applied, if I use Ia32 DXE *plus* my SMM series, then: > > > > > > - Using TCG in QEMU (= software emulation), the patch solves the > > > issue. > > > > > > - Using KVM with QEMU (= hardware virtualization), I continue seeing > > > reboots, but they hit in a different place. Somewhere inside or > > > after the SMBASE relocation. I believe this is a KVM bug. I will > > > send a separate email about this. > > > > > > ** Comments on the patch: > > > > > > > CpuDxe.diff > > > > > > > > > > > > 9238355e710a898a148efa072c67693fac631e42 > > > > UefiCpuPkg/CpuDxe/ApStartup.c | 140 > > > > +++++++++++++++++++++++++++++++++++++++++- > > > > 1 file changed, 138 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/UefiCpuPkg/CpuDxe/ApStartup.c > > > > b/UefiCpuPkg/CpuDxe/ApStartup.c index 7613b47..59cf8e6 100644 > > > > --- a/UefiCpuPkg/CpuDxe/ApStartup.c > > > > +++ b/UefiCpuPkg/CpuDxe/ApStartup.c > > > > @@ -19,6 +19,47 @@ > > > > #pragma pack(1) > > > > > > > > typedef struct { > > > > + UINT8 MoveIa32EferMsrToEcx[5]; > > > > + UINT8 ReadIa32EferMsr[2]; > > > > + UINT8 SetExecuteDisableBitEnableBit[4]; > > > > + UINT8 WriteIa32EferMsr[2]; > > > > + > > > > +#if defined (MDE_CPU_IA32) > > > > + UINT8 MovEaxCr3; > > > > + UINT32 Cr3Value; > > > > + UINT8 MovCr3Eax[3]; > > > > + > > > > + UINT8 MoveCr4ToEax[3]; > > > > + UINT8 SetCr4Bit5[4]; > > > > + UINT8 MoveEaxToCr4[3]; > > > > + > > > > + UINT8 MoveCr0ToEax[3]; > > > > + UINT8 SetCr0PagingBit[4]; > > > > + UINT8 MoveEaxToCr0[3]; > > > > +#endif > > > > +} ENABLE_EXECUTE_DISABLE_CODE; > > > > + > > > > +ENABLE_EXECUTE_DISABLE_CODE > > mEnableExecuteDisbleCodeTemplate > > > = { > > > > > > (1) This should be STATIC. (Although, I realize mStartupCodeTemplate > > > is not STATIC either, so feel free to ignore this.) > > > > > > > + { 0xB9, 0x80, 0x00, 0x00, 0xC0 }, // mov ecx, 0xc0000080 > > > > + { 0x0F, 0x32 }, // rdmsr > > > > + { 0x0F, 0xBA, 0xE8, 0x0B }, // bts eax, 11 > > > > + { 0x0F, 0x30 }, // wrmsr > > > > + > > > > +#if defined (MDE_CPU_IA32) > > > > + 0xB8, 0x00000000, // mov eax, cr3 value > > > > + { 0x0F, 0x22, 0xd8 }, // mov cr3, eax > > > > + > > > > + { 0x0F, 0x20, 0xE0 }, // mov eax, cr4 > > > > + { 0x0F, 0xBA, 0xE8, 0x05 }, // bts eax, 5 > > > > + { 0x0F, 0x22, 0xE0 }, // mov cr4, eax > > > > + > > > > + { 0x0F, 0x20, 0xC0 }, // mov eax, cr0 > > > > + { 0x0F, 0xBA, 0xE8, 0x1F }, // bts eax, 31 > > > > + { 0x0F, 0x22, 0xC0 }, // mov cr0, eax > > > > +#endif > > > > +}; > > > > + > > > > +typedef struct { > > > > UINT8 JmpToCli[2]; > > > > > > > > UINT16 GdtLimit; > > > > @@ -56,6 +97,12 @@ typedef struct { > > > > // > > > > // Transition to X64 > > > > // > > > > + > > > > + // > > > > + // Code placeholder to enable Execute Disable Bit // > > > > + ENABLE_EXECUTE_DISABLE_CODE EnableExecuteDisble; > > > > + > > > > UINT8 MovEaxCr3; > > > > UINT32 Cr3Value; > > > > UINT8 MovCr3Eax[3]; > > > > @@ -75,7 +122,12 @@ typedef struct { > > > > //UINT8 DeadLoop[2]; > > > > > > > > UINT8 FarJmp32LongMode; UINT32 LongJmpOffset; UINT16 > > > > LongJmpSelector; -#endif // defined (MDE_CPU_X64) > > > > +#else > > > > + // > > > > + // Code placeholder to enable IA32 PAE Execute Disable > > > > + // > > > > + ENABLE_EXECUTE_DISABLE_CODE EnableExecuteDisble; #endif > > > > > > (2) I think that you can eliminate the #else branch (more precisely, > > > you don't need to introduce it at all). Simply add the > > > ENABLE_EXECUTE_DISABLE_CODE field above the > > > > > > #if defined (MDE_CPU_X64) > > > > > > line, so that it becomes common to X64 and Ia32. I agree that the > > > comment / purpose of the field differs between X64 and Ia32, but > > > that could be spelled out in one, common comment block. > > > > Good comments, agree with it. > > > > > > > > (3) Also, please search the whole patch for occurrences of "Disble", > > > that's a typo. > > > > My fault, will correct it. > > > > > > > > > > > > > #if defined (MDE_CPU_X64) > > > > UINT8 MovEaxOrRaxCpuDxeEntry[2]; UINTN CpuDxeEntryValue; @@ > - > > > 207,6 > > > > +259,17 @@ STARTUP_CODE mStartupCodeTemplate = { > > > > { 0x8e, 0xd0 }, // mov ss, ax > > > > > > > > #if defined (MDE_CPU_X64) > > > > + // > > > > + // Code placeholder to enable Execute Disable Bit // Default > > > > + is all NOP¡ªNo Operation > > > > > > (4) Your patch should be pure ASCII. There seems to be a UTF-8 > > > sequence between "NOP" and "No Operation", 0xA1 0xAA. > > > > I copied it from IA32 manual, will correct it. > > > > > > > > > + // > > > > + { > > > > + { 0x90, 0x90, 0x90, 0x90, 0x90 }, // mov ecx, 0xc0000080 > > > > + { 0x90, 0x90 }, // rdmsr > > > > + { 0x90, 0x90, 0x90, 0x90 }, // bts eax, 11 > > > > + { 0x90, 0x90 }, // wrmsr > > > > + }, > > > > + > > > > > > (5) I don't think it is useful to preserve the assembly instructions > > > here, in comments; the binary contents is just NOPs. The comments to > > > the right don't match. > > > > > > > 0xB8, 0x00000000, // mov eax, cr3 value > > > > { 0x0F, 0x22, 0xd8 }, // mov cr3, eax > > > > > > > > @@ -226,7 +289,29 @@ STARTUP_CODE mStartupCodeTemplate = { > > > > 0xEA, // FarJmp32LongMode > > > > OFFSET_OF(STARTUP_CODE, MovEaxOrRaxCpuDxeEntry), > > > > LINEAR_CODE64_SEL, > > > > -#endif // defined (MDE_CPU_X64) > > > > +#else > > > > + // > > > > + // Code placeholder to enable IA32 PAE Execute Disable > > > > + // Default is all NOP¡ªNo Operation > > > > + // > > > > + { > > > > + { 0x90, 0x90, 0x90, 0x90, 0x90 }, // mov ecx, 0xc0000080 > > > > + { 0x90, 0x90 }, // rdmsr > > > > + { 0x90, 0x90, 0x90, 0x90 }, // bts eax, 11 > > > > + { 0x90, 0x90 }, // wrmsr > > > > + > > > > + 0x90, 0x90909090, // mov eax, cr3 value > > > > + { 0x90, 0x90, 0x90 }, // mov cr3, eax > > > > + > > > > + { 0x90, 0x90, 0x90 }, // mov eax, cr4 > > > > + { 0x90, 0x90, 0x90, 0x90 }, // bts eax, 5 > > > > + { 0x90, 0x90, 0x90 }, // mov cr4, eax > > > > + > > > > + { 0x90, 0x90, 0x90 }, // mov eax, cr0 > > > > + { 0x90, 0x90, 0x90, 0x90 }, // bts eax, 31 > > > > + { 0x90, 0x90, 0x90 }, // mov cr0, eax > > > > + }, > > > > +#endif > > > > > > (6) Ditto. > > > > Ok, will remove them for (5) and (6). > > > > > > > > > > > > > //0xeb, 0xfe, // jmp $ > > > > #if defined (MDE_CPU_X64) > > > > @@ -241,6 +326,48 @@ STARTUP_CODE mStartupCodeTemplate = > > > { volatile > > > > STARTUP_CODE *StartupCode = NULL; > > > > > > > > /** > > > > + The function will check if BSP Execute Disable is enabled. > > > > + DxeIpl may have enabled Execute Disable for BSP, APs need to > > > > + get the status and sync up the settings. > > > > + > > > > + @retval TRUE BSP Execute Disable is enabled. > > > > + @retval FALSE BSP Execute Disable is not enabled. > > > > + > > > > +**/ > > > > +BOOLEAN > > > > +IsBspExecuteDisableEnabled ( > > > > + VOID > > > > + ) > > > > +{ > > > > + UINT32 RegEax; > > > > + UINT32 RegEdx; > > > > + UINT64 MsrRegisters; > > > > + BOOLEAN Enabled; > > > > + > > > > + Enabled = FALSE; > > > > + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); if (RegEax > > > > + >= > > > > + 0x80000001) { > > > > + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); > > > > + // > > > > + // Cpuid 0x80000001 > > > > + // Bit 20: Execute Disable Bit available. > > > > + // > > > > + if ((RegEdx & BIT20) != 0) { > > > > + MsrRegisters = AsmReadMsr64 (0xC0000080); > > > > + // > > > > + // Msr 0xC0000080 > > > > + // Bit 11: Execute Disable Bit enable. > > > > + // > > > > + if ((MsrRegisters & BIT11) != 0) { > > > > + Enabled = TRUE; > > > > + } > > > > + } > > > > + } > > > > + > > > > + return Enabled; > > > > +} > > > > + > > > > +/** > > > > Prepares Startup Code for APs. > > > > This function prepares Startup Code for APs. > > > > > > > > @@ -280,9 +407,18 @@ PrepareAPStartupCode ( > > > > > > > > StartupCode->FlatJmpOffset += (UINT32) StartAddress; > > > > > > > > + if (IsBspExecuteDisableEnabled ()) { > > > > + CopyMem ( > > > > + (VOID*) &StartupCode->EnableExecuteDisble, > > > > > > (7) No need for the (VOID*) cast. > > > > With (VOID *) cast, I met build failure below. > > Correct one typo above, "With" need to be "Without". > > > > > f:\svngit\edk2gitsvn\UefiCpuPkg\CpuDxe\ApStartup.c(412) : error C2220: > > warning treated as error - no 'object' file generated > > f:\svngit\edk2gitsvn\UefiCpuPkg\CpuDxe\ApStartup.c(412) : warning > C4090: > > 'function' : different 'volatile' qualifiers NMAKE : fatal error U1077: > > '"C:\Program Files (x86)\Microsoft Visual Studio > > 12.0\Vc\bin\x86_amd64\cl.exe"' : return code '0x2' > > Stop. > > > > I also saw the cast at CopyMem ((VOID*) StartupCode, > > &mStartupCodeTemplate, sizeof (*StartupCode));. > > > > > > > > > + &mEnableExecuteDisbleCodeTemplate, > > > > + sizeof (ENABLE_EXECUTE_DISABLE_CODE) > > > > + ); > > > > + } > > > > #if defined (MDE_CPU_X64) > > > > StartupCode->Cr3Value = (UINT32) AsmReadCr3 (); > > > > StartupCode->LongJmpOffset += (UINT32) StartAddress; > > > > +#else > > > > + StartupCode->EnableExecuteDisble.Cr3Value = (UINT32) > AsmReadCr3 > > > > +(); > > > > > > (8) I think the (UINT32) cast can be dropped in this branch, but > > > it's not important. > > > > Prefer to keep it as Cr3Value is defined as UINT32 although UINTN == > > UINT32 at IA32 build. > > > > > > > > > #endif > > > > > > > > return EFI_SUCCESS; > > > > > > > > > > So, I think the patch is good, and that we should look into the KVM > > > problem separately. I'll follow up soon. > > > > > > Thanks > > > Laszlo > > _______________________________________________ > > edk2-devel mailing list > > edk2-devel@lists.01.org > > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel