Re: [edk2] [PATCH v3 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM
On 11 June 2018 at 17:51, Gao, Liming wrote: > Reviewed-by: Liming Gao > Pushed as 4134f2bddcb68d2e20ed000cdf54abf3f1140904 Thanks all >> -Original Message- >> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Ard >> Biesheuvel >> Sent: Monday, June 11, 2018 3:26 PM >> To: edk2-devel@lists.01.org >> Cc: Kinney, Michael D ; ler...@redhat.com; Gao, >> Liming ; >> leif.lindh...@linaro.org; Ard Biesheuvel >> Subject: [edk2] [PATCH v3 1/2] MdePkg/BaseIoLibIntrinsic: make >> BaseIoLibIntrinsic safe for ArmVirt/KVM >> >> KVM on ARM refuses to decode load/store instructions used to perform >> I/O to emulated devices, and instead relies on the exception syndrome >> information to describe the operand register, access size, etc. >> This is only possible for instructions that have a single input/output >> register (as opposed to ones that increment the offset register, or >> load/store pair instructions, etc). Otherwise, QEMU crashes with the >> following error >> >> error: kvm run failed Function not implemented >> R00=01010101 R01=0008 R02=0048 R03=08000820 >> R04=0120 R05=7faaa0e0 R06=7faaa0dc R07=7faaa0e8 >> R08=7faaa0ec R09=7faaa088 R10=00ff R11=0080 >> R12=ff00 R13=7fccfe08 R14=7faa835f R15=7faa887c >> PSR=81f3 N--- T svc32 >> QEMU: Terminated >> >> and KVM produces a warning such as the following in the kernel log >> >> kvm [17646]: load/store instruction decoding not implemented >> >> The IoLib implementation provided by MdePkg/Library/BaseIoLibIntrinsic >> is based on C code, and when LTO is in effect, the MMIO accesses could >> be merged with, e.g., manipulations of the loop counter, producing >> opcodes that KVM does not support for emulated MMIO. >> >> So let's add a special ArmVirt flavor of this library that implements >> that actual load/store operations in assembler, ensuring that the >> instructions involved can be emulated by KVM. >> >> Contributed-under: TianoCore Contribution Agreement 1.1 >> Signed-off-by: Ard Biesheuvel >> --- >> v3: add missing prototype comments in IoLibArmVirt.c >> remove mention of ASSERT () from description of internal asm routines >> v2: add missing .uni file >> split off ArmVirtPkg change >> add VS2017 version of AArch64 asm file >> add reference to MdePkg.dsc >> >> MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S | 148 >> MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.asm | 149 >> MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.S | 145 >> MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.asm | 149 >> MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf | 52 ++ >> MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.uni | 23 + >> MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c| 733 >> >> MdePkg/MdePkg.dsc | 1 + >> 8 files changed, 1400 insertions(+) >> >> diff --git a/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S >> b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S >> new file mode 100644 >> index ..85f59324270c >> --- /dev/null >> +++ b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S >> @@ -0,0 +1,148 @@ >> +# >> +# Copyright (c) 2014-2018, Linaro Limited. All rights reserved. >> +# >> +# This program and the accompanying materials are licensed and made >> available >> +# under the terms and conditions of the BSD License which accompanies this >> +# distribution. The full text of the license may be found at >> +# http://opensource.org/licenses/bsd-license.php >> +# >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR >> IMPLIED. >> +# >> +# >> + >> +.text >> +.align 3 >> + >> +GCC_ASM_EXPORT(MmioRead8Internal) >> +GCC_ASM_EXPORT(MmioWrite8Internal) >> +GCC_ASM_EXPORT(MmioRead16Internal) >> +GCC_ASM_EXPORT(MmioWrite16Internal) >> +GCC_ASM_EXPORT(MmioRead32Internal) >> +GCC_ASM_EXPORT(MmioWrite32Internal) >> +GCC_ASM_EXPORT(MmioRead64Internal) >> +GCC_ASM_EXPORT(MmioWrite64Internal) >> + >> +// >> +// Reads an 8-bit MMIO register. >> +// >> +// Reads the 8-bit MMIO register specified by Address. The 8-bit read >> value is >> +// returned. This function must guarantee that all MMIO read and write >> +// operations are serialized. >> +// >> +// @param Address The MMIO register to read. >> +// >> +// @return The value read. >> +// >> +ASM_PFX(MmioRead8Internal): >> + ldrbw0, [x0] >> + dmb ld >> + ret >> + >> +// >> +// Writes an 8-bit MMIO register. >> +// >> +// Writes the 8-bit MMIO register specified by Address with the value >> specified >> +// by Value and returns Value. This function must guarantee that all MMIO >> read >> +// and write operations are serialized. >> +// >> +// @param Address The MMIO register to
Re: [edk2] [PATCH v3 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM
Reviewed-by: Liming Gao > -Original Message- > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Ard > Biesheuvel > Sent: Monday, June 11, 2018 3:26 PM > To: edk2-devel@lists.01.org > Cc: Kinney, Michael D ; ler...@redhat.com; Gao, > Liming ; > leif.lindh...@linaro.org; Ard Biesheuvel > Subject: [edk2] [PATCH v3 1/2] MdePkg/BaseIoLibIntrinsic: make > BaseIoLibIntrinsic safe for ArmVirt/KVM > > KVM on ARM refuses to decode load/store instructions used to perform > I/O to emulated devices, and instead relies on the exception syndrome > information to describe the operand register, access size, etc. > This is only possible for instructions that have a single input/output > register (as opposed to ones that increment the offset register, or > load/store pair instructions, etc). Otherwise, QEMU crashes with the > following error > > error: kvm run failed Function not implemented > R00=01010101 R01=0008 R02=0048 R03=08000820 > R04=0120 R05=7faaa0e0 R06=7faaa0dc R07=7faaa0e8 > R08=7faaa0ec R09=7faaa088 R10=00ff R11=0080 > R12=ff00 R13=7fccfe08 R14=7faa835f R15=7faa887c > PSR=81f3 N--- T svc32 > QEMU: Terminated > > and KVM produces a warning such as the following in the kernel log > > kvm [17646]: load/store instruction decoding not implemented > > The IoLib implementation provided by MdePkg/Library/BaseIoLibIntrinsic > is based on C code, and when LTO is in effect, the MMIO accesses could > be merged with, e.g., manipulations of the loop counter, producing > opcodes that KVM does not support for emulated MMIO. > > So let's add a special ArmVirt flavor of this library that implements > that actual load/store operations in assembler, ensuring that the > instructions involved can be emulated by KVM. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel > --- > v3: add missing prototype comments in IoLibArmVirt.c > remove mention of ASSERT () from description of internal asm routines > v2: add missing .uni file > split off ArmVirtPkg change > add VS2017 version of AArch64 asm file > add reference to MdePkg.dsc > > MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S | 148 > MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.asm | 149 > MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.S | 145 > MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.asm | 149 > MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf | 52 ++ > MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.uni | 23 + > MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c| 733 > > MdePkg/MdePkg.dsc | 1 + > 8 files changed, 1400 insertions(+) > > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S > b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S > new file mode 100644 > index ..85f59324270c > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S > @@ -0,0 +1,148 @@ > +# > +# Copyright (c) 2014-2018, Linaro Limited. All rights reserved. > +# > +# This program and the accompanying materials are licensed and made > available > +# under the terms and conditions of the BSD License which accompanies this > +# distribution. The full text of the license may be found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR > IMPLIED. > +# > +# > + > +.text > +.align 3 > + > +GCC_ASM_EXPORT(MmioRead8Internal) > +GCC_ASM_EXPORT(MmioWrite8Internal) > +GCC_ASM_EXPORT(MmioRead16Internal) > +GCC_ASM_EXPORT(MmioWrite16Internal) > +GCC_ASM_EXPORT(MmioRead32Internal) > +GCC_ASM_EXPORT(MmioWrite32Internal) > +GCC_ASM_EXPORT(MmioRead64Internal) > +GCC_ASM_EXPORT(MmioWrite64Internal) > + > +// > +// Reads an 8-bit MMIO register. > +// > +// Reads the 8-bit MMIO register specified by Address. The 8-bit read value > is > +// returned. This function must guarantee that all MMIO read and write > +// operations are serialized. > +// > +// @param Address The MMIO register to read. > +// > +// @return The value read. > +// > +ASM_PFX(MmioRead8Internal): > + ldrbw0, [x0] > + dmb ld > + ret > + > +// > +// Writes an 8-bit MMIO register. > +// > +// Writes the 8-bit MMIO register specified by Address with the value > specified > +// by Value and returns Value. This function must guarantee that all MMIO > read > +// and write operations are serialized. > +// > +// @param Address The MMIO register to write. > +// @param Value The value to write to the MMIO register. > +// > +ASM_PFX(MmioWrite8Internal): > + dmb st > + strbw1, [x0] > + ret > + > +// > +// Reads a 16-bit MMIO register. > +// > +// Reads the
Re: [edk2] [PATCH v3 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM
On 06/11/18 09:25, Ard Biesheuvel wrote: > KVM on ARM refuses to decode load/store instructions used to perform > I/O to emulated devices, and instead relies on the exception syndrome > information to describe the operand register, access size, etc. > This is only possible for instructions that have a single input/output > register (as opposed to ones that increment the offset register, or > load/store pair instructions, etc). Otherwise, QEMU crashes with the > following error > > error: kvm run failed Function not implemented > R00=01010101 R01=0008 R02=0048 R03=08000820 > R04=0120 R05=7faaa0e0 R06=7faaa0dc R07=7faaa0e8 > R08=7faaa0ec R09=7faaa088 R10=00ff R11=0080 > R12=ff00 R13=7fccfe08 R14=7faa835f R15=7faa887c > PSR=81f3 N--- T svc32 > QEMU: Terminated > > and KVM produces a warning such as the following in the kernel log > > kvm [17646]: load/store instruction decoding not implemented > > The IoLib implementation provided by MdePkg/Library/BaseIoLibIntrinsic > is based on C code, and when LTO is in effect, the MMIO accesses could > be merged with, e.g., manipulations of the loop counter, producing > opcodes that KVM does not support for emulated MMIO. > > So let's add a special ArmVirt flavor of this library that implements > that actual load/store operations in assembler, ensuring that the > instructions involved can be emulated by KVM. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel > --- > v3: add missing prototype comments in IoLibArmVirt.c > remove mention of ASSERT () from description of internal asm routines > v2: add missing .uni file > split off ArmVirtPkg change > add VS2017 version of AArch64 asm file > add reference to MdePkg.dsc > > MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S | 148 > MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.asm | 149 > MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.S | 145 > MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.asm | 149 > MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf | 52 ++ > MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.uni | 23 + > MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c| 733 > > MdePkg/MdePkg.dsc | 1 + > 8 files changed, 1400 insertions(+) Acked-by: Laszlo Ersek ___ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel