* [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM @ 2018-01-30 15:33 Laszlo Ersek 2018-01-30 15:33 ` [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() Laszlo Ersek ` (5 more replies) 0 siblings, 6 replies; 27+ messages in thread From: Laszlo Ersek @ 2018-01-30 15:33 UTC (permalink / raw) To: edk2-devel-01; +Cc: Eric Dong, Jian J Wang, Jiewen Yao, Paolo Bonzini, Ruiyu Ni Repo: https://github.com/lersek/edk2.git Branch: smm_startup_ia32_nocond This small series fixes the IA32 SMM regression on KVM that I reported recently. The first two patches are cleanups (no functional changes), the third patch is the fix. Cc: Eric Dong <eric.dong@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Thanks Laszlo Laszlo Ersek (3): UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from IA32 SmmStartup() UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in IA32 SmmStartup() UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 28 +++++++++----------- 1 file changed, 13 insertions(+), 15 deletions(-) -- 2.14.1.3.gb7cf6e02401b ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-30 15:33 [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM Laszlo Ersek @ 2018-01-30 15:33 ` Laszlo Ersek 2018-01-30 17:22 ` Kinney, Michael D 2018-01-30 15:33 ` [PATCH 2/3] UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from " Laszlo Ersek ` (4 subsequent siblings) 5 siblings, 1 reply; 27+ messages in thread From: Laszlo Ersek @ 2018-01-30 15:33 UTC (permalink / raw) To: edk2-devel-01; +Cc: Eric Dong, Jian J Wang, Jiewen Yao, Paolo Bonzini, Ruiyu Ni The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global variables are used for patching assembly instructions, thus we can never remove the DB encodings for those instructions. At least we should add the intended meanings in comments. This patch only changes comments. Cc: Eric Dong <eric.dong@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <lersek@redhat.com> --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm index e96dd8d2392a..08534dba64b7 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) ASM_PFX(SmmStartup): DB 0x66 mov eax, 0x80000001 ; read capability cpuid DB 0x66 mov ebx, edx ; rdmsr will change edx. keep it in ebx. - DB 0x66, 0xb8 + DB 0x66, 0xb8 ; mov eax, imm32 ASM_PFX(gSmmCr3): DD 0 mov cr3, eax DB 0x67, 0x66 lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - ASM_PFX(SmmStartup))] - DB 0x66, 0xb8 + DB 0x66, 0xb8 ; mov eax, imm32 ASM_PFX(gSmmCr4): DD 0 mov cr4, eax DB 0x66 mov ecx, 0xc0000080 ; IA32_EFER MSR rdmsr DB 0x66 test ebx, BIT20 ; check NXE capability jz .1 or ah, BIT3 ; set NXE bit wrmsr .1: - DB 0x66, 0xb8 + DB 0x66, 0xb8 ; mov eax, imm32 ASM_PFX(gSmmCr0): DD 0 DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, PROTECT_MODE_DS mov cr0, eax - DB 0x66, 0xea ; jmp far [ptr48] + DB 0x66, 0xea ; jmp far [ptr48] ASM_PFX(gSmmJmpAddr): DD @32bit DW PROTECT_MODE_CS @32bit: mov ds, edi mov es, edi -- 2.14.1.3.gb7cf6e02401b ^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-30 15:33 ` [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() Laszlo Ersek @ 2018-01-30 17:22 ` Kinney, Michael D 2018-01-30 18:17 ` Laszlo Ersek 0 siblings, 1 reply; 27+ messages in thread From: Kinney, Michael D @ 2018-01-30 17:22 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01, Kinney, Michael D Cc: Ni, Ruiyu, Yao, Jiewen, Dong, Eric, Paolo Bonzini Laszlo, The DBs can be removed if the label is moved after the instruction and the patch is done to the label minus the size of the patch value. Mike > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] > On Behalf Of Laszlo Ersek > Sent: Tuesday, January 30, 2018 7:34 AM > To: edk2-devel-01 <edk2-devel@lists.01.org> > Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen > <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com>; > Paolo Bonzini <pbonzini@redhat.com> > Subject: [edk2] [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: > update comments in IA32 SmmStartup() > > The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global > variables are used > for patching assembly instructions, thus we can never > remove the DB > encodings for those instructions. At least we should add > the intended > meanings in comments. > > This patch only changes comments. > > Cc: Eric Dong <eric.dong@intel.com> > Cc: Jian J Wang <jian.j.wang@intel.com> > Cc: Jiewen Yao <jiewen.yao@intel.com> > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Ruiyu Ni <ruiyu.ni@intel.com> > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Laszlo Ersek <lersek@redhat.com> > --- > UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > index e96dd8d2392a..08534dba64b7 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) > ASM_PFX(SmmStartup): > DB 0x66 > mov eax, 0x80000001 ; read > capability > cpuid > DB 0x66 > mov ebx, edx ; rdmsr will > change edx. keep it in ebx. > - DB 0x66, 0xb8 > + DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr3): DD 0 > mov cr3, eax > DB 0x67, 0x66 > lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - > ASM_PFX(SmmStartup))] > - DB 0x66, 0xb8 > + DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr4): DD 0 > mov cr4, eax > DB 0x66 > mov ecx, 0xc0000080 ; IA32_EFER MSR > rdmsr > DB 0x66 > test ebx, BIT20 ; check NXE > capability > jz .1 > or ah, BIT3 ; set NXE bit > wrmsr > .1: > - DB 0x66, 0xb8 > + DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr0): DD 0 > DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, > PROTECT_MODE_DS > mov cr0, eax > - DB 0x66, 0xea ; jmp far > [ptr48] > + DB 0x66, 0xea ; jmp far > [ptr48] > ASM_PFX(gSmmJmpAddr): > DD @32bit > DW PROTECT_MODE_CS > @32bit: > mov ds, edi > mov es, edi > -- > 2.14.1.3.gb7cf6e02401b > > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-30 17:22 ` Kinney, Michael D @ 2018-01-30 18:17 ` Laszlo Ersek 2018-01-30 20:31 ` Kinney, Michael D 0 siblings, 1 reply; 27+ messages in thread From: Laszlo Ersek @ 2018-01-30 18:17 UTC (permalink / raw) To: Kinney, Michael D, edk2-devel-01 Cc: Ni, Ruiyu, Yao, Jiewen, Dong, Eric, Paolo Bonzini On 01/30/18 18:22, Kinney, Michael D wrote: > Laszlo, > > The DBs can be removed if the label is moved after > the instruction and the patch is done to the label > minus the size of the patch value. Indeed I haven't thought of this. If I understand correctly, it means extern UINT8 gSmmCr0; *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = (UINT32)AsmReadCr0 (); TBH, the DB feels less ugly to me than this :) Still, if you think it would be an acceptable price to pay for removing the remaining DBs, I can respin. Thanks Laszlo >> -----Original Message----- >> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] >> On Behalf Of Laszlo Ersek >> Sent: Tuesday, January 30, 2018 7:34 AM >> To: edk2-devel-01 <edk2-devel@lists.01.org> >> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen >> <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com>; >> Paolo Bonzini <pbonzini@redhat.com> >> Subject: [edk2] [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: >> update comments in IA32 SmmStartup() >> >> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global >> variables are used >> for patching assembly instructions, thus we can never >> remove the DB >> encodings for those instructions. At least we should add >> the intended >> meanings in comments. >> >> This patch only changes comments. >> >> Cc: Eric Dong <eric.dong@intel.com> >> Cc: Jian J Wang <jian.j.wang@intel.com> >> Cc: Jiewen Yao <jiewen.yao@intel.com> >> Cc: Paolo Bonzini <pbonzini@redhat.com> >> Cc: Ruiyu Ni <ruiyu.ni@intel.com> >> Contributed-under: TianoCore Contribution Agreement 1.1 >> Signed-off-by: Laszlo Ersek <lersek@redhat.com> >> --- >> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 ++++---- >> 1 file changed, 4 insertions(+), 4 deletions(-) >> >> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >> index e96dd8d2392a..08534dba64b7 100644 >> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) >> ASM_PFX(SmmStartup): >> DB 0x66 >> mov eax, 0x80000001 ; read >> capability >> cpuid >> DB 0x66 >> mov ebx, edx ; rdmsr will >> change edx. keep it in ebx. >> - DB 0x66, 0xb8 >> + DB 0x66, 0xb8 ; mov eax, imm32 >> ASM_PFX(gSmmCr3): DD 0 >> mov cr3, eax >> DB 0x67, 0x66 >> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - >> ASM_PFX(SmmStartup))] >> - DB 0x66, 0xb8 >> + DB 0x66, 0xb8 ; mov eax, imm32 >> ASM_PFX(gSmmCr4): DD 0 >> mov cr4, eax >> DB 0x66 >> mov ecx, 0xc0000080 ; IA32_EFER MSR >> rdmsr >> DB 0x66 >> test ebx, BIT20 ; check NXE >> capability >> jz .1 >> or ah, BIT3 ; set NXE bit >> wrmsr >> .1: >> - DB 0x66, 0xb8 >> + DB 0x66, 0xb8 ; mov eax, imm32 >> ASM_PFX(gSmmCr0): DD 0 >> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, >> PROTECT_MODE_DS >> mov cr0, eax >> - DB 0x66, 0xea ; jmp far >> [ptr48] >> + DB 0x66, 0xea ; jmp far >> [ptr48] >> ASM_PFX(gSmmJmpAddr): >> DD @32bit >> DW PROTECT_MODE_CS >> @32bit: >> mov ds, edi >> mov es, edi >> -- >> 2.14.1.3.gb7cf6e02401b >> >> >> _______________________________________________ >> edk2-devel mailing list >> edk2-devel@lists.01.org >> https://lists.01.org/mailman/listinfo/edk2-devel ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-30 18:17 ` Laszlo Ersek @ 2018-01-30 20:31 ` Kinney, Michael D 2018-01-30 21:26 ` Kinney, Michael D 2018-01-30 21:45 ` Laszlo Ersek 0 siblings, 2 replies; 27+ messages in thread From: Kinney, Michael D @ 2018-01-30 20:31 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01, Kinney, Michael D Cc: Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric Laszlo, We have already used this technique in other NASM files to remove DBs. Let us know if you have suggestions on how to make the C code that performs the patches easier to read and maintain. Mike > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] > On Behalf Of Laszlo Ersek > Sent: Tuesday, January 30, 2018 10:17 AM > To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2- > devel-01 <edk2-devel@lists.01.org> > Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini > <pbonzini@redhat.com>; Yao, Jiewen > <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> > Subject: Re: [edk2] [PATCH 1/3] > UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 > SmmStartup() > > On 01/30/18 18:22, Kinney, Michael D wrote: > > Laszlo, > > > > The DBs can be removed if the label is moved after > > the instruction and the patch is done to the label > > minus the size of the patch value. > > Indeed I haven't thought of this. > > If I understand correctly, it means > > extern UINT8 gSmmCr0; > > *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = > (UINT32)AsmReadCr0 (); > > TBH, the DB feels less ugly to me than this :) > > Still, if you think it would be an acceptable price to > pay for removing > the remaining DBs, I can respin. > > Thanks > Laszlo > > >> -----Original Message----- > >> From: edk2-devel [mailto:edk2-devel- > bounces@lists.01.org] > >> On Behalf Of Laszlo Ersek > >> Sent: Tuesday, January 30, 2018 7:34 AM > >> To: edk2-devel-01 <edk2-devel@lists.01.org> > >> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen > >> <jiewen.yao@intel.com>; Dong, Eric > <eric.dong@intel.com>; > >> Paolo Bonzini <pbonzini@redhat.com> > >> Subject: [edk2] [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: > >> update comments in IA32 SmmStartup() > >> > >> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global > >> variables are used > >> for patching assembly instructions, thus we can never > >> remove the DB > >> encodings for those instructions. At least we should > add > >> the intended > >> meanings in comments. > >> > >> This patch only changes comments. > >> > >> Cc: Eric Dong <eric.dong@intel.com> > >> Cc: Jian J Wang <jian.j.wang@intel.com> > >> Cc: Jiewen Yao <jiewen.yao@intel.com> > >> Cc: Paolo Bonzini <pbonzini@redhat.com> > >> Cc: Ruiyu Ni <ruiyu.ni@intel.com> > >> Contributed-under: TianoCore Contribution Agreement > 1.1 > >> Signed-off-by: Laszlo Ersek <lersek@redhat.com> > >> --- > >> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 ++++- > --- > >> 1 file changed, 4 insertions(+), 4 deletions(-) > >> > >> diff --git > a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >> index e96dd8d2392a..08534dba64b7 100644 > >> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) > >> ASM_PFX(SmmStartup): > >> DB 0x66 > >> mov eax, 0x80000001 ; read > >> capability > >> cpuid > >> DB 0x66 > >> mov ebx, edx ; rdmsr will > >> change edx. keep it in ebx. > >> - DB 0x66, 0xb8 > >> + DB 0x66, 0xb8 ; mov eax, > imm32 > >> ASM_PFX(gSmmCr3): DD 0 > >> mov cr3, eax > >> DB 0x67, 0x66 > >> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - > >> ASM_PFX(SmmStartup))] > >> - DB 0x66, 0xb8 > >> + DB 0x66, 0xb8 ; mov eax, > imm32 > >> ASM_PFX(gSmmCr4): DD 0 > >> mov cr4, eax > >> DB 0x66 > >> mov ecx, 0xc0000080 ; IA32_EFER > MSR > >> rdmsr > >> DB 0x66 > >> test ebx, BIT20 ; check NXE > >> capability > >> jz .1 > >> or ah, BIT3 ; set NXE bit > >> wrmsr > >> .1: > >> - DB 0x66, 0xb8 > >> + DB 0x66, 0xb8 ; mov eax, > imm32 > >> ASM_PFX(gSmmCr0): DD 0 > >> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, > >> PROTECT_MODE_DS > >> mov cr0, eax > >> - DB 0x66, 0xea ; jmp far > >> [ptr48] > >> + DB 0x66, 0xea ; jmp far > >> [ptr48] > >> ASM_PFX(gSmmJmpAddr): > >> DD @32bit > >> DW PROTECT_MODE_CS > >> @32bit: > >> mov ds, edi > >> mov es, edi > >> -- > >> 2.14.1.3.gb7cf6e02401b > >> > >> > >> _______________________________________________ > >> 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-30 20:31 ` Kinney, Michael D @ 2018-01-30 21:26 ` Kinney, Michael D 2018-01-30 21:55 ` Laszlo Ersek 2018-01-30 21:45 ` Laszlo Ersek 1 sibling, 1 reply; 27+ messages in thread From: Kinney, Michael D @ 2018-01-30 21:26 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01, Kinney, Michael D Cc: Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric Laszlo, Maybe we can add a macro to help: #define PATCH_X86_ASM(Label,Type,Value) *((Type *)(&Label) - 1) = (Type)(Value) PATCH_X86_ASM (gSmmCr0, UINT32, AsmReadCr0()); Mike > -----Original Message----- > From: Kinney, Michael D > Sent: Tuesday, January 30, 2018 12:31 PM > To: Laszlo Ersek <lersek@redhat.com>; edk2-devel-01 > <edk2-devel@lists.01.org>; Kinney, Michael D > <michael.d.kinney@intel.com> > Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini > <pbonzini@redhat.com>; Yao, Jiewen > <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> > Subject: RE: [edk2] [PATCH 1/3] > UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 > SmmStartup() > > Laszlo, > > We have already used this technique in other NASM files > to remove DBs. > > Let us know if you have suggestions on how to make the > C code that performs the patches easier to read and > maintain. > > Mike > > > -----Original Message----- > > From: edk2-devel [mailto:edk2-devel- > bounces@lists.01.org] > > On Behalf Of Laszlo Ersek > > Sent: Tuesday, January 30, 2018 10:17 AM > > To: Kinney, Michael D <michael.d.kinney@intel.com>; > edk2- > > devel-01 <edk2-devel@lists.01.org> > > Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini > > <pbonzini@redhat.com>; Yao, Jiewen > > <jiewen.yao@intel.com>; Dong, Eric > <eric.dong@intel.com> > > Subject: Re: [edk2] [PATCH 1/3] > > UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 > > SmmStartup() > > > > On 01/30/18 18:22, Kinney, Michael D wrote: > > > Laszlo, > > > > > > The DBs can be removed if the label is moved after > > > the instruction and the patch is done to the label > > > minus the size of the patch value. > > > > Indeed I haven't thought of this. > > > > If I understand correctly, it means > > > > extern UINT8 gSmmCr0; > > > > *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = > > (UINT32)AsmReadCr0 (); > > > > TBH, the DB feels less ugly to me than this :) > > > > Still, if you think it would be an acceptable price to > > pay for removing > > the remaining DBs, I can respin. > > > > Thanks > > Laszlo > > > > >> -----Original Message----- > > >> From: edk2-devel [mailto:edk2-devel- > > bounces@lists.01.org] > > >> On Behalf Of Laszlo Ersek > > >> Sent: Tuesday, January 30, 2018 7:34 AM > > >> To: edk2-devel-01 <edk2-devel@lists.01.org> > > >> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen > > >> <jiewen.yao@intel.com>; Dong, Eric > > <eric.dong@intel.com>; > > >> Paolo Bonzini <pbonzini@redhat.com> > > >> Subject: [edk2] [PATCH 1/3] > UefiCpuPkg/PiSmmCpuDxeSmm: > > >> update comments in IA32 SmmStartup() > > >> > > >> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global > > >> variables are used > > >> for patching assembly instructions, thus we can > never > > >> remove the DB > > >> encodings for those instructions. At least we should > > add > > >> the intended > > >> meanings in comments. > > >> > > >> This patch only changes comments. > > >> > > >> Cc: Eric Dong <eric.dong@intel.com> > > >> Cc: Jian J Wang <jian.j.wang@intel.com> > > >> Cc: Jiewen Yao <jiewen.yao@intel.com> > > >> Cc: Paolo Bonzini <pbonzini@redhat.com> > > >> Cc: Ruiyu Ni <ruiyu.ni@intel.com> > > >> Contributed-under: TianoCore Contribution Agreement > > 1.1 > > >> Signed-off-by: Laszlo Ersek <lersek@redhat.com> > > >> --- > > >> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 > ++++- > > --- > > >> 1 file changed, 4 insertions(+), 4 deletions(-) > > >> > > >> diff --git > > a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > > >> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > > >> index e96dd8d2392a..08534dba64b7 100644 > > >> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > > >> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > > >> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) > > >> ASM_PFX(SmmStartup): > > >> DB 0x66 > > >> mov eax, 0x80000001 ; read > > >> capability > > >> cpuid > > >> DB 0x66 > > >> mov ebx, edx ; rdmsr > will > > >> change edx. keep it in ebx. > > >> - DB 0x66, 0xb8 > > >> + DB 0x66, 0xb8 ; mov eax, > > imm32 > > >> ASM_PFX(gSmmCr3): DD 0 > > >> mov cr3, eax > > >> DB 0x67, 0x66 > > >> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - > > >> ASM_PFX(SmmStartup))] > > >> - DB 0x66, 0xb8 > > >> + DB 0x66, 0xb8 ; mov eax, > > imm32 > > >> ASM_PFX(gSmmCr4): DD 0 > > >> mov cr4, eax > > >> DB 0x66 > > >> mov ecx, 0xc0000080 ; IA32_EFER > > MSR > > >> rdmsr > > >> DB 0x66 > > >> test ebx, BIT20 ; check NXE > > >> capability > > >> jz .1 > > >> or ah, BIT3 ; set NXE > bit > > >> wrmsr > > >> .1: > > >> - DB 0x66, 0xb8 > > >> + DB 0x66, 0xb8 ; mov eax, > > imm32 > > >> ASM_PFX(gSmmCr0): DD 0 > > >> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, > > >> PROTECT_MODE_DS > > >> mov cr0, eax > > >> - DB 0x66, 0xea ; jmp far > > >> [ptr48] > > >> + DB 0x66, 0xea ; jmp far > > >> [ptr48] > > >> ASM_PFX(gSmmJmpAddr): > > >> DD @32bit > > >> DW PROTECT_MODE_CS > > >> @32bit: > > >> mov ds, edi > > >> mov es, edi > > >> -- > > >> 2.14.1.3.gb7cf6e02401b > > >> > > >> > > >> _______________________________________________ > > >> 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-30 21:26 ` Kinney, Michael D @ 2018-01-30 21:55 ` Laszlo Ersek 0 siblings, 0 replies; 27+ messages in thread From: Laszlo Ersek @ 2018-01-30 21:55 UTC (permalink / raw) To: Kinney, Michael D, edk2-devel-01 Cc: Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric On 01/30/18 22:26, Kinney, Michael D wrote: > Laszlo, > > Maybe we can add a macro to help: > > #define PATCH_X86_ASM(Label,Type,Value) *((Type *)(&Label) - 1) = (Type)(Value) > > PATCH_X86_ASM (gSmmCr0, UINT32, AsmReadCr0()); Before sending my previous email, I thought of something like this. Here I slightly dislike: - the unaligned access to a wider-than-byte object - the larger potential for triggering undefined behavior in the C language implementation (due to type punning) -- doing the arithmetic in UINTN and using CopyMem for the data movement should mitigate that - the requirement that the object to patch has to be followed by the same number of bytes (otherwise linking might fail, I think). For example if we'd like to patch 4 bytes at the very end of the assembly code, e.g. in a jmp instruction, we'd have to match that with a DD, just so the extern UINT32 global variable could be declared and linked. I think requiring just one byte trailing padding and making all such markers UINT8 is easier to handle - the requirement that the declared type of "gSmmCr0" match the type passed to the macro as 2nd argument That said, I'm fine using either of PATCH_X86_ASM() and PatchAssembly(). Thanks! Laszlo > > Mike > >> -----Original Message----- >> From: Kinney, Michael D >> Sent: Tuesday, January 30, 2018 12:31 PM >> To: Laszlo Ersek <lersek@redhat.com>; edk2-devel-01 >> <edk2-devel@lists.01.org>; Kinney, Michael D >> <michael.d.kinney@intel.com> >> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >> <pbonzini@redhat.com>; Yao, Jiewen >> <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> >> Subject: RE: [edk2] [PATCH 1/3] >> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >> SmmStartup() >> >> Laszlo, >> >> We have already used this technique in other NASM files >> to remove DBs. >> >> Let us know if you have suggestions on how to make the >> C code that performs the patches easier to read and >> maintain. >> >> Mike >> >>> -----Original Message----- >>> From: edk2-devel [mailto:edk2-devel- >> bounces@lists.01.org] >>> On Behalf Of Laszlo Ersek >>> Sent: Tuesday, January 30, 2018 10:17 AM >>> To: Kinney, Michael D <michael.d.kinney@intel.com>; >> edk2- >>> devel-01 <edk2-devel@lists.01.org> >>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>> <pbonzini@redhat.com>; Yao, Jiewen >>> <jiewen.yao@intel.com>; Dong, Eric >> <eric.dong@intel.com> >>> Subject: Re: [edk2] [PATCH 1/3] >>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>> SmmStartup() >>> >>> On 01/30/18 18:22, Kinney, Michael D wrote: >>>> Laszlo, >>>> >>>> The DBs can be removed if the label is moved after >>>> the instruction and the patch is done to the label >>>> minus the size of the patch value. >>> >>> Indeed I haven't thought of this. >>> >>> If I understand correctly, it means >>> >>> extern UINT8 gSmmCr0; >>> >>> *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = >>> (UINT32)AsmReadCr0 (); >>> >>> TBH, the DB feels less ugly to me than this :) >>> >>> Still, if you think it would be an acceptable price to >>> pay for removing >>> the remaining DBs, I can respin. >>> >>> Thanks >>> Laszlo >>> >>>>> -----Original Message----- >>>>> From: edk2-devel [mailto:edk2-devel- >>> bounces@lists.01.org] >>>>> On Behalf Of Laszlo Ersek >>>>> Sent: Tuesday, January 30, 2018 7:34 AM >>>>> To: edk2-devel-01 <edk2-devel@lists.01.org> >>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen >>>>> <jiewen.yao@intel.com>; Dong, Eric >>> <eric.dong@intel.com>; >>>>> Paolo Bonzini <pbonzini@redhat.com> >>>>> Subject: [edk2] [PATCH 1/3] >> UefiCpuPkg/PiSmmCpuDxeSmm: >>>>> update comments in IA32 SmmStartup() >>>>> >>>>> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global >>>>> variables are used >>>>> for patching assembly instructions, thus we can >> never >>>>> remove the DB >>>>> encodings for those instructions. At least we should >>> add >>>>> the intended >>>>> meanings in comments. >>>>> >>>>> This patch only changes comments. >>>>> >>>>> Cc: Eric Dong <eric.dong@intel.com> >>>>> Cc: Jian J Wang <jian.j.wang@intel.com> >>>>> Cc: Jiewen Yao <jiewen.yao@intel.com> >>>>> Cc: Paolo Bonzini <pbonzini@redhat.com> >>>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com> >>>>> Contributed-under: TianoCore Contribution Agreement >>> 1.1 >>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com> >>>>> --- >>>>> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 >> ++++- >>> --- >>>>> 1 file changed, 4 insertions(+), 4 deletions(-) >>>>> >>>>> diff --git >>> a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>> index e96dd8d2392a..08534dba64b7 100644 >>>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) >>>>> ASM_PFX(SmmStartup): >>>>> DB 0x66 >>>>> mov eax, 0x80000001 ; read >>>>> capability >>>>> cpuid >>>>> DB 0x66 >>>>> mov ebx, edx ; rdmsr >> will >>>>> change edx. keep it in ebx. >>>>> - DB 0x66, 0xb8 >>>>> + DB 0x66, 0xb8 ; mov eax, >>> imm32 >>>>> ASM_PFX(gSmmCr3): DD 0 >>>>> mov cr3, eax >>>>> DB 0x67, 0x66 >>>>> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - >>>>> ASM_PFX(SmmStartup))] >>>>> - DB 0x66, 0xb8 >>>>> + DB 0x66, 0xb8 ; mov eax, >>> imm32 >>>>> ASM_PFX(gSmmCr4): DD 0 >>>>> mov cr4, eax >>>>> DB 0x66 >>>>> mov ecx, 0xc0000080 ; IA32_EFER >>> MSR >>>>> rdmsr >>>>> DB 0x66 >>>>> test ebx, BIT20 ; check NXE >>>>> capability >>>>> jz .1 >>>>> or ah, BIT3 ; set NXE >> bit >>>>> wrmsr >>>>> .1: >>>>> - DB 0x66, 0xb8 >>>>> + DB 0x66, 0xb8 ; mov eax, >>> imm32 >>>>> ASM_PFX(gSmmCr0): DD 0 >>>>> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, >>>>> PROTECT_MODE_DS >>>>> mov cr0, eax >>>>> - DB 0x66, 0xea ; jmp far >>>>> [ptr48] >>>>> + DB 0x66, 0xea ; jmp far >>>>> [ptr48] >>>>> ASM_PFX(gSmmJmpAddr): >>>>> DD @32bit >>>>> DW PROTECT_MODE_CS >>>>> @32bit: >>>>> mov ds, edi >>>>> mov es, edi >>>>> -- >>>>> 2.14.1.3.gb7cf6e02401b >>>>> >>>>> >>>>> _______________________________________________ >>>>> 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-30 20:31 ` Kinney, Michael D 2018-01-30 21:26 ` Kinney, Michael D @ 2018-01-30 21:45 ` Laszlo Ersek 2018-01-30 22:25 ` Kinney, Michael D 1 sibling, 1 reply; 27+ messages in thread From: Laszlo Ersek @ 2018-01-30 21:45 UTC (permalink / raw) To: Kinney, Michael D, edk2-devel-01 Cc: Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric On 01/30/18 21:31, Kinney, Michael D wrote: > Laszlo, > > We have already used this technique in other NASM files > to remove DBs. OK. > Let us know if you have suggestions on how to make the > C code that performs the patches easier to read and > maintain. How about this: VOID PatchAssembly ( VOID *BufferEnd, UINT64 PatchValue, UINTN ValueSize ) { CopyMem ( (VOID *)((UINTN)BufferEnd - ValueSize), &PatchValue, ValueSize ); } extern UINT8 gAsmSmmCr0; extern UINT8 gAsmSmmCr3; extern UINT8 gAsmSmmCr4; ... { PatchAssembly (&gAsmSmmCr0, AsmReadCr0 (), 4); PatchAssembly (&gAsmSmmCr3, AsmReadCr3 (), 4); PatchAssembly (&gAsmSmmCr4, AsmReadCr4 (), 4); ... } (I think it's fine to open-code the last argument as "4", rather than "sizeof (UINT32)", because for patching, we must have intimate knowledge of the instruction anyway.) To me, this is easier to read, because: - there are no complex casts in the "business logic" - the size is spelled out once per patching - the function name and the variable names make it clear we are patching separately compiled assembly code that was linked into the same module. What do you think? Thanks! Laszlo >> -----Original Message----- >> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] >> On Behalf Of Laszlo Ersek >> Sent: Tuesday, January 30, 2018 10:17 AM >> To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2- >> devel-01 <edk2-devel@lists.01.org> >> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >> <pbonzini@redhat.com>; Yao, Jiewen >> <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> >> Subject: Re: [edk2] [PATCH 1/3] >> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >> SmmStartup() >> >> On 01/30/18 18:22, Kinney, Michael D wrote: >>> Laszlo, >>> >>> The DBs can be removed if the label is moved after >>> the instruction and the patch is done to the label >>> minus the size of the patch value. >> >> Indeed I haven't thought of this. >> >> If I understand correctly, it means >> >> extern UINT8 gSmmCr0; >> >> *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = >> (UINT32)AsmReadCr0 (); >> >> TBH, the DB feels less ugly to me than this :) >> >> Still, if you think it would be an acceptable price to >> pay for removing >> the remaining DBs, I can respin. >> >> Thanks >> Laszlo >> >>>> -----Original Message----- >>>> From: edk2-devel [mailto:edk2-devel- >> bounces@lists.01.org] >>>> On Behalf Of Laszlo Ersek >>>> Sent: Tuesday, January 30, 2018 7:34 AM >>>> To: edk2-devel-01 <edk2-devel@lists.01.org> >>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen >>>> <jiewen.yao@intel.com>; Dong, Eric >> <eric.dong@intel.com>; >>>> Paolo Bonzini <pbonzini@redhat.com> >>>> Subject: [edk2] [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: >>>> update comments in IA32 SmmStartup() >>>> >>>> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global >>>> variables are used >>>> for patching assembly instructions, thus we can never >>>> remove the DB >>>> encodings for those instructions. At least we should >> add >>>> the intended >>>> meanings in comments. >>>> >>>> This patch only changes comments. >>>> >>>> Cc: Eric Dong <eric.dong@intel.com> >>>> Cc: Jian J Wang <jian.j.wang@intel.com> >>>> Cc: Jiewen Yao <jiewen.yao@intel.com> >>>> Cc: Paolo Bonzini <pbonzini@redhat.com> >>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com> >>>> Contributed-under: TianoCore Contribution Agreement >> 1.1 >>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com> >>>> --- >>>> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 ++++- >> --- >>>> 1 file changed, 4 insertions(+), 4 deletions(-) >>>> >>>> diff --git >> a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>> index e96dd8d2392a..08534dba64b7 100644 >>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) >>>> ASM_PFX(SmmStartup): >>>> DB 0x66 >>>> mov eax, 0x80000001 ; read >>>> capability >>>> cpuid >>>> DB 0x66 >>>> mov ebx, edx ; rdmsr will >>>> change edx. keep it in ebx. >>>> - DB 0x66, 0xb8 >>>> + DB 0x66, 0xb8 ; mov eax, >> imm32 >>>> ASM_PFX(gSmmCr3): DD 0 >>>> mov cr3, eax >>>> DB 0x67, 0x66 >>>> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - >>>> ASM_PFX(SmmStartup))] >>>> - DB 0x66, 0xb8 >>>> + DB 0x66, 0xb8 ; mov eax, >> imm32 >>>> ASM_PFX(gSmmCr4): DD 0 >>>> mov cr4, eax >>>> DB 0x66 >>>> mov ecx, 0xc0000080 ; IA32_EFER >> MSR >>>> rdmsr >>>> DB 0x66 >>>> test ebx, BIT20 ; check NXE >>>> capability >>>> jz .1 >>>> or ah, BIT3 ; set NXE bit >>>> wrmsr >>>> .1: >>>> - DB 0x66, 0xb8 >>>> + DB 0x66, 0xb8 ; mov eax, >> imm32 >>>> ASM_PFX(gSmmCr0): DD 0 >>>> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, >>>> PROTECT_MODE_DS >>>> mov cr0, eax >>>> - DB 0x66, 0xea ; jmp far >>>> [ptr48] >>>> + DB 0x66, 0xea ; jmp far >>>> [ptr48] >>>> ASM_PFX(gSmmJmpAddr): >>>> DD @32bit >>>> DW PROTECT_MODE_CS >>>> @32bit: >>>> mov ds, edi >>>> mov es, edi >>>> -- >>>> 2.14.1.3.gb7cf6e02401b >>>> >>>> >>>> _______________________________________________ >>>> 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-30 21:45 ` Laszlo Ersek @ 2018-01-30 22:25 ` Kinney, Michael D 2018-01-31 5:44 ` Ni, Ruiyu 2018-01-31 10:40 ` Laszlo Ersek 0 siblings, 2 replies; 27+ messages in thread From: Kinney, Michael D @ 2018-01-30 22:25 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01, Kinney, Michael D Cc: Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric Laszlo, I agree that the function is better than a macro. I thought of the alignment issues as well. CopyMem() is a good solution. We could also consider WriteUnalignedxx() functions in BaseLib. I was originally thinking this functionality would go into BaseLib. But with the use of CopyMem(), we can't do that. Maybe we should use WriteUnalignedxx() and add some ASSERT() checks. VOID PatchAssembly ( VOID *BufferEnd, UINT64 PatchValue, UINTN ValueSize ) { ASSERT ((UINTN)BufferEnd > ValueSize); switch (ValueSize) { case 1: ASSERT (PatchValue <= MAX_UINT8); *((UINT8 *)BufferEnd - 1) = (UINT8)PatchValue; case 2: ASSERT (PatchValue <= MAX_UINT16); WriteUnaligned16 ((UINT16 *)(BufferEnd) - 1, (UINT16)PatchValue)); break; case 4: ASSERT (PatchValue <= MAX_UINT32); WriteUnaligned32 ((UINT32 *)(BufferEnd) - 1, (UINT32)PatchValue)); break; case 8: WriteUnaligned64 ((UINT64 *)(BufferEnd) - 1, PatchValue)); break; default: ASSERT (FALSE); } } Mike > -----Original Message----- > From: Laszlo Ersek [mailto:lersek@redhat.com] > Sent: Tuesday, January 30, 2018 1:45 PM > To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2- > devel-01 <edk2-devel@lists.01.org> > Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini > <pbonzini@redhat.com>; Yao, Jiewen > <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> > Subject: Re: [edk2] [PATCH 1/3] > UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 > SmmStartup() > > On 01/30/18 21:31, Kinney, Michael D wrote: > > Laszlo, > > > > We have already used this technique in other NASM files > > to remove DBs. > > OK. > > > Let us know if you have suggestions on how to make the > > C code that performs the patches easier to read and > > maintain. > > How about this: > > VOID > PatchAssembly ( > VOID *BufferEnd, > UINT64 PatchValue, > UINTN ValueSize > ) > { > CopyMem ( > (VOID *)((UINTN)BufferEnd - ValueSize), > &PatchValue, > ValueSize > ); > } > > extern UINT8 gAsmSmmCr0; > extern UINT8 gAsmSmmCr3; > extern UINT8 gAsmSmmCr4; > > ... > { > PatchAssembly (&gAsmSmmCr0, AsmReadCr0 (), 4); > PatchAssembly (&gAsmSmmCr3, AsmReadCr3 (), 4); > PatchAssembly (&gAsmSmmCr4, AsmReadCr4 (), 4); > ... > } > > (I think it's fine to open-code the last argument as "4", > rather than > "sizeof (UINT32)", because for patching, we must have > intimate knowledge > of the instruction anyway.) > > To me, this is easier to read, because: > > - there are no complex casts in the "business logic" > - the size is spelled out once per patching > - the function name and the variable names make it clear > we are patching > separately compiled assembly code that was linked into > the same > module. > > What do you think? > > Thanks! > Laszlo > > >> -----Original Message----- > >> From: edk2-devel [mailto:edk2-devel- > bounces@lists.01.org] > >> On Behalf Of Laszlo Ersek > >> Sent: Tuesday, January 30, 2018 10:17 AM > >> To: Kinney, Michael D <michael.d.kinney@intel.com>; > edk2- > >> devel-01 <edk2-devel@lists.01.org> > >> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini > >> <pbonzini@redhat.com>; Yao, Jiewen > >> <jiewen.yao@intel.com>; Dong, Eric > <eric.dong@intel.com> > >> Subject: Re: [edk2] [PATCH 1/3] > >> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 > >> SmmStartup() > >> > >> On 01/30/18 18:22, Kinney, Michael D wrote: > >>> Laszlo, > >>> > >>> The DBs can be removed if the label is moved after > >>> the instruction and the patch is done to the label > >>> minus the size of the patch value. > >> > >> Indeed I haven't thought of this. > >> > >> If I understand correctly, it means > >> > >> extern UINT8 gSmmCr0; > >> > >> *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = > >> (UINT32)AsmReadCr0 (); > >> > >> TBH, the DB feels less ugly to me than this :) > >> > >> Still, if you think it would be an acceptable price to > >> pay for removing > >> the remaining DBs, I can respin. > >> > >> Thanks > >> Laszlo > >> > >>>> -----Original Message----- > >>>> From: edk2-devel [mailto:edk2-devel- > >> bounces@lists.01.org] > >>>> On Behalf Of Laszlo Ersek > >>>> Sent: Tuesday, January 30, 2018 7:34 AM > >>>> To: edk2-devel-01 <edk2-devel@lists.01.org> > >>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen > >>>> <jiewen.yao@intel.com>; Dong, Eric > >> <eric.dong@intel.com>; > >>>> Paolo Bonzini <pbonzini@redhat.com> > >>>> Subject: [edk2] [PATCH 1/3] > UefiCpuPkg/PiSmmCpuDxeSmm: > >>>> update comments in IA32 SmmStartup() > >>>> > >>>> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global > >>>> variables are used > >>>> for patching assembly instructions, thus we can > never > >>>> remove the DB > >>>> encodings for those instructions. At least we should > >> add > >>>> the intended > >>>> meanings in comments. > >>>> > >>>> This patch only changes comments. > >>>> > >>>> Cc: Eric Dong <eric.dong@intel.com> > >>>> Cc: Jian J Wang <jian.j.wang@intel.com> > >>>> Cc: Jiewen Yao <jiewen.yao@intel.com> > >>>> Cc: Paolo Bonzini <pbonzini@redhat.com> > >>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com> > >>>> Contributed-under: TianoCore Contribution Agreement > >> 1.1 > >>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com> > >>>> --- > >>>> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 > ++++- > >> --- > >>>> 1 file changed, 4 insertions(+), 4 deletions(-) > >>>> > >>>> diff --git > >> a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >>>> index e96dd8d2392a..08534dba64b7 100644 > >>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >>>> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) > >>>> ASM_PFX(SmmStartup): > >>>> DB 0x66 > >>>> mov eax, 0x80000001 ; read > >>>> capability > >>>> cpuid > >>>> DB 0x66 > >>>> mov ebx, edx ; rdmsr > will > >>>> change edx. keep it in ebx. > >>>> - DB 0x66, 0xb8 > >>>> + DB 0x66, 0xb8 ; mov eax, > >> imm32 > >>>> ASM_PFX(gSmmCr3): DD 0 > >>>> mov cr3, eax > >>>> DB 0x67, 0x66 > >>>> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - > >>>> ASM_PFX(SmmStartup))] > >>>> - DB 0x66, 0xb8 > >>>> + DB 0x66, 0xb8 ; mov eax, > >> imm32 > >>>> ASM_PFX(gSmmCr4): DD 0 > >>>> mov cr4, eax > >>>> DB 0x66 > >>>> mov ecx, 0xc0000080 ; IA32_EFER > >> MSR > >>>> rdmsr > >>>> DB 0x66 > >>>> test ebx, BIT20 ; check NXE > >>>> capability > >>>> jz .1 > >>>> or ah, BIT3 ; set NXE > bit > >>>> wrmsr > >>>> .1: > >>>> - DB 0x66, 0xb8 > >>>> + DB 0x66, 0xb8 ; mov eax, > >> imm32 > >>>> ASM_PFX(gSmmCr0): DD 0 > >>>> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, > >>>> PROTECT_MODE_DS > >>>> mov cr0, eax > >>>> - DB 0x66, 0xea ; jmp far > >>>> [ptr48] > >>>> + DB 0x66, 0xea ; jmp far > >>>> [ptr48] > >>>> ASM_PFX(gSmmJmpAddr): > >>>> DD @32bit > >>>> DW PROTECT_MODE_CS > >>>> @32bit: > >>>> mov ds, edi > >>>> mov es, edi > >>>> -- > >>>> 2.14.1.3.gb7cf6e02401b > >>>> > >>>> > >>>> _______________________________________________ > >>>> 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-30 22:25 ` Kinney, Michael D @ 2018-01-31 5:44 ` Ni, Ruiyu 2018-01-31 5:54 ` Ni, Ruiyu 2018-01-31 10:42 ` Laszlo Ersek 2018-01-31 10:40 ` Laszlo Ersek 1 sibling, 2 replies; 27+ messages in thread From: Ni, Ruiyu @ 2018-01-31 5:44 UTC (permalink / raw) To: Kinney, Michael D, Laszlo Ersek, edk2-devel-01 Cc: Paolo Bonzini, Yao, Jiewen, Dong, Eric Mike, Laszlo, Does the patch only apply to the operand? If so, PatchAssembly looks too general. How about the name like PatchAssemblyOperand? On 1/31/2018 6:25 AM, Kinney, Michael D wrote: > Laszlo, > > I agree that the function is better than a macro. > > I thought of the alignment issues as well. CopyMem() > is a good solution. We could also consider > WriteUnalignedxx() functions in BaseLib. > > I was originally thinking this functionality would go > into BaseLib. But with the use of CopyMem(), we can't > do that. Maybe we should use WriteUnalignedxx() and > add some ASSERT() checks. > > VOID > PatchAssembly ( > VOID *BufferEnd, > UINT64 PatchValue, > UINTN ValueSize > ) > { > ASSERT ((UINTN)BufferEnd > ValueSize); > switch (ValueSize) { > case 1: > ASSERT (PatchValue <= MAX_UINT8); > *((UINT8 *)BufferEnd - 1) = (UINT8)PatchValue; > case 2: > ASSERT (PatchValue <= MAX_UINT16); > WriteUnaligned16 ((UINT16 *)(BufferEnd) - 1, (UINT16)PatchValue)); > break; > case 4: > ASSERT (PatchValue <= MAX_UINT32); > WriteUnaligned32 ((UINT32 *)(BufferEnd) - 1, (UINT32)PatchValue)); > break; > case 8: > WriteUnaligned64 ((UINT64 *)(BufferEnd) - 1, PatchValue)); > break; > default: > ASSERT (FALSE); > } > } > > Mike > >> -----Original Message----- >> From: Laszlo Ersek [mailto:lersek@redhat.com] >> Sent: Tuesday, January 30, 2018 1:45 PM >> To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2- >> devel-01 <edk2-devel@lists.01.org> >> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >> <pbonzini@redhat.com>; Yao, Jiewen >> <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> >> Subject: Re: [edk2] [PATCH 1/3] >> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >> SmmStartup() >> >> On 01/30/18 21:31, Kinney, Michael D wrote: >>> Laszlo, >>> >>> We have already used this technique in other NASM files >>> to remove DBs. >> >> OK. >> >>> Let us know if you have suggestions on how to make the >>> C code that performs the patches easier to read and >>> maintain. >> >> How about this: >> >> VOID >> PatchAssembly ( >> VOID *BufferEnd, >> UINT64 PatchValue, >> UINTN ValueSize >> ) >> { >> CopyMem ( >> (VOID *)((UINTN)BufferEnd - ValueSize), >> &PatchValue, >> ValueSize >> ); >> } >> >> extern UINT8 gAsmSmmCr0; >> extern UINT8 gAsmSmmCr3; >> extern UINT8 gAsmSmmCr4; >> >> ... >> { >> PatchAssembly (&gAsmSmmCr0, AsmReadCr0 (), 4); >> PatchAssembly (&gAsmSmmCr3, AsmReadCr3 (), 4); >> PatchAssembly (&gAsmSmmCr4, AsmReadCr4 (), 4); >> ... >> } >> >> (I think it's fine to open-code the last argument as "4", >> rather than >> "sizeof (UINT32)", because for patching, we must have >> intimate knowledge >> of the instruction anyway.) >> >> To me, this is easier to read, because: >> >> - there are no complex casts in the "business logic" >> - the size is spelled out once per patching >> - the function name and the variable names make it clear >> we are patching >> separately compiled assembly code that was linked into >> the same >> module. >> >> What do you think? >> >> Thanks! >> Laszlo >> >>>> -----Original Message----- >>>> From: edk2-devel [mailto:edk2-devel- >> bounces@lists.01.org] >>>> On Behalf Of Laszlo Ersek >>>> Sent: Tuesday, January 30, 2018 10:17 AM >>>> To: Kinney, Michael D <michael.d.kinney@intel.com>; >> edk2- >>>> devel-01 <edk2-devel@lists.01.org> >>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>>> <pbonzini@redhat.com>; Yao, Jiewen >>>> <jiewen.yao@intel.com>; Dong, Eric >> <eric.dong@intel.com> >>>> Subject: Re: [edk2] [PATCH 1/3] >>>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>>> SmmStartup() >>>> >>>> On 01/30/18 18:22, Kinney, Michael D wrote: >>>>> Laszlo, >>>>> >>>>> The DBs can be removed if the label is moved after >>>>> the instruction and the patch is done to the label >>>>> minus the size of the patch value. >>>> >>>> Indeed I haven't thought of this. >>>> >>>> If I understand correctly, it means >>>> >>>> extern UINT8 gSmmCr0; >>>> >>>> *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = >>>> (UINT32)AsmReadCr0 (); >>>> >>>> TBH, the DB feels less ugly to me than this :) >>>> >>>> Still, if you think it would be an acceptable price to >>>> pay for removing >>>> the remaining DBs, I can respin. >>>> >>>> Thanks >>>> Laszlo >>>> >>>>>> -----Original Message----- >>>>>> From: edk2-devel [mailto:edk2-devel- >>>> bounces@lists.01.org] >>>>>> On Behalf Of Laszlo Ersek >>>>>> Sent: Tuesday, January 30, 2018 7:34 AM >>>>>> To: edk2-devel-01 <edk2-devel@lists.01.org> >>>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen >>>>>> <jiewen.yao@intel.com>; Dong, Eric >>>> <eric.dong@intel.com>; >>>>>> Paolo Bonzini <pbonzini@redhat.com> >>>>>> Subject: [edk2] [PATCH 1/3] >> UefiCpuPkg/PiSmmCpuDxeSmm: >>>>>> update comments in IA32 SmmStartup() >>>>>> >>>>>> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global >>>>>> variables are used >>>>>> for patching assembly instructions, thus we can >> never >>>>>> remove the DB >>>>>> encodings for those instructions. At least we should >>>> add >>>>>> the intended >>>>>> meanings in comments. >>>>>> >>>>>> This patch only changes comments. >>>>>> >>>>>> Cc: Eric Dong <eric.dong@intel.com> >>>>>> Cc: Jian J Wang <jian.j.wang@intel.com> >>>>>> Cc: Jiewen Yao <jiewen.yao@intel.com> >>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com> >>>>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com> >>>>>> Contributed-under: TianoCore Contribution Agreement >>>> 1.1 >>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com> >>>>>> --- >>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 >> ++++- >>>> --- >>>>>> 1 file changed, 4 insertions(+), 4 deletions(-) >>>>>> >>>>>> diff --git >>>> a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>> index e96dd8d2392a..08534dba64b7 100644 >>>>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) >>>>>> ASM_PFX(SmmStartup): >>>>>> DB 0x66 >>>>>> mov eax, 0x80000001 ; read >>>>>> capability >>>>>> cpuid >>>>>> DB 0x66 >>>>>> mov ebx, edx ; rdmsr >> will >>>>>> change edx. keep it in ebx. >>>>>> - DB 0x66, 0xb8 >>>>>> + DB 0x66, 0xb8 ; mov eax, >>>> imm32 >>>>>> ASM_PFX(gSmmCr3): DD 0 >>>>>> mov cr3, eax >>>>>> DB 0x67, 0x66 >>>>>> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - >>>>>> ASM_PFX(SmmStartup))] >>>>>> - DB 0x66, 0xb8 >>>>>> + DB 0x66, 0xb8 ; mov eax, >>>> imm32 >>>>>> ASM_PFX(gSmmCr4): DD 0 >>>>>> mov cr4, eax >>>>>> DB 0x66 >>>>>> mov ecx, 0xc0000080 ; IA32_EFER >>>> MSR >>>>>> rdmsr >>>>>> DB 0x66 >>>>>> test ebx, BIT20 ; check NXE >>>>>> capability >>>>>> jz .1 >>>>>> or ah, BIT3 ; set NXE >> bit >>>>>> wrmsr >>>>>> .1: >>>>>> - DB 0x66, 0xb8 >>>>>> + DB 0x66, 0xb8 ; mov eax, >>>> imm32 >>>>>> ASM_PFX(gSmmCr0): DD 0 >>>>>> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, >>>>>> PROTECT_MODE_DS >>>>>> mov cr0, eax >>>>>> - DB 0x66, 0xea ; jmp far >>>>>> [ptr48] >>>>>> + DB 0x66, 0xea ; jmp far >>>>>> [ptr48] >>>>>> ASM_PFX(gSmmJmpAddr): >>>>>> DD @32bit >>>>>> DW PROTECT_MODE_CS >>>>>> @32bit: >>>>>> mov ds, edi >>>>>> mov es, edi >>>>>> -- >>>>>> 2.14.1.3.gb7cf6e02401b >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> 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 > -- Thanks, Ray ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-31 5:44 ` Ni, Ruiyu @ 2018-01-31 5:54 ` Ni, Ruiyu 2018-01-31 10:56 ` Laszlo Ersek 2018-01-31 10:42 ` Laszlo Ersek 1 sibling, 1 reply; 27+ messages in thread From: Ni, Ruiyu @ 2018-01-31 5:54 UTC (permalink / raw) To: Kinney, Michael D, Laszlo Ersek, edk2-devel-01 Cc: Paolo Bonzini, Yao, Jiewen, Dong, Eric On 1/31/2018 1:44 PM, Ni, Ruiyu wrote: > Mike, Laszlo, > Does the patch only apply to the operand? > If so, PatchAssembly looks too general. > How about the name like PatchAssemblyOperand? > > > On 1/31/2018 6:25 AM, Kinney, Michael D wrote: >> Laszlo, >> >> I agree that the function is better than a macro. >> >> I thought of the alignment issues as well. CopyMem() >> is a good solution. We could also consider >> WriteUnalignedxx() functions in BaseLib. >> >> I was originally thinking this functionality would go >> into BaseLib. But with the use of CopyMem(), we can't >> do that. Maybe we should use WriteUnalignedxx() and >> add some ASSERT() checks. >> >> VOID >> PatchAssembly ( >> VOID *BufferEnd, >> UINT64 PatchValue, >> UINTN ValueSize >> ) >> { >> ASSERT ((UINTN)BufferEnd > ValueSize); >> switch (ValueSize) { >> case 1: >> ASSERT (PatchValue <= MAX_UINT8); >> *((UINT8 *)BufferEnd - 1) = (UINT8)PatchValue; >> case 2: >> ASSERT (PatchValue <= MAX_UINT16); >> WriteUnaligned16 ((UINT16 *)(BufferEnd) - 1, (UINT16)PatchValue)); >> break; >> case 4: >> ASSERT (PatchValue <= MAX_UINT32); >> WriteUnaligned32 ((UINT32 *)(BufferEnd) - 1, (UINT32)PatchValue)); >> break; >> case 8: >> WriteUnaligned64 ((UINT64 *)(BufferEnd) - 1, PatchValue)); >> break; >> default: >> ASSERT (FALSE); >> } >> } >> >> Mike >> >>> -----Original Message----- >>> From: Laszlo Ersek [mailto:lersek@redhat.com] >>> Sent: Tuesday, January 30, 2018 1:45 PM >>> To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2- >>> devel-01 <edk2-devel@lists.01.org> >>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>> <pbonzini@redhat.com>; Yao, Jiewen >>> <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> >>> Subject: Re: [edk2] [PATCH 1/3] >>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>> SmmStartup() >>> >>> On 01/30/18 21:31, Kinney, Michael D wrote: >>>> Laszlo, >>>> >>>> We have already used this technique in other NASM files >>>> to remove DBs. >>> >>> OK. >>> >>>> Let us know if you have suggestions on how to make the >>>> C code that performs the patches easier to read and >>>> maintain. >>> >>> How about this: >>> >>> VOID >>> PatchAssembly ( >>> VOID *BufferEnd, >>> UINT64 PatchValue, >>> UINTN ValueSize >>> ) >>> { >>> CopyMem ( >>> (VOID *)((UINTN)BufferEnd - ValueSize), >>> &PatchValue, >>> ValueSize >>> ); >>> } >>> >>> extern UINT8 gAsmSmmCr0; >>> extern UINT8 gAsmSmmCr3; >>> extern UINT8 gAsmSmmCr4; >>> >>> ... >>> { >>> PatchAssembly (&gAsmSmmCr0, AsmReadCr0 (), 4); >>> PatchAssembly (&gAsmSmmCr3, AsmReadCr3 (), 4); >>> PatchAssembly (&gAsmSmmCr4, AsmReadCr4 (), 4); >>> ... >>> } >>> >>> (I think it's fine to open-code the last argument as "4", >>> rather than >>> "sizeof (UINT32)", because for patching, we must have >>> intimate knowledge >>> of the instruction anyway.) >>> >>> To me, this is easier to read, because: >>> >>> - there are no complex casts in the "business logic" >>> - the size is spelled out once per patching >>> - the function name and the variable names make it clear >>> we are patching >>> separately compiled assembly code that was linked into >>> the same >>> module. >>> >>> What do you think? >>> >>> Thanks! >>> Laszlo >>> >>>>> -----Original Message----- >>>>> From: edk2-devel [mailto:edk2-devel- >>> bounces@lists.01.org] >>>>> On Behalf Of Laszlo Ersek >>>>> Sent: Tuesday, January 30, 2018 10:17 AM >>>>> To: Kinney, Michael D <michael.d.kinney@intel.com>; >>> edk2- >>>>> devel-01 <edk2-devel@lists.01.org> >>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>>>> <pbonzini@redhat.com>; Yao, Jiewen >>>>> <jiewen.yao@intel.com>; Dong, Eric >>> <eric.dong@intel.com> >>>>> Subject: Re: [edk2] [PATCH 1/3] >>>>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>>>> SmmStartup() >>>>> >>>>> On 01/30/18 18:22, Kinney, Michael D wrote: >>>>>> Laszlo, >>>>>> >>>>>> The DBs can be removed if the label is moved after >>>>>> the instruction and the patch is done to the label >>>>>> minus the size of the patch value. >>>>> >>>>> Indeed I haven't thought of this. >>>>> >>>>> If I understand correctly, it means >>>>> >>>>> extern UINT8 gSmmCr0; >>>>> >>>>> *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = >>>>> (UINT32)AsmReadCr0 (); >>>>> >>>>> TBH, the DB feels less ugly to me than this :) >>>>> >>>>> Still, if you think it would be an acceptable price to >>>>> pay for removing >>>>> the remaining DBs, I can respin. >>>>> >>>>> Thanks >>>>> Laszlo >>>>> >>>>>>> -----Original Message----- >>>>>>> From: edk2-devel [mailto:edk2-devel- >>>>> bounces@lists.01.org] >>>>>>> On Behalf Of Laszlo Ersek >>>>>>> Sent: Tuesday, January 30, 2018 7:34 AM >>>>>>> To: edk2-devel-01 <edk2-devel@lists.01.org> >>>>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen >>>>>>> <jiewen.yao@intel.com>; Dong, Eric >>>>> <eric.dong@intel.com>; >>>>>>> Paolo Bonzini <pbonzini@redhat.com> >>>>>>> Subject: [edk2] [PATCH 1/3] >>> UefiCpuPkg/PiSmmCpuDxeSmm: >>>>>>> update comments in IA32 SmmStartup() >>>>>>> >>>>>>> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global >>>>>>> variables are used >>>>>>> for patching assembly instructions, thus we can >>> never >>>>>>> remove the DB >>>>>>> encodings for those instructions. At least we should >>>>> add >>>>>>> the intended >>>>>>> meanings in comments. >>>>>>> >>>>>>> This patch only changes comments. >>>>>>> >>>>>>> Cc: Eric Dong <eric.dong@intel.com> >>>>>>> Cc: Jian J Wang <jian.j.wang@intel.com> >>>>>>> Cc: Jiewen Yao <jiewen.yao@intel.com> >>>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com> >>>>>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com> >>>>>>> Contributed-under: TianoCore Contribution Agreement >>>>> 1.1 >>>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com> >>>>>>> --- >>>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 >>> ++++- >>>>> --- >>>>>>> 1 file changed, 4 insertions(+), 4 deletions(-) >>>>>>> >>>>>>> diff --git >>>>> a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> index e96dd8d2392a..08534dba64b7 100644 >>>>>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) >>>>>>> ASM_PFX(SmmStartup): >>>>>>> DB 0x66 >>>>>>> mov eax, 0x80000001 ; read >>>>>>> capability >>>>>>> cpuid >>>>>>> DB 0x66 >>>>>>> mov ebx, edx ; rdmsr >>> will >>>>>>> change edx. keep it in ebx. >>>>>>> - DB 0x66, 0xb8 >>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>> imm32 >>>>>>> ASM_PFX(gSmmCr3): DD 0 >>>>>>> mov cr3, eax >>>>>>> DB 0x67, 0x66 >>>>>>> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - >>>>>>> ASM_PFX(SmmStartup))] >>>>>>> - DB 0x66, 0xb8 >>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>> imm32 >>>>>>> ASM_PFX(gSmmCr4): DD 0 >>>>>>> mov cr4, eax >>>>>>> DB 0x66 >>>>>>> mov ecx, 0xc0000080 ; IA32_EFER >>>>> MSR >>>>>>> rdmsr >>>>>>> DB 0x66 >>>>>>> test ebx, BIT20 ; check NXE >>>>>>> capability >>>>>>> jz .1 >>>>>>> or ah, BIT3 ; set NXE >>> bit >>>>>>> wrmsr >>>>>>> .1: >>>>>>> - DB 0x66, 0xb8 >>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>> imm32 >>>>>>> ASM_PFX(gSmmCr0): DD 0 >>>>>>> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, >>>>>>> PROTECT_MODE_DS >>>>>>> mov cr0, eax >>>>>>> - DB 0x66, 0xea ; jmp far >>>>>>> [ptr48] >>>>>>> + DB 0x66, 0xea ; jmp far >>>>>>> [ptr48] >>>>>>> ASM_PFX(gSmmJmpAddr): >>>>>>> DD @32bit >>>>>>> DW PROTECT_MODE_CS >>>>>>> @32bit: >>>>>>> mov ds, edi >>>>>>> mov es, edi >>>>>>> -- >>>>>>> 2.14.1.3.gb7cf6e02401b >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> 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 >> > > Laszlo, Mike, Considering this patch doesn't make the code worse, actually improved a tiny bit, can we firstly check in the three patches? Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com> -- Thanks, Ray ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-31 5:54 ` Ni, Ruiyu @ 2018-01-31 10:56 ` Laszlo Ersek 0 siblings, 0 replies; 27+ messages in thread From: Laszlo Ersek @ 2018-01-31 10:56 UTC (permalink / raw) To: Ni, Ruiyu, Kinney, Michael D, edk2-devel-01 Cc: Paolo Bonzini, Yao, Jiewen, Dong, Eric On 01/31/18 06:54, Ni, Ruiyu wrote: > Laszlo, Mike, > Considering this patch doesn't make the code worse, > actually improved a tiny bit, can we firstly check in the three patches? I agree; the PatchAssembly() discussion is taking quite a bit of thought, meanwhile IA32 SMM is broken on KVM -- and even on QEMU! (Paolo helped me test that, and yes, QEMU/TCG is affected the exact same way.) I will go ahead and push the patches with the reviews from Paolo and Ray, with the following small modifications: * In the commit message of the first patch, I'll change we can never remove to we can't yet remove in the commit message. * In the third patch, I will change the commit message from SMM emulation under KVM to SMM emulation under both KVM and QEMU (TCG) * In the third patch, I will update the code comments as requested by Ray. > Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com> Thanks! Laszlo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-31 5:44 ` Ni, Ruiyu 2018-01-31 5:54 ` Ni, Ruiyu @ 2018-01-31 10:42 ` Laszlo Ersek 1 sibling, 0 replies; 27+ messages in thread From: Laszlo Ersek @ 2018-01-31 10:42 UTC (permalink / raw) To: Ni, Ruiyu, Kinney, Michael D, edk2-devel-01 Cc: Paolo Bonzini, Yao, Jiewen, Dong, Eric On 01/31/18 06:44, Ni, Ruiyu wrote: > Mike, Laszlo, > Does the patch only apply to the operand? > If so, PatchAssembly looks too general. > How about the name like PatchAssemblyOperand? Originally I meant to call the function "PatchInstruction", but then I thought it could be used for patching any other artifacts too, in object code that comes from NASM. I'm also fine calling it PatchAssemblyOperand, or even PatchInstructionTrailingOperand :) Thanks Laszlo > On 1/31/2018 6:25 AM, Kinney, Michael D wrote: >> Laszlo, >> >> I agree that the function is better than a macro. >> >> I thought of the alignment issues as well. CopyMem() >> is a good solution. We could also consider >> WriteUnalignedxx() functions in BaseLib. >> >> I was originally thinking this functionality would go >> into BaseLib. But with the use of CopyMem(), we can't >> do that. Maybe we should use WriteUnalignedxx() and >> add some ASSERT() checks. >> >> VOID >> PatchAssembly ( >> VOID *BufferEnd, >> UINT64 PatchValue, >> UINTN ValueSize >> ) >> { >> ASSERT ((UINTN)BufferEnd > ValueSize); >> switch (ValueSize) { >> case 1: >> ASSERT (PatchValue <= MAX_UINT8); >> *((UINT8 *)BufferEnd - 1) = (UINT8)PatchValue; >> case 2: >> ASSERT (PatchValue <= MAX_UINT16); >> WriteUnaligned16 ((UINT16 *)(BufferEnd) - 1, (UINT16)PatchValue)); >> break; >> case 4: >> ASSERT (PatchValue <= MAX_UINT32); >> WriteUnaligned32 ((UINT32 *)(BufferEnd) - 1, (UINT32)PatchValue)); >> break; >> case 8: >> WriteUnaligned64 ((UINT64 *)(BufferEnd) - 1, PatchValue)); >> break; >> default: >> ASSERT (FALSE); >> } >> } >> >> Mike >> >>> -----Original Message----- >>> From: Laszlo Ersek [mailto:lersek@redhat.com] >>> Sent: Tuesday, January 30, 2018 1:45 PM >>> To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2- >>> devel-01 <edk2-devel@lists.01.org> >>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>> <pbonzini@redhat.com>; Yao, Jiewen >>> <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> >>> Subject: Re: [edk2] [PATCH 1/3] >>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>> SmmStartup() >>> >>> On 01/30/18 21:31, Kinney, Michael D wrote: >>>> Laszlo, >>>> >>>> We have already used this technique in other NASM files >>>> to remove DBs. >>> >>> OK. >>> >>>> Let us know if you have suggestions on how to make the >>>> C code that performs the patches easier to read and >>>> maintain. >>> >>> How about this: >>> >>> VOID >>> PatchAssembly ( >>> VOID *BufferEnd, >>> UINT64 PatchValue, >>> UINTN ValueSize >>> ) >>> { >>> CopyMem ( >>> (VOID *)((UINTN)BufferEnd - ValueSize), >>> &PatchValue, >>> ValueSize >>> ); >>> } >>> >>> extern UINT8 gAsmSmmCr0; >>> extern UINT8 gAsmSmmCr3; >>> extern UINT8 gAsmSmmCr4; >>> >>> ... >>> { >>> PatchAssembly (&gAsmSmmCr0, AsmReadCr0 (), 4); >>> PatchAssembly (&gAsmSmmCr3, AsmReadCr3 (), 4); >>> PatchAssembly (&gAsmSmmCr4, AsmReadCr4 (), 4); >>> ... >>> } >>> >>> (I think it's fine to open-code the last argument as "4", >>> rather than >>> "sizeof (UINT32)", because for patching, we must have >>> intimate knowledge >>> of the instruction anyway.) >>> >>> To me, this is easier to read, because: >>> >>> - there are no complex casts in the "business logic" >>> - the size is spelled out once per patching >>> - the function name and the variable names make it clear >>> we are patching >>> separately compiled assembly code that was linked into >>> the same >>> module. >>> >>> What do you think? >>> >>> Thanks! >>> Laszlo >>> >>>>> -----Original Message----- >>>>> From: edk2-devel [mailto:edk2-devel- >>> bounces@lists.01.org] >>>>> On Behalf Of Laszlo Ersek >>>>> Sent: Tuesday, January 30, 2018 10:17 AM >>>>> To: Kinney, Michael D <michael.d.kinney@intel.com>; >>> edk2- >>>>> devel-01 <edk2-devel@lists.01.org> >>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>>>> <pbonzini@redhat.com>; Yao, Jiewen >>>>> <jiewen.yao@intel.com>; Dong, Eric >>> <eric.dong@intel.com> >>>>> Subject: Re: [edk2] [PATCH 1/3] >>>>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>>>> SmmStartup() >>>>> >>>>> On 01/30/18 18:22, Kinney, Michael D wrote: >>>>>> Laszlo, >>>>>> >>>>>> The DBs can be removed if the label is moved after >>>>>> the instruction and the patch is done to the label >>>>>> minus the size of the patch value. >>>>> >>>>> Indeed I haven't thought of this. >>>>> >>>>> If I understand correctly, it means >>>>> >>>>> extern UINT8 gSmmCr0; >>>>> >>>>> *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = >>>>> (UINT32)AsmReadCr0 (); >>>>> >>>>> TBH, the DB feels less ugly to me than this :) >>>>> >>>>> Still, if you think it would be an acceptable price to >>>>> pay for removing >>>>> the remaining DBs, I can respin. >>>>> >>>>> Thanks >>>>> Laszlo >>>>> >>>>>>> -----Original Message----- >>>>>>> From: edk2-devel [mailto:edk2-devel- >>>>> bounces@lists.01.org] >>>>>>> On Behalf Of Laszlo Ersek >>>>>>> Sent: Tuesday, January 30, 2018 7:34 AM >>>>>>> To: edk2-devel-01 <edk2-devel@lists.01.org> >>>>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen >>>>>>> <jiewen.yao@intel.com>; Dong, Eric >>>>> <eric.dong@intel.com>; >>>>>>> Paolo Bonzini <pbonzini@redhat.com> >>>>>>> Subject: [edk2] [PATCH 1/3] >>> UefiCpuPkg/PiSmmCpuDxeSmm: >>>>>>> update comments in IA32 SmmStartup() >>>>>>> >>>>>>> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global >>>>>>> variables are used >>>>>>> for patching assembly instructions, thus we can >>> never >>>>>>> remove the DB >>>>>>> encodings for those instructions. At least we should >>>>> add >>>>>>> the intended >>>>>>> meanings in comments. >>>>>>> >>>>>>> This patch only changes comments. >>>>>>> >>>>>>> Cc: Eric Dong <eric.dong@intel.com> >>>>>>> Cc: Jian J Wang <jian.j.wang@intel.com> >>>>>>> Cc: Jiewen Yao <jiewen.yao@intel.com> >>>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com> >>>>>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com> >>>>>>> Contributed-under: TianoCore Contribution Agreement >>>>> 1.1 >>>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com> >>>>>>> --- >>>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 >>> ++++- >>>>> --- >>>>>>> 1 file changed, 4 insertions(+), 4 deletions(-) >>>>>>> >>>>>>> diff --git >>>>> a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> index e96dd8d2392a..08534dba64b7 100644 >>>>>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) >>>>>>> ASM_PFX(SmmStartup): >>>>>>> DB 0x66 >>>>>>> mov eax, 0x80000001 ; read >>>>>>> capability >>>>>>> cpuid >>>>>>> DB 0x66 >>>>>>> mov ebx, edx ; rdmsr >>> will >>>>>>> change edx. keep it in ebx. >>>>>>> - DB 0x66, 0xb8 >>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>> imm32 >>>>>>> ASM_PFX(gSmmCr3): DD 0 >>>>>>> mov cr3, eax >>>>>>> DB 0x67, 0x66 >>>>>>> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - >>>>>>> ASM_PFX(SmmStartup))] >>>>>>> - DB 0x66, 0xb8 >>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>> imm32 >>>>>>> ASM_PFX(gSmmCr4): DD 0 >>>>>>> mov cr4, eax >>>>>>> DB 0x66 >>>>>>> mov ecx, 0xc0000080 ; IA32_EFER >>>>> MSR >>>>>>> rdmsr >>>>>>> DB 0x66 >>>>>>> test ebx, BIT20 ; check NXE >>>>>>> capability >>>>>>> jz .1 >>>>>>> or ah, BIT3 ; set NXE >>> bit >>>>>>> wrmsr >>>>>>> .1: >>>>>>> - DB 0x66, 0xb8 >>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>> imm32 >>>>>>> ASM_PFX(gSmmCr0): DD 0 >>>>>>> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, >>>>>>> PROTECT_MODE_DS >>>>>>> mov cr0, eax >>>>>>> - DB 0x66, 0xea ; jmp far >>>>>>> [ptr48] >>>>>>> + DB 0x66, 0xea ; jmp far >>>>>>> [ptr48] >>>>>>> ASM_PFX(gSmmJmpAddr): >>>>>>> DD @32bit >>>>>>> DW PROTECT_MODE_CS >>>>>>> @32bit: >>>>>>> mov ds, edi >>>>>>> mov es, edi >>>>>>> -- >>>>>>> 2.14.1.3.gb7cf6e02401b >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> 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 >> > > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-30 22:25 ` Kinney, Michael D 2018-01-31 5:44 ` Ni, Ruiyu @ 2018-01-31 10:40 ` Laszlo Ersek 2018-01-31 22:11 ` Kinney, Michael D 2018-02-02 10:06 ` Ard Biesheuvel 1 sibling, 2 replies; 27+ messages in thread From: Laszlo Ersek @ 2018-01-31 10:40 UTC (permalink / raw) To: Kinney, Michael D, edk2-devel-01 Cc: Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric, Ard Biesheuvel, Leif Lindholm (Linaro address) On 01/30/18 23:25, Kinney, Michael D wrote: > Laszlo, > > I agree that the function is better than a macro. > > I thought of the alignment issues as well. CopyMem() > is a good solution. We could also consider > WriteUnalignedxx() functions in BaseLib. IMO, the WriteUnalignedxx functions are a bit pointless in the exact form they are declared (this was discussed earlier esp. with regard to aarch64). The functions take pointers to objects that already have the target type, such as UINT32 EFIAPI WriteUnaligned32 ( OUT UINT32 *Buffer, IN UINT32 Value ) Here the type of Buffer should be (VOID *), not (UINT32 *). Otherwise, the undefined behavior (due to mis-alignment) surfaces as soon as the function is called with an unaligned pointer (i.e. before the target area is actually written). > I was originally thinking this functionality would go > into BaseLib. But with the use of CopyMem(), we can't > do that. Can we put it in BaseMemoryLib instead (which is where CopyMem() is from)? That library class is still low-level enough. And, while I count 9 library instances, PatchAssembly() is not a large function, we could tolerate adding it to all 9 instances, identically. Let me also ask the opposite question: should we perhaps make the PatchAssembly() API *less* abstract? (Also suggested by your naming of the macro, PATCH_X86_ASM.) If the instruction encoding on e.g. AARCH64 doesn't lend itself to such patching (= expressed through the address right after the instruction), then even BaseMemoryLib may be too generic for the API. > Maybe we should use WriteUnalignedxx() and > add some ASSERT() checks. > > VOID > PatchAssembly ( > VOID *BufferEnd, > UINT64 PatchValue, > UINTN ValueSize > ) > { > ASSERT ((UINTN)BufferEnd > ValueSize); > switch (ValueSize) { > case 1: > ASSERT (PatchValue <= MAX_UINT8); > *((UINT8 *)BufferEnd - 1) = (UINT8)PatchValue; > case 2: > ASSERT (PatchValue <= MAX_UINT16); > WriteUnaligned16 ((UINT16 *)(BufferEnd) - 1, (UINT16)PatchValue)); > break; > case 4: > ASSERT (PatchValue <= MAX_UINT32); > WriteUnaligned32 ((UINT32 *)(BufferEnd) - 1, (UINT32)PatchValue)); > break; > case 8: > WriteUnaligned64 ((UINT64 *)(BufferEnd) - 1, PatchValue)); > break; > default: > ASSERT (FALSE); > } > } In my opinion: - If Ard and Leif say that PatchAssembly() API makes sense for AARCH64, then I think we can go with the above generic implementation (for BaseLib). - If Ard and Leif say the API is only useful on x86, then I suggest that we implement the API separately for all arches (still in BaseLib): - On x86, we should simply open-code the unaligned accesses (like you originall suggested). The pointer arithmetic will look a bit wild, but it's safely hidden behind a BaseLib API, so client code will look nice. - On all other arches, we should implement the function with ASSERT(FALSE). Thanks! Laszlo > > Mike > >> -----Original Message----- >> From: Laszlo Ersek [mailto:lersek@redhat.com] >> Sent: Tuesday, January 30, 2018 1:45 PM >> To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2- >> devel-01 <edk2-devel@lists.01.org> >> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >> <pbonzini@redhat.com>; Yao, Jiewen >> <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> >> Subject: Re: [edk2] [PATCH 1/3] >> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >> SmmStartup() >> >> On 01/30/18 21:31, Kinney, Michael D wrote: >>> Laszlo, >>> >>> We have already used this technique in other NASM files >>> to remove DBs. >> >> OK. >> >>> Let us know if you have suggestions on how to make the >>> C code that performs the patches easier to read and >>> maintain. >> >> How about this: >> >> VOID >> PatchAssembly ( >> VOID *BufferEnd, >> UINT64 PatchValue, >> UINTN ValueSize >> ) >> { >> CopyMem ( >> (VOID *)((UINTN)BufferEnd - ValueSize), >> &PatchValue, >> ValueSize >> ); >> } >> >> extern UINT8 gAsmSmmCr0; >> extern UINT8 gAsmSmmCr3; >> extern UINT8 gAsmSmmCr4; >> >> ... >> { >> PatchAssembly (&gAsmSmmCr0, AsmReadCr0 (), 4); >> PatchAssembly (&gAsmSmmCr3, AsmReadCr3 (), 4); >> PatchAssembly (&gAsmSmmCr4, AsmReadCr4 (), 4); >> ... >> } >> >> (I think it's fine to open-code the last argument as "4", >> rather than >> "sizeof (UINT32)", because for patching, we must have >> intimate knowledge >> of the instruction anyway.) >> >> To me, this is easier to read, because: >> >> - there are no complex casts in the "business logic" >> - the size is spelled out once per patching >> - the function name and the variable names make it clear >> we are patching >> separately compiled assembly code that was linked into >> the same >> module. >> >> What do you think? >> >> Thanks! >> Laszlo >> >>>> -----Original Message----- >>>> From: edk2-devel [mailto:edk2-devel- >> bounces@lists.01.org] >>>> On Behalf Of Laszlo Ersek >>>> Sent: Tuesday, January 30, 2018 10:17 AM >>>> To: Kinney, Michael D <michael.d.kinney@intel.com>; >> edk2- >>>> devel-01 <edk2-devel@lists.01.org> >>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>>> <pbonzini@redhat.com>; Yao, Jiewen >>>> <jiewen.yao@intel.com>; Dong, Eric >> <eric.dong@intel.com> >>>> Subject: Re: [edk2] [PATCH 1/3] >>>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>>> SmmStartup() >>>> >>>> On 01/30/18 18:22, Kinney, Michael D wrote: >>>>> Laszlo, >>>>> >>>>> The DBs can be removed if the label is moved after >>>>> the instruction and the patch is done to the label >>>>> minus the size of the patch value. >>>> >>>> Indeed I haven't thought of this. >>>> >>>> If I understand correctly, it means >>>> >>>> extern UINT8 gSmmCr0; >>>> >>>> *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = >>>> (UINT32)AsmReadCr0 (); >>>> >>>> TBH, the DB feels less ugly to me than this :) >>>> >>>> Still, if you think it would be an acceptable price to >>>> pay for removing >>>> the remaining DBs, I can respin. >>>> >>>> Thanks >>>> Laszlo >>>> >>>>>> -----Original Message----- >>>>>> From: edk2-devel [mailto:edk2-devel- >>>> bounces@lists.01.org] >>>>>> On Behalf Of Laszlo Ersek >>>>>> Sent: Tuesday, January 30, 2018 7:34 AM >>>>>> To: edk2-devel-01 <edk2-devel@lists.01.org> >>>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen >>>>>> <jiewen.yao@intel.com>; Dong, Eric >>>> <eric.dong@intel.com>; >>>>>> Paolo Bonzini <pbonzini@redhat.com> >>>>>> Subject: [edk2] [PATCH 1/3] >> UefiCpuPkg/PiSmmCpuDxeSmm: >>>>>> update comments in IA32 SmmStartup() >>>>>> >>>>>> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global >>>>>> variables are used >>>>>> for patching assembly instructions, thus we can >> never >>>>>> remove the DB >>>>>> encodings for those instructions. At least we should >>>> add >>>>>> the intended >>>>>> meanings in comments. >>>>>> >>>>>> This patch only changes comments. >>>>>> >>>>>> Cc: Eric Dong <eric.dong@intel.com> >>>>>> Cc: Jian J Wang <jian.j.wang@intel.com> >>>>>> Cc: Jiewen Yao <jiewen.yao@intel.com> >>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com> >>>>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com> >>>>>> Contributed-under: TianoCore Contribution Agreement >>>> 1.1 >>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com> >>>>>> --- >>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 >> ++++- >>>> --- >>>>>> 1 file changed, 4 insertions(+), 4 deletions(-) >>>>>> >>>>>> diff --git >>>> a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>> index e96dd8d2392a..08534dba64b7 100644 >>>>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) >>>>>> ASM_PFX(SmmStartup): >>>>>> DB 0x66 >>>>>> mov eax, 0x80000001 ; read >>>>>> capability >>>>>> cpuid >>>>>> DB 0x66 >>>>>> mov ebx, edx ; rdmsr >> will >>>>>> change edx. keep it in ebx. >>>>>> - DB 0x66, 0xb8 >>>>>> + DB 0x66, 0xb8 ; mov eax, >>>> imm32 >>>>>> ASM_PFX(gSmmCr3): DD 0 >>>>>> mov cr3, eax >>>>>> DB 0x67, 0x66 >>>>>> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - >>>>>> ASM_PFX(SmmStartup))] >>>>>> - DB 0x66, 0xb8 >>>>>> + DB 0x66, 0xb8 ; mov eax, >>>> imm32 >>>>>> ASM_PFX(gSmmCr4): DD 0 >>>>>> mov cr4, eax >>>>>> DB 0x66 >>>>>> mov ecx, 0xc0000080 ; IA32_EFER >>>> MSR >>>>>> rdmsr >>>>>> DB 0x66 >>>>>> test ebx, BIT20 ; check NXE >>>>>> capability >>>>>> jz .1 >>>>>> or ah, BIT3 ; set NXE >> bit >>>>>> wrmsr >>>>>> .1: >>>>>> - DB 0x66, 0xb8 >>>>>> + DB 0x66, 0xb8 ; mov eax, >>>> imm32 >>>>>> ASM_PFX(gSmmCr0): DD 0 >>>>>> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, >>>>>> PROTECT_MODE_DS >>>>>> mov cr0, eax >>>>>> - DB 0x66, 0xea ; jmp far >>>>>> [ptr48] >>>>>> + DB 0x66, 0xea ; jmp far >>>>>> [ptr48] >>>>>> ASM_PFX(gSmmJmpAddr): >>>>>> DD @32bit >>>>>> DW PROTECT_MODE_CS >>>>>> @32bit: >>>>>> mov ds, edi >>>>>> mov es, edi >>>>>> -- >>>>>> 2.14.1.3.gb7cf6e02401b >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> 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 > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-31 10:40 ` Laszlo Ersek @ 2018-01-31 22:11 ` Kinney, Michael D 2018-02-02 6:05 ` Laszlo Ersek 2018-02-02 10:06 ` Ard Biesheuvel 1 sibling, 1 reply; 27+ messages in thread From: Kinney, Michael D @ 2018-01-31 22:11 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01, Kinney, Michael D Cc: Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric, Ard Biesheuvel, Leif Lindholm (Linaro address) Laszlo, I agree the Unaligned functions have issues. We should see if we could change the param type. It should be a backwards compatible change to go from a type specific pointer to VOID *. But need to check with all supported compilers. We can have arch specific functions and macros. There are many in BaseLib.h. This way, if a macro or function is used by an unsupported arch, the build will fail. I also like some of the name change suggestions. Maybe PatchInstructionX86() and change the parameter name to InstructionEnd. BaseLib.h ========== #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) VOID EFIAPI PatchInstructionX86 ( VOID *InstructionEnd, UINT64 PatchValue, UINTN ValueSize ); #endif BaseLib Instance ========== VOID EFIAPI PatchInstructionX86 ( VOID *InstructionEnd, UINT64 PatchValue, UINTN ValueSize ) { ASSERT ((UINTN)InstructionEnd > ValueSize); switch (ValueSize) { case 1: ASSERT (PatchValue <= MAX_UINT8); *((UINT8 *)InstructionEnd - 1) = (UINT8)PatchValue; case 2: ASSERT (PatchValue <= MAX_UINT16); WriteUnaligned16 ((UINT16 *)(InstructionEnd) - 1, (UINT16)PatchValue)); break; case 4: ASSERT (PatchValue <= MAX_UINT32); WriteUnaligned32 ((UINT32 *)(InstructionEnd) - 1, (UINT32)PatchValue)); break; case 8: WriteUnaligned64 ((UINT64 *)(InstructionEnd) - 1, PatchValue)); break; default: ASSERT (FALSE); } } Mike > -----Original Message----- > From: Laszlo Ersek [mailto:lersek@redhat.com] > Sent: Wednesday, January 31, 2018 2:40 AM > To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2- > devel-01 <edk2-devel@lists.01.org> > Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini > <pbonzini@redhat.com>; Yao, Jiewen > <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com>; > Ard Biesheuvel <ard.biesheuvel@linaro.org>; Leif Lindholm > (Linaro address) <leif.lindholm@linaro.org> > Subject: Re: [edk2] [PATCH 1/3] > UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 > SmmStartup() > > On 01/30/18 23:25, Kinney, Michael D wrote: > > Laszlo, > > > > I agree that the function is better than a macro. > > > > I thought of the alignment issues as well. CopyMem() > > is a good solution. We could also consider > > WriteUnalignedxx() functions in BaseLib. > > IMO, the WriteUnalignedxx functions are a bit pointless > in the exact > form they are declared (this was discussed earlier esp. > with regard to > aarch64). The functions take pointers to objects that > already have the > target type, such as > > UINT32 > EFIAPI > WriteUnaligned32 ( > OUT UINT32 *Buffer, > IN UINT32 Value > ) > > Here the type of Buffer should be (VOID *), not (UINT32 > *). Otherwise, > the undefined behavior (due to mis-alignment) surfaces as > soon as the > function is called with an unaligned pointer (i.e. before > the target > area is actually written). > > > I was originally thinking this functionality would go > > into BaseLib. But with the use of CopyMem(), we can't > > do that. > > Can we put it in BaseMemoryLib instead (which is where > CopyMem() is > from)? That library class is still low-level enough. And, > while I count > 9 library instances, PatchAssembly() is not a large > function, we could > tolerate adding it to all 9 instances, identically. > > Let me also ask the opposite question: should we perhaps > make the > PatchAssembly() API *less* abstract? (Also suggested by > your naming of > the macro, PATCH_X86_ASM.) If the instruction encoding on > e.g. AARCH64 > doesn't lend itself to such patching (= expressed through > the address > right after the instruction), then even BaseMemoryLib may > be too generic > for the API. > > > Maybe we should use WriteUnalignedxx() and > > add some ASSERT() checks. > > > > VOID > > PatchAssembly ( > > VOID *BufferEnd, > > UINT64 PatchValue, > > UINTN ValueSize > > ) > > { > > ASSERT ((UINTN)BufferEnd > ValueSize); > > switch (ValueSize) { > > case 1: > > ASSERT (PatchValue <= MAX_UINT8); > > *((UINT8 *)BufferEnd - 1) = (UINT8)PatchValue; > > case 2: > > ASSERT (PatchValue <= MAX_UINT16); > > WriteUnaligned16 ((UINT16 *)(BufferEnd) - 1, > (UINT16)PatchValue)); > > break; > > case 4: > > ASSERT (PatchValue <= MAX_UINT32); > > WriteUnaligned32 ((UINT32 *)(BufferEnd) - 1, > (UINT32)PatchValue)); > > break; > > case 8: > > WriteUnaligned64 ((UINT64 *)(BufferEnd) - 1, > PatchValue)); > > break; > > default: > > ASSERT (FALSE); > > } > > } > > In my opinion: > > - If Ard and Leif say that PatchAssembly() API makes > sense for AARCH64, > then I think we can go with the above generic > implementation (for > BaseLib). > > - If Ard and Leif say the API is only useful on x86, then > I suggest that > we implement the API separately for all arches (still > in BaseLib): > > - On x86, we should simply open-code the unaligned > accesses (like you > originall suggested). The pointer arithmetic will > look a bit wild, > but it's safely hidden behind a BaseLib API, so > client code will > look nice. > > - On all other arches, we should implement the function > with > ASSERT(FALSE). > > Thanks! > Laszlo > > > > > Mike > > > >> -----Original Message----- > >> From: Laszlo Ersek [mailto:lersek@redhat.com] > >> Sent: Tuesday, January 30, 2018 1:45 PM > >> To: Kinney, Michael D <michael.d.kinney@intel.com>; > edk2- > >> devel-01 <edk2-devel@lists.01.org> > >> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini > >> <pbonzini@redhat.com>; Yao, Jiewen > >> <jiewen.yao@intel.com>; Dong, Eric > <eric.dong@intel.com> > >> Subject: Re: [edk2] [PATCH 1/3] > >> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 > >> SmmStartup() > >> > >> On 01/30/18 21:31, Kinney, Michael D wrote: > >>> Laszlo, > >>> > >>> We have already used this technique in other NASM > files > >>> to remove DBs. > >> > >> OK. > >> > >>> Let us know if you have suggestions on how to make > the > >>> C code that performs the patches easier to read and > >>> maintain. > >> > >> How about this: > >> > >> VOID > >> PatchAssembly ( > >> VOID *BufferEnd, > >> UINT64 PatchValue, > >> UINTN ValueSize > >> ) > >> { > >> CopyMem ( > >> (VOID *)((UINTN)BufferEnd - ValueSize), > >> &PatchValue, > >> ValueSize > >> ); > >> } > >> > >> extern UINT8 gAsmSmmCr0; > >> extern UINT8 gAsmSmmCr3; > >> extern UINT8 gAsmSmmCr4; > >> > >> ... > >> { > >> PatchAssembly (&gAsmSmmCr0, AsmReadCr0 (), 4); > >> PatchAssembly (&gAsmSmmCr3, AsmReadCr3 (), 4); > >> PatchAssembly (&gAsmSmmCr4, AsmReadCr4 (), 4); > >> ... > >> } > >> > >> (I think it's fine to open-code the last argument as > "4", > >> rather than > >> "sizeof (UINT32)", because for patching, we must have > >> intimate knowledge > >> of the instruction anyway.) > >> > >> To me, this is easier to read, because: > >> > >> - there are no complex casts in the "business logic" > >> - the size is spelled out once per patching > >> - the function name and the variable names make it > clear > >> we are patching > >> separately compiled assembly code that was linked > into > >> the same > >> module. > >> > >> What do you think? > >> > >> Thanks! > >> Laszlo > >> > >>>> -----Original Message----- > >>>> From: edk2-devel [mailto:edk2-devel- > >> bounces@lists.01.org] > >>>> On Behalf Of Laszlo Ersek > >>>> Sent: Tuesday, January 30, 2018 10:17 AM > >>>> To: Kinney, Michael D <michael.d.kinney@intel.com>; > >> edk2- > >>>> devel-01 <edk2-devel@lists.01.org> > >>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini > >>>> <pbonzini@redhat.com>; Yao, Jiewen > >>>> <jiewen.yao@intel.com>; Dong, Eric > >> <eric.dong@intel.com> > >>>> Subject: Re: [edk2] [PATCH 1/3] > >>>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 > >>>> SmmStartup() > >>>> > >>>> On 01/30/18 18:22, Kinney, Michael D wrote: > >>>>> Laszlo, > >>>>> > >>>>> The DBs can be removed if the label is moved after > >>>>> the instruction and the patch is done to the label > >>>>> minus the size of the patch value. > >>>> > >>>> Indeed I haven't thought of this. > >>>> > >>>> If I understand correctly, it means > >>>> > >>>> extern UINT8 gSmmCr0; > >>>> > >>>> *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = > >>>> (UINT32)AsmReadCr0 (); > >>>> > >>>> TBH, the DB feels less ugly to me than this :) > >>>> > >>>> Still, if you think it would be an acceptable price > to > >>>> pay for removing > >>>> the remaining DBs, I can respin. > >>>> > >>>> Thanks > >>>> Laszlo > >>>> > >>>>>> -----Original Message----- > >>>>>> From: edk2-devel [mailto:edk2-devel- > >>>> bounces@lists.01.org] > >>>>>> On Behalf Of Laszlo Ersek > >>>>>> Sent: Tuesday, January 30, 2018 7:34 AM > >>>>>> To: edk2-devel-01 <edk2-devel@lists.01.org> > >>>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen > >>>>>> <jiewen.yao@intel.com>; Dong, Eric > >>>> <eric.dong@intel.com>; > >>>>>> Paolo Bonzini <pbonzini@redhat.com> > >>>>>> Subject: [edk2] [PATCH 1/3] > >> UefiCpuPkg/PiSmmCpuDxeSmm: > >>>>>> update comments in IA32 SmmStartup() > >>>>>> > >>>>>> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr > global > >>>>>> variables are used > >>>>>> for patching assembly instructions, thus we can > >> never > >>>>>> remove the DB > >>>>>> encodings for those instructions. At least we > should > >>>> add > >>>>>> the intended > >>>>>> meanings in comments. > >>>>>> > >>>>>> This patch only changes comments. > >>>>>> > >>>>>> Cc: Eric Dong <eric.dong@intel.com> > >>>>>> Cc: Jian J Wang <jian.j.wang@intel.com> > >>>>>> Cc: Jiewen Yao <jiewen.yao@intel.com> > >>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com> > >>>>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com> > >>>>>> Contributed-under: TianoCore Contribution > Agreement > >>>> 1.1 > >>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com> > >>>>>> --- > >>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 > >> ++++- > >>>> --- > >>>>>> 1 file changed, 4 insertions(+), 4 deletions(-) > >>>>>> > >>>>>> diff --git > >>>> a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >>>>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >>>>>> index e96dd8d2392a..08534dba64b7 100644 > >>>>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >>>>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > >>>>>> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) > >>>>>> ASM_PFX(SmmStartup): > >>>>>> DB 0x66 > >>>>>> mov eax, 0x80000001 ; read > >>>>>> capability > >>>>>> cpuid > >>>>>> DB 0x66 > >>>>>> mov ebx, edx ; rdmsr > >> will > >>>>>> change edx. keep it in ebx. > >>>>>> - DB 0x66, 0xb8 > >>>>>> + DB 0x66, 0xb8 ; mov > eax, > >>>> imm32 > >>>>>> ASM_PFX(gSmmCr3): DD 0 > >>>>>> mov cr3, eax > >>>>>> DB 0x67, 0x66 > >>>>>> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - > >>>>>> ASM_PFX(SmmStartup))] > >>>>>> - DB 0x66, 0xb8 > >>>>>> + DB 0x66, 0xb8 ; mov > eax, > >>>> imm32 > >>>>>> ASM_PFX(gSmmCr4): DD 0 > >>>>>> mov cr4, eax > >>>>>> DB 0x66 > >>>>>> mov ecx, 0xc0000080 ; > IA32_EFER > >>>> MSR > >>>>>> rdmsr > >>>>>> DB 0x66 > >>>>>> test ebx, BIT20 ; check > NXE > >>>>>> capability > >>>>>> jz .1 > >>>>>> or ah, BIT3 ; set NXE > >> bit > >>>>>> wrmsr > >>>>>> .1: > >>>>>> - DB 0x66, 0xb8 > >>>>>> + DB 0x66, 0xb8 ; mov > eax, > >>>> imm32 > >>>>>> ASM_PFX(gSmmCr0): DD 0 > >>>>>> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, > >>>>>> PROTECT_MODE_DS > >>>>>> mov cr0, eax > >>>>>> - DB 0x66, 0xea ; jmp > far > >>>>>> [ptr48] > >>>>>> + DB 0x66, 0xea ; jmp far > >>>>>> [ptr48] > >>>>>> ASM_PFX(gSmmJmpAddr): > >>>>>> DD @32bit > >>>>>> DW PROTECT_MODE_CS > >>>>>> @32bit: > >>>>>> mov ds, edi > >>>>>> mov es, edi > >>>>>> -- > >>>>>> 2.14.1.3.gb7cf6e02401b > >>>>>> > >>>>>> > >>>>>> _______________________________________________ > >>>>>> 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 > > > > _______________________________________________ > > edk2-devel mailing list > > edk2-devel@lists.01.org > > https://lists.01.org/mailman/listinfo/edk2-devel > > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-31 22:11 ` Kinney, Michael D @ 2018-02-02 6:05 ` Laszlo Ersek 0 siblings, 0 replies; 27+ messages in thread From: Laszlo Ersek @ 2018-02-02 6:05 UTC (permalink / raw) To: Kinney, Michael D, edk2-devel-01 Cc: Ni, Ruiyu, Dong, Eric, Ard Biesheuvel, Leif Lindholm (Linaro address), Yao, Jiewen, Paolo Bonzini On 01/31/18 23:11, Kinney, Michael D wrote: > Laszlo, > > I agree the Unaligned functions have issues. > We should see if we could change the param type. > It should be a backwards compatible change to > go from a type specific pointer to VOID *. But > need to check with all supported compilers. > > We can have arch specific functions and macros. > There are many in BaseLib.h. This way, if a macro > or function is used by an unsupported arch, the > build will fail. I also like some of the name > change suggestions. Maybe PatchInstructionX86() > and change the parameter name to InstructionEnd. > > BaseLib.h > ========== > #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) > > VOID > EFIAPI > PatchInstructionX86 ( > VOID *InstructionEnd, > UINT64 PatchValue, > UINTN ValueSize > ); > > #endif > > BaseLib Instance > ========== > VOID > EFIAPI > PatchInstructionX86 ( > VOID *InstructionEnd, > UINT64 PatchValue, > UINTN ValueSize > ) > { > ASSERT ((UINTN)InstructionEnd > ValueSize); > switch (ValueSize) { > case 1: > ASSERT (PatchValue <= MAX_UINT8); > *((UINT8 *)InstructionEnd - 1) = (UINT8)PatchValue; > case 2: > ASSERT (PatchValue <= MAX_UINT16); > WriteUnaligned16 ((UINT16 *)(InstructionEnd) - 1, (UINT16)PatchValue)); > break; > case 4: > ASSERT (PatchValue <= MAX_UINT32); > WriteUnaligned32 ((UINT32 *)(InstructionEnd) - 1, (UINT32)PatchValue)); > break; > case 8: > WriteUnaligned64 ((UINT64 *)(InstructionEnd) - 1, PatchValue)); > break; > default: > ASSERT (FALSE); > } > } I managed to remove all instruction DBs from PiSmmCpuDxeSmm. I plan to post the patches this week or the next. Thanks! Laszlo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-01-31 10:40 ` Laszlo Ersek 2018-01-31 22:11 ` Kinney, Michael D @ 2018-02-02 10:06 ` Ard Biesheuvel 2018-02-02 13:26 ` Laszlo Ersek 2018-02-02 13:28 ` Leif Lindholm 1 sibling, 2 replies; 27+ messages in thread From: Ard Biesheuvel @ 2018-02-02 10:06 UTC (permalink / raw) To: Laszlo Ersek Cc: Kinney, Michael D, edk2-devel-01, Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric, Leif Lindholm (Linaro address) On 31 January 2018 at 10:40, Laszlo Ersek <lersek@redhat.com> wrote: > On 01/30/18 23:25, Kinney, Michael D wrote: >> Laszlo, >> >> I agree that the function is better than a macro. >> >> I thought of the alignment issues as well. CopyMem() >> is a good solution. We could also consider >> WriteUnalignedxx() functions in BaseLib. > > IMO, the WriteUnalignedxx functions are a bit pointless in the exact > form they are declared (this was discussed earlier esp. with regard to > aarch64). The functions take pointers to objects that already have the > target type, such as > > UINT32 > EFIAPI > WriteUnaligned32 ( > OUT UINT32 *Buffer, > IN UINT32 Value > ) > > Here the type of Buffer should be (VOID *), not (UINT32 *). Otherwise, > the undefined behavior (due to mis-alignment) surfaces as soon as the > function is called with an unaligned pointer (i.e. before the target > area is actually written). > >> I was originally thinking this functionality would go >> into BaseLib. But with the use of CopyMem(), we can't >> do that. > > Can we put it in BaseMemoryLib instead (which is where CopyMem() is > from)? That library class is still low-level enough. And, while I count > 9 library instances, PatchAssembly() is not a large function, we could > tolerate adding it to all 9 instances, identically. > > Let me also ask the opposite question: should we perhaps make the > PatchAssembly() API *less* abstract? (Also suggested by your naming of > the macro, PATCH_X86_ASM.) If the instruction encoding on e.g. AARCH64 > doesn't lend itself to such patching (= expressed through the address > right after the instruction), then even BaseMemoryLib may be too generic > for the API. > >> Maybe we should use WriteUnalignedxx() and >> add some ASSERT() checks. >> >> VOID >> PatchAssembly ( >> VOID *BufferEnd, >> UINT64 PatchValue, >> UINTN ValueSize >> ) >> { >> ASSERT ((UINTN)BufferEnd > ValueSize); >> switch (ValueSize) { >> case 1: >> ASSERT (PatchValue <= MAX_UINT8); >> *((UINT8 *)BufferEnd - 1) = (UINT8)PatchValue; >> case 2: >> ASSERT (PatchValue <= MAX_UINT16); >> WriteUnaligned16 ((UINT16 *)(BufferEnd) - 1, (UINT16)PatchValue)); >> break; >> case 4: >> ASSERT (PatchValue <= MAX_UINT32); >> WriteUnaligned32 ((UINT32 *)(BufferEnd) - 1, (UINT32)PatchValue)); >> break; >> case 8: >> WriteUnaligned64 ((UINT64 *)(BufferEnd) - 1, PatchValue)); >> break; >> default: >> ASSERT (FALSE); >> } >> } > > In my opinion: > > - If Ard and Leif say that PatchAssembly() API makes sense for AARCH64, > then I think we can go with the above generic implementation (for > BaseLib). > Code patching on ARM/AARCH64 has some hoops to jump through, i.e., clean the D-cache to the point of unification, invalidate the I-cache, probably some barriers in case the patching function happened to end up in the same cache line as the patchee (which may not be a concern for this specific use case, but it does need to be taken into account if this is turned into a patch-any-assembly-anywhere function) So if the PatchAssembly() prototype does end up in a generic library class, we'd have to provide ARM and AARCH64 specific implementations anyway, and given that I don't see any use for this on ARM/AARCH64 in the first place, I think this should belong in an IA32/X64 specific package. > - If Ard and Leif say the API is only useful on x86, then I suggest that > we implement the API separately for all arches (still in BaseLib): > > - On x86, we should simply open-code the unaligned accesses (like you > originall suggested). The pointer arithmetic will look a bit wild, > but it's safely hidden behind a BaseLib API, so client code will > look nice. > > - On all other arches, we should implement the function with > ASSERT(FALSE). > > Thanks! > Laszlo > >> >> Mike >> >>> -----Original Message----- >>> From: Laszlo Ersek [mailto:lersek@redhat.com] >>> Sent: Tuesday, January 30, 2018 1:45 PM >>> To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2- >>> devel-01 <edk2-devel@lists.01.org> >>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>> <pbonzini@redhat.com>; Yao, Jiewen >>> <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> >>> Subject: Re: [edk2] [PATCH 1/3] >>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>> SmmStartup() >>> >>> On 01/30/18 21:31, Kinney, Michael D wrote: >>>> Laszlo, >>>> >>>> We have already used this technique in other NASM files >>>> to remove DBs. >>> >>> OK. >>> >>>> Let us know if you have suggestions on how to make the >>>> C code that performs the patches easier to read and >>>> maintain. >>> >>> How about this: >>> >>> VOID >>> PatchAssembly ( >>> VOID *BufferEnd, >>> UINT64 PatchValue, >>> UINTN ValueSize >>> ) >>> { >>> CopyMem ( >>> (VOID *)((UINTN)BufferEnd - ValueSize), >>> &PatchValue, >>> ValueSize >>> ); >>> } >>> >>> extern UINT8 gAsmSmmCr0; >>> extern UINT8 gAsmSmmCr3; >>> extern UINT8 gAsmSmmCr4; >>> >>> ... >>> { >>> PatchAssembly (&gAsmSmmCr0, AsmReadCr0 (), 4); >>> PatchAssembly (&gAsmSmmCr3, AsmReadCr3 (), 4); >>> PatchAssembly (&gAsmSmmCr4, AsmReadCr4 (), 4); >>> ... >>> } >>> >>> (I think it's fine to open-code the last argument as "4", >>> rather than >>> "sizeof (UINT32)", because for patching, we must have >>> intimate knowledge >>> of the instruction anyway.) >>> >>> To me, this is easier to read, because: >>> >>> - there are no complex casts in the "business logic" >>> - the size is spelled out once per patching >>> - the function name and the variable names make it clear >>> we are patching >>> separately compiled assembly code that was linked into >>> the same >>> module. >>> >>> What do you think? >>> >>> Thanks! >>> Laszlo >>> >>>>> -----Original Message----- >>>>> From: edk2-devel [mailto:edk2-devel- >>> bounces@lists.01.org] >>>>> On Behalf Of Laszlo Ersek >>>>> Sent: Tuesday, January 30, 2018 10:17 AM >>>>> To: Kinney, Michael D <michael.d.kinney@intel.com>; >>> edk2- >>>>> devel-01 <edk2-devel@lists.01.org> >>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>>>> <pbonzini@redhat.com>; Yao, Jiewen >>>>> <jiewen.yao@intel.com>; Dong, Eric >>> <eric.dong@intel.com> >>>>> Subject: Re: [edk2] [PATCH 1/3] >>>>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>>>> SmmStartup() >>>>> >>>>> On 01/30/18 18:22, Kinney, Michael D wrote: >>>>>> Laszlo, >>>>>> >>>>>> The DBs can be removed if the label is moved after >>>>>> the instruction and the patch is done to the label >>>>>> minus the size of the patch value. >>>>> >>>>> Indeed I haven't thought of this. >>>>> >>>>> If I understand correctly, it means >>>>> >>>>> extern UINT8 gSmmCr0; >>>>> >>>>> *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = >>>>> (UINT32)AsmReadCr0 (); >>>>> >>>>> TBH, the DB feels less ugly to me than this :) >>>>> >>>>> Still, if you think it would be an acceptable price to >>>>> pay for removing >>>>> the remaining DBs, I can respin. >>>>> >>>>> Thanks >>>>> Laszlo >>>>> >>>>>>> -----Original Message----- >>>>>>> From: edk2-devel [mailto:edk2-devel- >>>>> bounces@lists.01.org] >>>>>>> On Behalf Of Laszlo Ersek >>>>>>> Sent: Tuesday, January 30, 2018 7:34 AM >>>>>>> To: edk2-devel-01 <edk2-devel@lists.01.org> >>>>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen >>>>>>> <jiewen.yao@intel.com>; Dong, Eric >>>>> <eric.dong@intel.com>; >>>>>>> Paolo Bonzini <pbonzini@redhat.com> >>>>>>> Subject: [edk2] [PATCH 1/3] >>> UefiCpuPkg/PiSmmCpuDxeSmm: >>>>>>> update comments in IA32 SmmStartup() >>>>>>> >>>>>>> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global >>>>>>> variables are used >>>>>>> for patching assembly instructions, thus we can >>> never >>>>>>> remove the DB >>>>>>> encodings for those instructions. At least we should >>>>> add >>>>>>> the intended >>>>>>> meanings in comments. >>>>>>> >>>>>>> This patch only changes comments. >>>>>>> >>>>>>> Cc: Eric Dong <eric.dong@intel.com> >>>>>>> Cc: Jian J Wang <jian.j.wang@intel.com> >>>>>>> Cc: Jiewen Yao <jiewen.yao@intel.com> >>>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com> >>>>>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com> >>>>>>> Contributed-under: TianoCore Contribution Agreement >>>>> 1.1 >>>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com> >>>>>>> --- >>>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 >>> ++++- >>>>> --- >>>>>>> 1 file changed, 4 insertions(+), 4 deletions(-) >>>>>>> >>>>>>> diff --git >>>>> a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> index e96dd8d2392a..08534dba64b7 100644 >>>>>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) >>>>>>> ASM_PFX(SmmStartup): >>>>>>> DB 0x66 >>>>>>> mov eax, 0x80000001 ; read >>>>>>> capability >>>>>>> cpuid >>>>>>> DB 0x66 >>>>>>> mov ebx, edx ; rdmsr >>> will >>>>>>> change edx. keep it in ebx. >>>>>>> - DB 0x66, 0xb8 >>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>> imm32 >>>>>>> ASM_PFX(gSmmCr3): DD 0 >>>>>>> mov cr3, eax >>>>>>> DB 0x67, 0x66 >>>>>>> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - >>>>>>> ASM_PFX(SmmStartup))] >>>>>>> - DB 0x66, 0xb8 >>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>> imm32 >>>>>>> ASM_PFX(gSmmCr4): DD 0 >>>>>>> mov cr4, eax >>>>>>> DB 0x66 >>>>>>> mov ecx, 0xc0000080 ; IA32_EFER >>>>> MSR >>>>>>> rdmsr >>>>>>> DB 0x66 >>>>>>> test ebx, BIT20 ; check NXE >>>>>>> capability >>>>>>> jz .1 >>>>>>> or ah, BIT3 ; set NXE >>> bit >>>>>>> wrmsr >>>>>>> .1: >>>>>>> - DB 0x66, 0xb8 >>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>> imm32 >>>>>>> ASM_PFX(gSmmCr0): DD 0 >>>>>>> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, >>>>>>> PROTECT_MODE_DS >>>>>>> mov cr0, eax >>>>>>> - DB 0x66, 0xea ; jmp far >>>>>>> [ptr48] >>>>>>> + DB 0x66, 0xea ; jmp far >>>>>>> [ptr48] >>>>>>> ASM_PFX(gSmmJmpAddr): >>>>>>> DD @32bit >>>>>>> DW PROTECT_MODE_CS >>>>>>> @32bit: >>>>>>> mov ds, edi >>>>>>> mov es, edi >>>>>>> -- >>>>>>> 2.14.1.3.gb7cf6e02401b >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> 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 >> >> _______________________________________________ >> edk2-devel mailing list >> edk2-devel@lists.01.org >> https://lists.01.org/mailman/listinfo/edk2-devel >> > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-02-02 10:06 ` Ard Biesheuvel @ 2018-02-02 13:26 ` Laszlo Ersek 2018-02-02 13:28 ` Leif Lindholm 1 sibling, 0 replies; 27+ messages in thread From: Laszlo Ersek @ 2018-02-02 13:26 UTC (permalink / raw) To: Ard Biesheuvel Cc: Kinney, Michael D, edk2-devel-01, Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric, Leif Lindholm (Linaro address) On 02/02/18 11:06, Ard Biesheuvel wrote: > On 31 January 2018 at 10:40, Laszlo Ersek <lersek@redhat.com> wrote: >> On 01/30/18 23:25, Kinney, Michael D wrote: >>> Laszlo, >>> >>> I agree that the function is better than a macro. >>> >>> I thought of the alignment issues as well. CopyMem() >>> is a good solution. We could also consider >>> WriteUnalignedxx() functions in BaseLib. >> >> IMO, the WriteUnalignedxx functions are a bit pointless in the exact >> form they are declared (this was discussed earlier esp. with regard to >> aarch64). The functions take pointers to objects that already have the >> target type, such as >> >> UINT32 >> EFIAPI >> WriteUnaligned32 ( >> OUT UINT32 *Buffer, >> IN UINT32 Value >> ) >> >> Here the type of Buffer should be (VOID *), not (UINT32 *). Otherwise, >> the undefined behavior (due to mis-alignment) surfaces as soon as the >> function is called with an unaligned pointer (i.e. before the target >> area is actually written). >> >>> I was originally thinking this functionality would go >>> into BaseLib. But with the use of CopyMem(), we can't >>> do that. >> >> Can we put it in BaseMemoryLib instead (which is where CopyMem() is >> from)? That library class is still low-level enough. And, while I count >> 9 library instances, PatchAssembly() is not a large function, we could >> tolerate adding it to all 9 instances, identically. >> >> Let me also ask the opposite question: should we perhaps make the >> PatchAssembly() API *less* abstract? (Also suggested by your naming of >> the macro, PATCH_X86_ASM.) If the instruction encoding on e.g. AARCH64 >> doesn't lend itself to such patching (= expressed through the address >> right after the instruction), then even BaseMemoryLib may be too generic >> for the API. >> >>> Maybe we should use WriteUnalignedxx() and >>> add some ASSERT() checks. >>> >>> VOID >>> PatchAssembly ( >>> VOID *BufferEnd, >>> UINT64 PatchValue, >>> UINTN ValueSize >>> ) >>> { >>> ASSERT ((UINTN)BufferEnd > ValueSize); >>> switch (ValueSize) { >>> case 1: >>> ASSERT (PatchValue <= MAX_UINT8); >>> *((UINT8 *)BufferEnd - 1) = (UINT8)PatchValue; >>> case 2: >>> ASSERT (PatchValue <= MAX_UINT16); >>> WriteUnaligned16 ((UINT16 *)(BufferEnd) - 1, (UINT16)PatchValue)); >>> break; >>> case 4: >>> ASSERT (PatchValue <= MAX_UINT32); >>> WriteUnaligned32 ((UINT32 *)(BufferEnd) - 1, (UINT32)PatchValue)); >>> break; >>> case 8: >>> WriteUnaligned64 ((UINT64 *)(BufferEnd) - 1, PatchValue)); >>> break; >>> default: >>> ASSERT (FALSE); >>> } >>> } >> >> In my opinion: >> >> - If Ard and Leif say that PatchAssembly() API makes sense for AARCH64, >> then I think we can go with the above generic implementation (for >> BaseLib). >> > > Code patching on ARM/AARCH64 has some hoops to jump through, i.e., > clean the D-cache to the point of unification, invalidate the I-cache, > probably some barriers in case the patching function happened to end > up in the same cache line as the patchee (which may not be a concern > for this specific use case, but it does need to be taken into account > if this is turned into a patch-any-assembly-anywhere function) > > So if the PatchAssembly() prototype does end up in a generic library > class, we'd have to provide ARM and AARCH64 specific implementations > anyway, and given that I don't see any use for this on ARM/AARCH64 in > the first place, I think this should belong in an IA32/X64 specific > package. Thank you for the response! For now I'm going to post the series with the function introduced as PatchInstructionX86() to BaseLib, visibly only to IA32 and X64 edk2 platforms. If a better place than BaseLib looks necessary, I can move it according to review comments. Thanks! Laszlo > >> - If Ard and Leif say the API is only useful on x86, then I suggest that >> we implement the API separately for all arches (still in BaseLib): >> >> - On x86, we should simply open-code the unaligned accesses (like you >> originall suggested). The pointer arithmetic will look a bit wild, >> but it's safely hidden behind a BaseLib API, so client code will >> look nice. >> >> - On all other arches, we should implement the function with >> ASSERT(FALSE). >> >> Thanks! >> Laszlo >> >>> >>> Mike >>> >>>> -----Original Message----- >>>> From: Laszlo Ersek [mailto:lersek@redhat.com] >>>> Sent: Tuesday, January 30, 2018 1:45 PM >>>> To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2- >>>> devel-01 <edk2-devel@lists.01.org> >>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>>> <pbonzini@redhat.com>; Yao, Jiewen >>>> <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> >>>> Subject: Re: [edk2] [PATCH 1/3] >>>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>>> SmmStartup() >>>> >>>> On 01/30/18 21:31, Kinney, Michael D wrote: >>>>> Laszlo, >>>>> >>>>> We have already used this technique in other NASM files >>>>> to remove DBs. >>>> >>>> OK. >>>> >>>>> Let us know if you have suggestions on how to make the >>>>> C code that performs the patches easier to read and >>>>> maintain. >>>> >>>> How about this: >>>> >>>> VOID >>>> PatchAssembly ( >>>> VOID *BufferEnd, >>>> UINT64 PatchValue, >>>> UINTN ValueSize >>>> ) >>>> { >>>> CopyMem ( >>>> (VOID *)((UINTN)BufferEnd - ValueSize), >>>> &PatchValue, >>>> ValueSize >>>> ); >>>> } >>>> >>>> extern UINT8 gAsmSmmCr0; >>>> extern UINT8 gAsmSmmCr3; >>>> extern UINT8 gAsmSmmCr4; >>>> >>>> ... >>>> { >>>> PatchAssembly (&gAsmSmmCr0, AsmReadCr0 (), 4); >>>> PatchAssembly (&gAsmSmmCr3, AsmReadCr3 (), 4); >>>> PatchAssembly (&gAsmSmmCr4, AsmReadCr4 (), 4); >>>> ... >>>> } >>>> >>>> (I think it's fine to open-code the last argument as "4", >>>> rather than >>>> "sizeof (UINT32)", because for patching, we must have >>>> intimate knowledge >>>> of the instruction anyway.) >>>> >>>> To me, this is easier to read, because: >>>> >>>> - there are no complex casts in the "business logic" >>>> - the size is spelled out once per patching >>>> - the function name and the variable names make it clear >>>> we are patching >>>> separately compiled assembly code that was linked into >>>> the same >>>> module. >>>> >>>> What do you think? >>>> >>>> Thanks! >>>> Laszlo >>>> >>>>>> -----Original Message----- >>>>>> From: edk2-devel [mailto:edk2-devel- >>>> bounces@lists.01.org] >>>>>> On Behalf Of Laszlo Ersek >>>>>> Sent: Tuesday, January 30, 2018 10:17 AM >>>>>> To: Kinney, Michael D <michael.d.kinney@intel.com>; >>>> edk2- >>>>>> devel-01 <edk2-devel@lists.01.org> >>>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Paolo Bonzini >>>>>> <pbonzini@redhat.com>; Yao, Jiewen >>>>>> <jiewen.yao@intel.com>; Dong, Eric >>>> <eric.dong@intel.com> >>>>>> Subject: Re: [edk2] [PATCH 1/3] >>>>>> UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 >>>>>> SmmStartup() >>>>>> >>>>>> On 01/30/18 18:22, Kinney, Michael D wrote: >>>>>>> Laszlo, >>>>>>> >>>>>>> The DBs can be removed if the label is moved after >>>>>>> the instruction and the patch is done to the label >>>>>>> minus the size of the patch value. >>>>>> >>>>>> Indeed I haven't thought of this. >>>>>> >>>>>> If I understand correctly, it means >>>>>> >>>>>> extern UINT8 gSmmCr0; >>>>>> >>>>>> *(UINT32*)(&gSmmCr0 - sizeof (UINT32)) = >>>>>> (UINT32)AsmReadCr0 (); >>>>>> >>>>>> TBH, the DB feels less ugly to me than this :) >>>>>> >>>>>> Still, if you think it would be an acceptable price to >>>>>> pay for removing >>>>>> the remaining DBs, I can respin. >>>>>> >>>>>> Thanks >>>>>> Laszlo >>>>>> >>>>>>>> -----Original Message----- >>>>>>>> From: edk2-devel [mailto:edk2-devel- >>>>>> bounces@lists.01.org] >>>>>>>> On Behalf Of Laszlo Ersek >>>>>>>> Sent: Tuesday, January 30, 2018 7:34 AM >>>>>>>> To: edk2-devel-01 <edk2-devel@lists.01.org> >>>>>>>> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Yao, Jiewen >>>>>>>> <jiewen.yao@intel.com>; Dong, Eric >>>>>> <eric.dong@intel.com>; >>>>>>>> Paolo Bonzini <pbonzini@redhat.com> >>>>>>>> Subject: [edk2] [PATCH 1/3] >>>> UefiCpuPkg/PiSmmCpuDxeSmm: >>>>>>>> update comments in IA32 SmmStartup() >>>>>>>> >>>>>>>> The gSmmCr3, gSmmCr4, gSmmCr0 and gSmmJmpAddr global >>>>>>>> variables are used >>>>>>>> for patching assembly instructions, thus we can >>>> never >>>>>>>> remove the DB >>>>>>>> encodings for those instructions. At least we should >>>>>> add >>>>>>>> the intended >>>>>>>> meanings in comments. >>>>>>>> >>>>>>>> This patch only changes comments. >>>>>>>> >>>>>>>> Cc: Eric Dong <eric.dong@intel.com> >>>>>>>> Cc: Jian J Wang <jian.j.wang@intel.com> >>>>>>>> Cc: Jiewen Yao <jiewen.yao@intel.com> >>>>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com> >>>>>>>> Cc: Ruiyu Ni <ruiyu.ni@intel.com> >>>>>>>> Contributed-under: TianoCore Contribution Agreement >>>>>> 1.1 >>>>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com> >>>>>>>> --- >>>>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 8 >>>> ++++- >>>>>> --- >>>>>>>> 1 file changed, 4 insertions(+), 4 deletions(-) >>>>>>>> >>>>>>>> diff --git >>>>>> a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>>> index e96dd8d2392a..08534dba64b7 100644 >>>>>>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm >>>>>>>> @@ -44,34 +44,34 @@ global ASM_PFX(SmmStartup) >>>>>>>> ASM_PFX(SmmStartup): >>>>>>>> DB 0x66 >>>>>>>> mov eax, 0x80000001 ; read >>>>>>>> capability >>>>>>>> cpuid >>>>>>>> DB 0x66 >>>>>>>> mov ebx, edx ; rdmsr >>>> will >>>>>>>> change edx. keep it in ebx. >>>>>>>> - DB 0x66, 0xb8 >>>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>>> imm32 >>>>>>>> ASM_PFX(gSmmCr3): DD 0 >>>>>>>> mov cr3, eax >>>>>>>> DB 0x67, 0x66 >>>>>>>> lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - >>>>>>>> ASM_PFX(SmmStartup))] >>>>>>>> - DB 0x66, 0xb8 >>>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>>> imm32 >>>>>>>> ASM_PFX(gSmmCr4): DD 0 >>>>>>>> mov cr4, eax >>>>>>>> DB 0x66 >>>>>>>> mov ecx, 0xc0000080 ; IA32_EFER >>>>>> MSR >>>>>>>> rdmsr >>>>>>>> DB 0x66 >>>>>>>> test ebx, BIT20 ; check NXE >>>>>>>> capability >>>>>>>> jz .1 >>>>>>>> or ah, BIT3 ; set NXE >>>> bit >>>>>>>> wrmsr >>>>>>>> .1: >>>>>>>> - DB 0x66, 0xb8 >>>>>>>> + DB 0x66, 0xb8 ; mov eax, >>>>>> imm32 >>>>>>>> ASM_PFX(gSmmCr0): DD 0 >>>>>>>> DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, >>>>>>>> PROTECT_MODE_DS >>>>>>>> mov cr0, eax >>>>>>>> - DB 0x66, 0xea ; jmp far >>>>>>>> [ptr48] >>>>>>>> + DB 0x66, 0xea ; jmp far >>>>>>>> [ptr48] >>>>>>>> ASM_PFX(gSmmJmpAddr): >>>>>>>> DD @32bit >>>>>>>> DW PROTECT_MODE_CS >>>>>>>> @32bit: >>>>>>>> mov ds, edi >>>>>>>> mov es, edi >>>>>>>> -- >>>>>>>> 2.14.1.3.gb7cf6e02401b >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> 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 >>> >>> _______________________________________________ >>> edk2-devel mailing list >>> edk2-devel@lists.01.org >>> https://lists.01.org/mailman/listinfo/edk2-devel >>> >> ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-02-02 10:06 ` Ard Biesheuvel 2018-02-02 13:26 ` Laszlo Ersek @ 2018-02-02 13:28 ` Leif Lindholm 2018-02-02 13:36 ` Laszlo Ersek 1 sibling, 1 reply; 27+ messages in thread From: Leif Lindholm @ 2018-02-02 13:28 UTC (permalink / raw) To: Ard Biesheuvel Cc: Laszlo Ersek, Kinney, Michael D, edk2-devel-01, Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric On Fri, Feb 02, 2018 at 10:06:07AM +0000, Ard Biesheuvel wrote: > On 31 January 2018 at 10:40, Laszlo Ersek <lersek@redhat.com> wrote: > > On 01/30/18 23:25, Kinney, Michael D wrote: > >> Laszlo, > >> > >> I agree that the function is better than a macro. > >> > >> I thought of the alignment issues as well. CopyMem() > >> is a good solution. We could also consider > >> WriteUnalignedxx() functions in BaseLib. > > > > IMO, the WriteUnalignedxx functions are a bit pointless in the exact > > form they are declared (this was discussed earlier esp. with regard to > > aarch64). The functions take pointers to objects that already have the > > target type, such as > > > > UINT32 > > EFIAPI > > WriteUnaligned32 ( > > OUT UINT32 *Buffer, > > IN UINT32 Value > > ) > > > > Here the type of Buffer should be (VOID *), not (UINT32 *). Otherwise, > > the undefined behavior (due to mis-alignment) surfaces as soon as the > > function is called with an unaligned pointer (i.e. before the target > > area is actually written). > > > >> I was originally thinking this functionality would go > >> into BaseLib. But with the use of CopyMem(), we can't > >> do that. > > > > Can we put it in BaseMemoryLib instead (which is where CopyMem() is > > from)? That library class is still low-level enough. And, while I count > > 9 library instances, PatchAssembly() is not a large function, we could > > tolerate adding it to all 9 instances, identically. > > > > Let me also ask the opposite question: should we perhaps make the > > PatchAssembly() API *less* abstract? (Also suggested by your naming of > > the macro, PATCH_X86_ASM.) If the instruction encoding on e.g. AARCH64 > > doesn't lend itself to such patching (= expressed through the address > > right after the instruction), then even BaseMemoryLib may be too generic > > for the API. > > > >> Maybe we should use WriteUnalignedxx() and > >> add some ASSERT() checks. > >> > >> VOID > >> PatchAssembly ( > >> VOID *BufferEnd, > >> UINT64 PatchValue, > >> UINTN ValueSize > >> ) > >> { > >> ASSERT ((UINTN)BufferEnd > ValueSize); > >> switch (ValueSize) { > >> case 1: > >> ASSERT (PatchValue <= MAX_UINT8); > >> *((UINT8 *)BufferEnd - 1) = (UINT8)PatchValue; > >> case 2: > >> ASSERT (PatchValue <= MAX_UINT16); > >> WriteUnaligned16 ((UINT16 *)(BufferEnd) - 1, (UINT16)PatchValue)); > >> break; > >> case 4: > >> ASSERT (PatchValue <= MAX_UINT32); > >> WriteUnaligned32 ((UINT32 *)(BufferEnd) - 1, (UINT32)PatchValue)); > >> break; > >> case 8: > >> WriteUnaligned64 ((UINT64 *)(BufferEnd) - 1, PatchValue)); > >> break; > >> default: > >> ASSERT (FALSE); > >> } > >> } > > > > In my opinion: > > > > - If Ard and Leif say that PatchAssembly() API makes sense for AARCH64, > > then I think we can go with the above generic implementation (for > > BaseLib). > > > > Code patching on ARM/AARCH64 has some hoops to jump through, i.e., > clean the D-cache to the point of unification, invalidate the I-cache, > probably some barriers in case the patching function happened to end > up in the same cache line as the patchee Not just the same cache line. Prefetching can happen whenever, for whatever reason. > (which may not be a concern > for this specific use case, but it does need to be taken into account > if this is turned into a patch-any-assembly-anywhere function) > > So if the PatchAssembly() prototype does end up in a generic library > class, we'd have to provide ARM and AARCH64 specific implementations > anyway, and given that I don't see any use for this on ARM/AARCH64 in > the first place, I think this should belong in an IA32/X64 specific > package. I also don't see a specific use for this on ARM* at the moment. But if this is going to become more widespread, it would be useful to introduce a higher-level layer with more portable semantics (I don't know RISC-V, but could imagine they require similar). However, at that point, we would probably want something buffer-oriented rather than instruction-oriented, since we'd like to keep the overhead down if writing more than one register's worth. / Leif ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() 2018-02-02 13:28 ` Leif Lindholm @ 2018-02-02 13:36 ` Laszlo Ersek 0 siblings, 0 replies; 27+ messages in thread From: Laszlo Ersek @ 2018-02-02 13:36 UTC (permalink / raw) To: Leif Lindholm, Ard Biesheuvel Cc: Kinney, Michael D, edk2-devel-01, Ni, Ruiyu, Paolo Bonzini, Yao, Jiewen, Dong, Eric On 02/02/18 14:28, Leif Lindholm wrote: > On Fri, Feb 02, 2018 at 10:06:07AM +0000, Ard Biesheuvel wrote: >> On 31 January 2018 at 10:40, Laszlo Ersek <lersek@redhat.com> wrote: >>> On 01/30/18 23:25, Kinney, Michael D wrote: >>>> Laszlo, >>>> >>>> I agree that the function is better than a macro. >>>> >>>> I thought of the alignment issues as well. CopyMem() >>>> is a good solution. We could also consider >>>> WriteUnalignedxx() functions in BaseLib. >>> >>> IMO, the WriteUnalignedxx functions are a bit pointless in the exact >>> form they are declared (this was discussed earlier esp. with regard to >>> aarch64). The functions take pointers to objects that already have the >>> target type, such as >>> >>> UINT32 >>> EFIAPI >>> WriteUnaligned32 ( >>> OUT UINT32 *Buffer, >>> IN UINT32 Value >>> ) >>> >>> Here the type of Buffer should be (VOID *), not (UINT32 *). Otherwise, >>> the undefined behavior (due to mis-alignment) surfaces as soon as the >>> function is called with an unaligned pointer (i.e. before the target >>> area is actually written). >>> >>>> I was originally thinking this functionality would go >>>> into BaseLib. But with the use of CopyMem(), we can't >>>> do that. >>> >>> Can we put it in BaseMemoryLib instead (which is where CopyMem() is >>> from)? That library class is still low-level enough. And, while I count >>> 9 library instances, PatchAssembly() is not a large function, we could >>> tolerate adding it to all 9 instances, identically. >>> >>> Let me also ask the opposite question: should we perhaps make the >>> PatchAssembly() API *less* abstract? (Also suggested by your naming of >>> the macro, PATCH_X86_ASM.) If the instruction encoding on e.g. AARCH64 >>> doesn't lend itself to such patching (= expressed through the address >>> right after the instruction), then even BaseMemoryLib may be too generic >>> for the API. >>> >>>> Maybe we should use WriteUnalignedxx() and >>>> add some ASSERT() checks. >>>> >>>> VOID >>>> PatchAssembly ( >>>> VOID *BufferEnd, >>>> UINT64 PatchValue, >>>> UINTN ValueSize >>>> ) >>>> { >>>> ASSERT ((UINTN)BufferEnd > ValueSize); >>>> switch (ValueSize) { >>>> case 1: >>>> ASSERT (PatchValue <= MAX_UINT8); >>>> *((UINT8 *)BufferEnd - 1) = (UINT8)PatchValue; >>>> case 2: >>>> ASSERT (PatchValue <= MAX_UINT16); >>>> WriteUnaligned16 ((UINT16 *)(BufferEnd) - 1, (UINT16)PatchValue)); >>>> break; >>>> case 4: >>>> ASSERT (PatchValue <= MAX_UINT32); >>>> WriteUnaligned32 ((UINT32 *)(BufferEnd) - 1, (UINT32)PatchValue)); >>>> break; >>>> case 8: >>>> WriteUnaligned64 ((UINT64 *)(BufferEnd) - 1, PatchValue)); >>>> break; >>>> default: >>>> ASSERT (FALSE); >>>> } >>>> } >>> >>> In my opinion: >>> >>> - If Ard and Leif say that PatchAssembly() API makes sense for AARCH64, >>> then I think we can go with the above generic implementation (for >>> BaseLib). >>> >> >> Code patching on ARM/AARCH64 has some hoops to jump through, i.e., >> clean the D-cache to the point of unification, invalidate the I-cache, >> probably some barriers in case the patching function happened to end >> up in the same cache line as the patchee > > Not just the same cache line. Prefetching can happen whenever, for > whatever reason. > >> (which may not be a concern >> for this specific use case, but it does need to be taken into account >> if this is turned into a patch-any-assembly-anywhere function) >> >> So if the PatchAssembly() prototype does end up in a generic library >> class, we'd have to provide ARM and AARCH64 specific implementations >> anyway, and given that I don't see any use for this on ARM/AARCH64 in >> the first place, I think this should belong in an IA32/X64 specific >> package. > > I also don't see a specific use for this on ARM* at the moment. But if > this is going to become more widespread, it would be useful to > introduce a higher-level layer with more portable semantics (I don't > know RISC-V, but could imagine they require similar). > However, at that point, we would probably want something > buffer-oriented rather than instruction-oriented, since we'd like to > keep the overhead down if writing more than one register's worth. I'll CC you and Ard on the BaseLib patches; hopefully PatchInstructionX86() will be possible to reimplement in terms of the more generic, buffer-oriented API, once we introduce that. Thanks! Laszlo ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 2/3] UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from IA32 SmmStartup() 2018-01-30 15:33 [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM Laszlo Ersek 2018-01-30 15:33 ` [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() Laszlo Ersek @ 2018-01-30 15:33 ` Laszlo Ersek 2018-01-31 5:45 ` Ni, Ruiyu 2018-01-30 15:33 ` [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in " Laszlo Ersek ` (3 subsequent siblings) 5 siblings, 1 reply; 27+ messages in thread From: Laszlo Ersek @ 2018-01-30 15:33 UTC (permalink / raw) To: edk2-devel-01; +Cc: Eric Dong, Jian J Wang, Jiewen Yao, Paolo Bonzini, Ruiyu Ni The SmmStartup() executes in SMM, which is very similar to real mode. Add "BITS 16" before it and "BITS 32" after it (just before the @32bit label). Remove the manual 0x66 operand-size override prefixes, for selecting 32-bit operands -- the sizes of our operands trigger NASM to insert the prefixes automatically in almost every spot. The one place where we have to add it back manually is the LGDT instruction. (The 0x67 address-size override prefix is also auto-generated.) This patch causes NASM to generate byte-identical object code (determined by disassembling both the pre-patch and post-patch versions, and comparing the listings), except: > @@ -158,7 +158,7 @@ > 00000142 6689D3 mov ebx,edx > 00000145 66B800000000 mov eax,0x0 > 0000014B 0F22D8 mov cr3,eax > -0000014E 67662E0F0155F6 o32 lgdt [cs:ebp-0xa] > +0000014E 2E66670F0155F6 o32 lgdt [cs:ebp-0xa] > 00000155 66B800000000 mov eax,0x0 > 0000015B 0F22E0 mov cr4,eax > 0000015E 66B9800000C0 mov ecx,0xc0000080 The only difference is the prefix list order, it changes from: - 0x67, 0x66, 0x2E to - 0x2E, 0x66, 0x67 (0x2E is "CS segment override"). Cc: Eric Dong <eric.dong@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=866 Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <lersek@redhat.com> --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm index 08534dba64b7..9231aa5b3ded 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm @@ -38,43 +38,42 @@ global ASM_PFX(gcSmmInitTemplate) ASM_PFX(gcSmiInitGdtr): DW 0 DQ 0 global ASM_PFX(SmmStartup) + +BITS 16 ASM_PFX(SmmStartup): - DB 0x66 mov eax, 0x80000001 ; read capability cpuid - DB 0x66 mov ebx, edx ; rdmsr will change edx. keep it in ebx. DB 0x66, 0xb8 ; mov eax, imm32 ASM_PFX(gSmmCr3): DD 0 mov cr3, eax - DB 0x67, 0x66 - lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - ASM_PFX(SmmStartup))] +o32 lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - ASM_PFX(SmmStartup))] DB 0x66, 0xb8 ; mov eax, imm32 ASM_PFX(gSmmCr4): DD 0 mov cr4, eax - DB 0x66 mov ecx, 0xc0000080 ; IA32_EFER MSR rdmsr - DB 0x66 test ebx, BIT20 ; check NXE capability jz .1 or ah, BIT3 ; set NXE bit wrmsr .1: DB 0x66, 0xb8 ; mov eax, imm32 ASM_PFX(gSmmCr0): DD 0 - DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, PROTECT_MODE_DS + mov di, PROTECT_MODE_DS mov cr0, eax DB 0x66, 0xea ; jmp far [ptr48] ASM_PFX(gSmmJmpAddr): DD @32bit DW PROTECT_MODE_CS + +BITS 32 @32bit: mov ds, edi mov es, edi mov fs, edi mov gs, edi mov ss, edi -- 2.14.1.3.gb7cf6e02401b ^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 2/3] UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from IA32 SmmStartup() 2018-01-30 15:33 ` [PATCH 2/3] UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from " Laszlo Ersek @ 2018-01-31 5:45 ` Ni, Ruiyu 0 siblings, 0 replies; 27+ messages in thread From: Ni, Ruiyu @ 2018-01-31 5:45 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01 Cc: Eric Dong, Jian J Wang, Jiewen Yao, Paolo Bonzini On 1/30/2018 11:33 PM, Laszlo Ersek wrote: > The SmmStartup() executes in SMM, which is very similar to real mode. Add > "BITS 16" before it and "BITS 32" after it (just before the @32bit label). > > Remove the manual 0x66 operand-size override prefixes, for selecting > 32-bit operands -- the sizes of our operands trigger NASM to insert the > prefixes automatically in almost every spot. The one place where we have > to add it back manually is the LGDT instruction. (The 0x67 address-size > override prefix is also auto-generated.) > > This patch causes NASM to generate byte-identical object code (determined > by disassembling both the pre-patch and post-patch versions, and comparing > the listings), except: > >> @@ -158,7 +158,7 @@ >> 00000142 6689D3 mov ebx,edx >> 00000145 66B800000000 mov eax,0x0 >> 0000014B 0F22D8 mov cr3,eax >> -0000014E 67662E0F0155F6 o32 lgdt [cs:ebp-0xa] >> +0000014E 2E66670F0155F6 o32 lgdt [cs:ebp-0xa] >> 00000155 66B800000000 mov eax,0x0 >> 0000015B 0F22E0 mov cr4,eax >> 0000015E 66B9800000C0 mov ecx,0xc0000080 > > The only difference is the prefix list order, it changes from: > > - 0x67, 0x66, 0x2E > > to > > - 0x2E, 0x66, 0x67 > > (0x2E is "CS segment override"). > > Cc: Eric Dong <eric.dong@intel.com> > Cc: Jian J Wang <jian.j.wang@intel.com> > Cc: Jiewen Yao <jiewen.yao@intel.com> > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Ruiyu Ni <ruiyu.ni@intel.com> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=866 > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Laszlo Ersek <lersek@redhat.com> > --- > UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 13 ++++++------- > 1 file changed, 6 insertions(+), 7 deletions(-) > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > index 08534dba64b7..9231aa5b3ded 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > @@ -38,43 +38,42 @@ global ASM_PFX(gcSmmInitTemplate) > > ASM_PFX(gcSmiInitGdtr): > DW 0 > DQ 0 > > global ASM_PFX(SmmStartup) > + > +BITS 16 > ASM_PFX(SmmStartup): > - DB 0x66 > mov eax, 0x80000001 ; read capability > cpuid > - DB 0x66 > mov ebx, edx ; rdmsr will change edx. keep it in ebx. > DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr3): DD 0 > mov cr3, eax > - DB 0x67, 0x66 > - lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - ASM_PFX(SmmStartup))] > +o32 lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - ASM_PFX(SmmStartup))] > DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr4): DD 0 > mov cr4, eax > - DB 0x66 > mov ecx, 0xc0000080 ; IA32_EFER MSR > rdmsr > - DB 0x66 > test ebx, BIT20 ; check NXE capability > jz .1 > or ah, BIT3 ; set NXE bit > wrmsr > .1: > DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr0): DD 0 > - DB 0xbf, PROTECT_MODE_DS, 0 ; mov di, PROTECT_MODE_DS > + mov di, PROTECT_MODE_DS > mov cr0, eax > DB 0x66, 0xea ; jmp far [ptr48] > ASM_PFX(gSmmJmpAddr): > DD @32bit > DW PROTECT_MODE_CS > + > +BITS 32 > @32bit: > mov ds, edi > mov es, edi > mov fs, edi > mov gs, edi > mov ss, edi > Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com> -- Thanks, Ray ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in IA32 SmmStartup() 2018-01-30 15:33 [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM Laszlo Ersek 2018-01-30 15:33 ` [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() Laszlo Ersek 2018-01-30 15:33 ` [PATCH 2/3] UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from " Laszlo Ersek @ 2018-01-30 15:33 ` Laszlo Ersek 2018-01-31 5:12 ` Ni, Ruiyu 2018-01-30 16:37 ` [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM Paolo Bonzini ` (2 subsequent siblings) 5 siblings, 1 reply; 27+ messages in thread From: Laszlo Ersek @ 2018-01-30 15:33 UTC (permalink / raw) To: edk2-devel-01; +Cc: Eric Dong, Jian J Wang, Jiewen Yao, Paolo Bonzini, Ruiyu Ni SMM emulation under KVM crashes the guest when the "jz" branch, added in commit d4d87596c11d ("UefiCpuPkg/PiSmmCpuDxeSmm: Enable NXE if it's supported", 2018-01-18), is taken. Rework the propagation of CPUID.80000001H:EDX.NX [bit 20] to IA32_EFER.NXE [bit 11] so that no code is executed conditionally. Cc: Eric Dong <eric.dong@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Ref: http://mid.mail-archive.com/d6fff558-6c4f-9ca6-74a7-e7cd9d007276@redhat.com Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <lersek@redhat.com> --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm index 9231aa5b3ded..102e0bdbabc8 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm @@ -44,26 +44,25 @@ global ASM_PFX(SmmStartup) BITS 16 ASM_PFX(SmmStartup): mov eax, 0x80000001 ; read capability cpuid mov ebx, edx ; rdmsr will change edx. keep it in ebx. + and ebx, BIT20 ; extract XD capability bit + shr ebx, 9 ; shift bit to IA32_EFER NXE position DB 0x66, 0xb8 ; mov eax, imm32 ASM_PFX(gSmmCr3): DD 0 mov cr3, eax o32 lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - ASM_PFX(SmmStartup))] DB 0x66, 0xb8 ; mov eax, imm32 ASM_PFX(gSmmCr4): DD 0 mov cr4, eax mov ecx, 0xc0000080 ; IA32_EFER MSR rdmsr - test ebx, BIT20 ; check NXE capability - jz .1 - or ah, BIT3 ; set NXE bit + or eax, ebx ; set NXE bit if XD is available wrmsr -.1: DB 0x66, 0xb8 ; mov eax, imm32 ASM_PFX(gSmmCr0): DD 0 mov di, PROTECT_MODE_DS mov cr0, eax DB 0x66, 0xea ; jmp far [ptr48] ASM_PFX(gSmmJmpAddr): -- 2.14.1.3.gb7cf6e02401b ^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in IA32 SmmStartup() 2018-01-30 15:33 ` [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in " Laszlo Ersek @ 2018-01-31 5:12 ` Ni, Ruiyu 0 siblings, 0 replies; 27+ messages in thread From: Ni, Ruiyu @ 2018-01-31 5:12 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01 Cc: Eric Dong, Jian J Wang, Jiewen Yao, Paolo Bonzini On 1/30/2018 11:33 PM, Laszlo Ersek wrote: > SMM emulation under KVM crashes the guest when the "jz" branch, added in > commit d4d87596c11d ("UefiCpuPkg/PiSmmCpuDxeSmm: Enable NXE if it's > supported", 2018-01-18), is taken. > > Rework the propagation of CPUID.80000001H:EDX.NX [bit 20] to IA32_EFER.NXE > [bit 11] so that no code is executed conditionally. > > Cc: Eric Dong <eric.dong@intel.com> > Cc: Jian J Wang <jian.j.wang@intel.com> > Cc: Jiewen Yao <jiewen.yao@intel.com> > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Ruiyu Ni <ruiyu.ni@intel.com> > Ref: http://mid.mail-archive.com/d6fff558-6c4f-9ca6-74a7-e7cd9d007276@redhat.com > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Laszlo Ersek <lersek@redhat.com> > --- > UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 7 +++---- > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > index 9231aa5b3ded..102e0bdbabc8 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > @@ -44,26 +44,25 @@ global ASM_PFX(SmmStartup) > > BITS 16 > ASM_PFX(SmmStartup): > mov eax, 0x80000001 ; read capability > cpuid > mov ebx, edx ; rdmsr will change edx. keep it in ebx. > + and ebx, BIT20 ; extract XD capability bit Per CPUID_EXTENDED_CPU_SIG_EDX definition in UefiCpuPkg/Include/Register/CpuId.h, the BIT name is NX. > + shr ebx, 9 ; shift bit to IA32_EFER NXE position How about changing above comments to: ; shift bit to IA32_EFER.NXE[BIT11] position? > DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr3): DD 0 > mov cr3, eax > o32 lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - ASM_PFX(SmmStartup))] > DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr4): DD 0 > mov cr4, eax > mov ecx, 0xc0000080 ; IA32_EFER MSR > rdmsr > - test ebx, BIT20 ; check NXE capability > - jz .1 > - or ah, BIT3 ; set NXE bit > + or eax, ebx ; set NXE bit if XD is available ; Bit name is NX. > wrmsr > -.1: > DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr0): DD 0 > mov di, PROTECT_MODE_DS > mov cr0, eax > DB 0x66, 0xea ; jmp far [ptr48] > ASM_PFX(gSmmJmpAddr): > Very clever solution to remove jz. With the minor comments update, Reviewed-by: Ruiyu Ni <ruiyu.ni@Intel.com> -- Thanks, Ray ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM 2018-01-30 15:33 [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM Laszlo Ersek ` (2 preceding siblings ...) 2018-01-30 15:33 ` [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in " Laszlo Ersek @ 2018-01-30 16:37 ` Paolo Bonzini 2018-01-31 12:17 ` Laszlo Ersek 2018-02-01 1:20 ` Wang, Jian J 5 siblings, 0 replies; 27+ messages in thread From: Paolo Bonzini @ 2018-01-30 16:37 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01; +Cc: Eric Dong, Jian J Wang, Jiewen Yao, Ruiyu Ni On 30/01/2018 10:33, Laszlo Ersek wrote: > Repo: https://github.com/lersek/edk2.git > Branch: smm_startup_ia32_nocond > > This small series fixes the IA32 SMM regression on KVM that I reported > recently. The first two patches are cleanups (no functional changes), > the third patch is the fix. > > Cc: Eric Dong <eric.dong@intel.com> > Cc: Jian J Wang <jian.j.wang@intel.com> > Cc: Jiewen Yao <jiewen.yao@intel.com> > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Paolo > Thanks > Laszlo > > Laszlo Ersek (3): > UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() > UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from IA32 SmmStartup() > UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in IA32 > SmmStartup() > > UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 28 +++++++++----------- > 1 file changed, 13 insertions(+), 15 deletions(-) > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM 2018-01-30 15:33 [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM Laszlo Ersek ` (3 preceding siblings ...) 2018-01-30 16:37 ` [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM Paolo Bonzini @ 2018-01-31 12:17 ` Laszlo Ersek 2018-02-01 1:20 ` Wang, Jian J 5 siblings, 0 replies; 27+ messages in thread From: Laszlo Ersek @ 2018-01-31 12:17 UTC (permalink / raw) To: edk2-devel-01; +Cc: Ruiyu Ni, Jiewen Yao, Eric Dong, Paolo Bonzini On 01/30/18 16:33, Laszlo Ersek wrote: > Repo: https://github.com/lersek/edk2.git > Branch: smm_startup_ia32_nocond > > This small series fixes the IA32 SMM regression on KVM that I reported > recently. The first two patches are cleanups (no functional changes), > the third patch is the fix. > > Cc: Eric Dong <eric.dong@intel.com> > Cc: Jian J Wang <jian.j.wang@intel.com> > Cc: Jiewen Yao <jiewen.yao@intel.com> > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Ruiyu Ni <ruiyu.ni@intel.com> > > Thanks > Laszlo > > Laszlo Ersek (3): > UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() > UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from IA32 SmmStartup() > UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in IA32 > SmmStartup() > > UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 28 +++++++++----------- > 1 file changed, 13 insertions(+), 15 deletions(-) > Code differences between the posted version and the pushed version, according to Ray's comments for patch #3, displayed with "git diff --word-diff" (look for [-...-] and {+...+} markers): > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > index 102e0bdbabc8..d64fcd48d03e 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm > @@ -47,8 +47,8 @@ ASM_PFX(SmmStartup): > mov eax, 0x80000001 ; read capability > cpuid > mov ebx, edx ; rdmsr will change edx. keep it in ebx. > and ebx, BIT20 ; extract [-XD-]{+NX+} capability bit > shr ebx, 9 ; shift bit to [-IA32_EFER NXE-]{+IA32_EFER.NXE[BIT11]+} position > DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr3): DD 0 > mov cr3, eax > @@ -58,7 +58,7 @@ ASM_PFX(gSmmCr4): DD 0 > mov cr4, eax > mov ecx, 0xc0000080 ; IA32_EFER MSR > rdmsr > or eax, ebx ; set NXE bit if [-XD-]{+NX+} is available > wrmsr > DB 0x66, 0xb8 ; mov eax, imm32 > ASM_PFX(gSmmCr0): DD 0 Series pushed as d5988a8ac971..8d4d55b15b58. Let's continue the PatchAssembly() discussion; once we reach an agreement on that, I'll post patches for that too. Thanks! Laszlo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM 2018-01-30 15:33 [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM Laszlo Ersek ` (4 preceding siblings ...) 2018-01-31 12:17 ` Laszlo Ersek @ 2018-02-01 1:20 ` Wang, Jian J 5 siblings, 0 replies; 27+ messages in thread From: Wang, Jian J @ 2018-02-01 1:20 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01 Cc: Dong, Eric, Yao, Jiewen, Paolo Bonzini, Ni, Ruiyu Hi Laszlo, Thank you very much for fixing this issue. Regards, Jian > -----Original Message----- > From: Laszlo Ersek [mailto:lersek@redhat.com] > Sent: Tuesday, January 30, 2018 11:34 PM > To: edk2-devel-01 <edk2-devel@lists.01.org> > Cc: Dong, Eric <eric.dong@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; > Yao, Jiewen <jiewen.yao@intel.com>; Paolo Bonzini <pbonzini@redhat.com>; > Ni, Ruiyu <ruiyu.ni@intel.com> > Subject: [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() > regression on KVM > > Repo: https://github.com/lersek/edk2.git > Branch: smm_startup_ia32_nocond > > This small series fixes the IA32 SMM regression on KVM that I reported > recently. The first two patches are cleanups (no functional changes), > the third patch is the fix. > > Cc: Eric Dong <eric.dong@intel.com> > Cc: Jian J Wang <jian.j.wang@intel.com> > Cc: Jiewen Yao <jiewen.yao@intel.com> > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Ruiyu Ni <ruiyu.ni@intel.com> > > Thanks > Laszlo > > Laszlo Ersek (3): > UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() > UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from IA32 > SmmStartup() > UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in IA32 > SmmStartup() > > UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm | 28 +++++++++----------- > 1 file changed, 13 insertions(+), 15 deletions(-) > > -- > 2.14.1.3.gb7cf6e02401b ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2018-02-02 13:31 UTC | newest] Thread overview: 27+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-01-30 15:33 [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM Laszlo Ersek 2018-01-30 15:33 ` [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: update comments in IA32 SmmStartup() Laszlo Ersek 2018-01-30 17:22 ` Kinney, Michael D 2018-01-30 18:17 ` Laszlo Ersek 2018-01-30 20:31 ` Kinney, Michael D 2018-01-30 21:26 ` Kinney, Michael D 2018-01-30 21:55 ` Laszlo Ersek 2018-01-30 21:45 ` Laszlo Ersek 2018-01-30 22:25 ` Kinney, Michael D 2018-01-31 5:44 ` Ni, Ruiyu 2018-01-31 5:54 ` Ni, Ruiyu 2018-01-31 10:56 ` Laszlo Ersek 2018-01-31 10:42 ` Laszlo Ersek 2018-01-31 10:40 ` Laszlo Ersek 2018-01-31 22:11 ` Kinney, Michael D 2018-02-02 6:05 ` Laszlo Ersek 2018-02-02 10:06 ` Ard Biesheuvel 2018-02-02 13:26 ` Laszlo Ersek 2018-02-02 13:28 ` Leif Lindholm 2018-02-02 13:36 ` Laszlo Ersek 2018-01-30 15:33 ` [PATCH 2/3] UefiCpuPkg/PiSmmCpuDxeSmm: remove unneeded DBs from " Laszlo Ersek 2018-01-31 5:45 ` Ni, Ruiyu 2018-01-30 15:33 ` [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in " Laszlo Ersek 2018-01-31 5:12 ` Ni, Ruiyu 2018-01-30 16:37 ` [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: fix IA32 SmmStartup() regression on KVM Paolo Bonzini 2018-01-31 12:17 ` Laszlo Ersek 2018-02-01 1:20 ` Wang, Jian J
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox