On 6 September 2015 at 14:22, Leif Lindholm <leif.lindh...@linaro.org> wrote: > On 6 September 2015 at 13:05, Ard Biesheuvel <ard.biesheu...@linaro.org> > wrote: >> On 6 September 2015 at 14:04, Leif Lindholm <leif.lindh...@linaro.org> wrote: >>> On 6 September 2015 at 12:52, Ard Biesheuvel <ard.biesheu...@linaro.org> >>> wrote: >>>> On 6 September 2015 at 10:15, Heyi Guo <heyi....@linaro.org> wrote: >>>>> There is a hidden bug for below code: >>>>> >>>>> (1 << BaseAddressAlignment) & *BlockEntrySize >>>>> >>>>> From disassembly code, we can the literal number 1 will be treated as >>>>> INT32 by compiler by default, and we'll get 0xFFFFFFFF80000000 when >>>>> BaseAddressAlignment is equal to 31. So we will always get 31 when >>>>> alignment is larger than 31. >>>>> >>>>> if ((1 << BaseAddressAlignment) & *BlockEntrySize) { >>>>> 5224: f9404be0 ldr x0, [sp,#144] >>>>> 5228: 2a0003e1 mov w1, w0 >>>>> 522c: 52800020 mov w0, #0x1 // #1 >>>>> 5230: 1ac12000 lsl w0, w0, w1 >>>>> 5234: 93407c01 sxtw x1, w0 >>>>> >>>>> The bug can be replayed on QEMU AARCH64; by adding some debug print, >>>>> we can see lots of level 1 tables created (for block of 1GB) even >>>>> when the region is large enough to use 512GB block size. >>>>> >>>>> Contributed-under: TianoCore Contribution Agreement 1.0 >>>>> Signed-off-by: Heyi Guo <heyi....@linaro.org> >>>>> Cc: Leif Lindholm <leif.lindh...@linaro.org> >>>>> Cc: Ard Biesheuvel <ard.biesheu...@linaro.org> >>>>> --- >>>>> ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c | 6 ++++-- >>>>> 1 file changed, 4 insertions(+), 2 deletions(-) >>>>> >>>>> diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c >>>>> b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c >>>>> index e7b095c..b039ae1 100644 >>>>> --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c >>>>> +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c >>>>> @@ -295,14 +295,16 @@ GetBlockEntryListFromAddress ( >>>>> if (RegionStart == 0) { >>>>> // Identify the highest possible alignment for the Region Size >>>>> for (BaseAddressAlignment = 0; BaseAddressAlignment < 64; >>>>> BaseAddressAlignment++) { >>>>> - if ((1 << BaseAddressAlignment) & *BlockEntrySize) { >>>>> + // Type casting is needed as literal number will be treated as >>>>> INT32 by >>>>> + // compiler >>>>> + if (((UINT64) 1 << BaseAddressAlignment) & *BlockEntrySize) { >>>> >>>> Please use '1UL' instead of '(UINT64) 1' >>> >>> Wouldn't 1ULL be a better choice? >>> To still work if someone was to copy code across to a 32-bit arch. >>> >> >> Perhaps yes, although I think it's the 'U' that makes the difference >> here, not the number of Ls :-) > > For this location, certainly. > But if the same code was compiled on a 32-bit architecture, it would. > UINT64 is the portable way to specify this, but at least ULL means the > same on 32- and 64-bit. UL does not. >
Ehm, looking at the surrounding code, we should probably just be using LowBitSet64() instead of open coding it. _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel