* [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
@ 2021-05-12 4:53 Ni, Ray
2021-05-13 3:32 ` Dong, Eric
2021-05-14 10:55 ` [edk2-devel] " Laszlo Ersek
0 siblings, 2 replies; 10+ messages in thread
From: Ni, Ray @ 2021-05-12 4:53 UTC (permalink / raw)
To: devel; +Cc: Eric Dong, Laszlo Ersek, Rahul Kumar
5-level paging can be enabled on CPU which supports up to 52 physical
address size. But when the feature was enabled, the 48 address size
limit was not removed and the 5-level paging testing didn't access
address >= 2^48. So the issue wasn't detected until recently an
address >= 2^48 is accessed.
Change-Id: Iaedc73be318d4b4122071efc3ba6e967a4b58fc3
Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
---
UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
index fd6583f9d1..89143810b6 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
@@ -1887,11 +1887,13 @@ InitializeMpServiceData (
IN UINTN ShadowStackSize
)
{
- UINT32 Cr3;
- UINTN Index;
- UINT8 *GdtTssTables;
- UINTN GdtTableStepSize;
- CPUID_VERSION_INFO_EDX RegEdx;
+ UINT32 Cr3;
+ UINTN Index;
+ UINT8 *GdtTssTables;
+ UINTN GdtTableStepSize;
+ CPUID_VERSION_INFO_EDX RegEdx;
+ UINT32 MaxExtendedFunction;
+ CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
//
// Determine if this CPU supports machine check
@@ -1918,9 +1920,17 @@ InitializeMpServiceData (
// Initialize physical address mask
// NOTE: Physical memory above virtual address limit is not supported !!!
//
- AsmCpuid (0x80000008, (UINT32*)&Index, NULL, NULL, NULL);
- gPhyMask = LShiftU64 (1, (UINT8)Index) - 1;
- gPhyMask &= (1ull << 48) - EFI_PAGE_SIZE;
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunction, NULL, NULL, NULL);
+ if (MaxExtendedFunction >= CPUID_VIR_PHY_ADDRESS_SIZE) {
+ AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);
+ } else {
+ VirPhyAddressSize.Bits.PhysicalAddressBits = 36;
+ }
+ gPhyMask = LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddressBits) - 1;
+ //
+ // Clear the low 12 bits
+ //
+ gPhyMask &= 0xfffffffffffff000ULL;
//
// Create page tables
--
2.31.1.windows.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
2021-05-12 4:53 [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation Ni, Ray
@ 2021-05-13 3:32 ` Dong, Eric
2021-05-14 10:55 ` [edk2-devel] " Laszlo Ersek
1 sibling, 0 replies; 10+ messages in thread
From: Dong, Eric @ 2021-05-13 3:32 UTC (permalink / raw)
To: Ni, Ray, devel@edk2.groups.io; +Cc: Laszlo Ersek, Kumar, Rahul1
Reviewed-by: Eric Dong <eric.dong@intel.com>
-----Original Message-----
From: Ni, Ray <ray.ni@intel.com>
Sent: Wednesday, May 12, 2021 12:53 PM
To: devel@edk2.groups.io
Cc: Dong, Eric <eric.dong@intel.com>; Laszlo Ersek <lersek@redhat.com>; Kumar, Rahul1 <rahul1.kumar@intel.com>
Subject: [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
5-level paging can be enabled on CPU which supports up to 52 physical
address size. But when the feature was enabled, the 48 address size
limit was not removed and the 5-level paging testing didn't access
address >= 2^48. So the issue wasn't detected until recently an
address >= 2^48 is accessed.
Change-Id: Iaedc73be318d4b4122071efc3ba6e967a4b58fc3
Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
---
UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
index fd6583f9d1..89143810b6 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
@@ -1887,11 +1887,13 @@ InitializeMpServiceData (
IN UINTN ShadowStackSize
)
{
- UINT32 Cr3;
- UINTN Index;
- UINT8 *GdtTssTables;
- UINTN GdtTableStepSize;
- CPUID_VERSION_INFO_EDX RegEdx;
+ UINT32 Cr3;
+ UINTN Index;
+ UINT8 *GdtTssTables;
+ UINTN GdtTableStepSize;
+ CPUID_VERSION_INFO_EDX RegEdx;
+ UINT32 MaxExtendedFunction;
+ CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
//
// Determine if this CPU supports machine check
@@ -1918,9 +1920,17 @@ InitializeMpServiceData (
// Initialize physical address mask
// NOTE: Physical memory above virtual address limit is not supported !!!
//
- AsmCpuid (0x80000008, (UINT32*)&Index, NULL, NULL, NULL);
- gPhyMask = LShiftU64 (1, (UINT8)Index) - 1;
- gPhyMask &= (1ull << 48) - EFI_PAGE_SIZE;
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunction, NULL, NULL, NULL);
+ if (MaxExtendedFunction >= CPUID_VIR_PHY_ADDRESS_SIZE) {
+ AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);
+ } else {
+ VirPhyAddressSize.Bits.PhysicalAddressBits = 36;
+ }
+ gPhyMask = LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddressBits) - 1;
+ //
+ // Clear the low 12 bits
+ //
+ gPhyMask &= 0xfffffffffffff000ULL;
//
// Create page tables
--
2.31.1.windows.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
2021-05-12 4:53 [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation Ni, Ray
2021-05-13 3:32 ` Dong, Eric
@ 2021-05-14 10:55 ` Laszlo Ersek
2021-05-15 0:04 ` Ni, Ray
1 sibling, 1 reply; 10+ messages in thread
From: Laszlo Ersek @ 2021-05-14 10:55 UTC (permalink / raw)
To: devel, ray.ni; +Cc: Eric Dong, Rahul Kumar
On 05/12/21 06:53, Ni, Ray wrote:
> 5-level paging can be enabled on CPU which supports up to 52 physical
> address size. But when the feature was enabled, the 48 address size
> limit was not removed and the 5-level paging testing didn't access
> address >= 2^48. So the issue wasn't detected until recently an
> address >= 2^48 is accessed.
>
> Change-Id: Iaedc73be318d4b4122071efc3ba6e967a4b58fc3
(1) Please drop the Change-Id from the upstream patch.
> Signed-off-by: Ray Ni <ray.ni@intel.com>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> ---
> UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 26 ++++++++++++++++++--------
> 1 file changed, 18 insertions(+), 8 deletions(-)
>
> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
> index fd6583f9d1..89143810b6 100644
> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
> @@ -1887,11 +1887,13 @@ InitializeMpServiceData (
> IN UINTN ShadowStackSize
> )
> {
> - UINT32 Cr3;
> - UINTN Index;
> - UINT8 *GdtTssTables;
> - UINTN GdtTableStepSize;
> - CPUID_VERSION_INFO_EDX RegEdx;
> + UINT32 Cr3;
> + UINTN Index;
> + UINT8 *GdtTssTables;
> + UINTN GdtTableStepSize;
> + CPUID_VERSION_INFO_EDX RegEdx;
> + UINT32 MaxExtendedFunction;
> + CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
>
> //
> // Determine if this CPU supports machine check
> @@ -1918,9 +1920,17 @@ InitializeMpServiceData (
> // Initialize physical address mask
> // NOTE: Physical memory above virtual address limit is not supported !!!
> //
> - AsmCpuid (0x80000008, (UINT32*)&Index, NULL, NULL, NULL);
> - gPhyMask = LShiftU64 (1, (UINT8)Index) - 1;
> - gPhyMask &= (1ull << 48) - EFI_PAGE_SIZE;
> + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunction, NULL, NULL, NULL);
> + if (MaxExtendedFunction >= CPUID_VIR_PHY_ADDRESS_SIZE) {
> + AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);
> + } else {
> + VirPhyAddressSize.Bits.PhysicalAddressBits = 36;
> + }
> + gPhyMask = LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddressBits) - 1;
> + //
> + // Clear the low 12 bits
> + //
> + gPhyMask &= 0xfffffffffffff000ULL;
>
> //
> // Create page tables
>
(2) Please introduce the following (new) function to UefiCpuLib:
/**
Get the physical address width supported by the processor.
@param[out] ValidAddressMask Bitmask with valid address bits set to
one; other bits are clear. Optional
parameter.
@param[out] ValidPageBaseAddressMask Bitmask with valid page base address
bits set to one; other bits are clear.
Optional parameter.
@return The physical address width supported by the processor.
**/
UINT8
EFIAPI
GetPhysicalAddressBits (
OUT UINT64 *ValidAddressMask OPTIONAL,
OUT UINT64 *ValidPageBaseAddressMask OPTIONAL
)
{
UINT32 MaxExtendedFunction;
CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
UINT64 AddressMask;
UINT64 PageBaseAddressMask;
AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunction, NULL, NULL, NULL);
if (MaxExtendedFunction >= CPUID_VIR_PHY_ADDRESS_SIZE) {
AsmCpuid (
CPUID_VIR_PHY_ADDRESS_SIZE,
&VirPhyAddressSize.Uint32,
NULL,
NULL,
NULL
);
} else {
VirPhyAddressSize.Bits.PhysicalAddressBits = 36;
}
AddressMask = LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddressBits) - 1;
PageBaseAddressMask = AddressMask & ~(UINT64)EFI_PAGE_MASK;
if (ValidAddressMask != NULL) {
*ValidAddressMask = AddressMask;
}
if (ValidPageBaseAddressMask != NULL) {
*ValidPageBaseAddressMask = PageBaseAddressMask;
}
return VirPhyAddressSize.Bits.PhysicalAddressBits;
}
(3) In a separate patch, please rewrite the MtrrLibInitializeMtrrMask()
function in "UefiCpuPkg/Library/MtrrLib/MtrrLib.c", to make use of the
new GetPhysicalAddressBits() function.
(4) In a separate patch, please rewrite the Is5LevelPagingNeeded()
function in "UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c", to make use of
the new GetPhysicalAddressBits() function.
(5) Please rework the current patch so that we simply call
GetPhysicalAddressBits (NULL, &gPhyMask);
in the InitializeMpServiceData() function, in
"UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c".
... Please realize that the current bug exists *precisely* because peole
have always been too lazy to introduce the GetPhysicalAddressBits()
helper function, and they've just gone around duplicating code like
there's no tomorrow. The solution to the problem is *NOT* to introduce
yet another naked CPUID_VIR_PHY_ADDRESS_SIZE call!
Thanks
Laszlo
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
2021-05-14 10:55 ` [edk2-devel] " Laszlo Ersek
@ 2021-05-15 0:04 ` Ni, Ray
2021-05-16 1:39 ` Laszlo Ersek
0 siblings, 1 reply; 10+ messages in thread
From: Ni, Ray @ 2021-05-15 0:04 UTC (permalink / raw)
To: Laszlo Ersek, devel
[-- Attachment #1: Type: text/plain, Size: 954 bytes --]
Laszlo,
Do you think that another API is also needed: GetPhysicalAddressWidth() that returns number 36/52?
physical address width is needed by (besides those that rely on the width for mask calculation):
UefiCpuPkg\CpuMpPei\CpuPaging.c
UefiCpuPkg\PiSmmCpuDxeSmm\X64\PageTbl.c
MdeModulePkg\Core\DxeIplPeim\X64\VirtualMemory.c
MdeModulePkg\Universal\Acpi\S3SaveStateDxe\AcpiS3ContextSave.c
MdeModulePkg\Universal\CapsulePei\UefiCapsule.c
MdePkg\Library\SmmIoLib\SmmIoLib.c
OvmfPkg\XenPlatformPei\MemDetect.c
UefiCpuPkg\Universal\Acpi\S3Resume2Pei\S3Resume.c
UefiPayloadPkg\UefiPayloadEntry\X64\VirtualMemory.c
GetPhysicalAddressMask() can call GetPhysicalAddressWidth().
Since it's a large-scale change but the SMM high MMIO access bug is critical/urgent, I prefer to firstly push this bug fix change and then work on the new APIs.
https://bugzilla.tianocore.org/show_bug.cgi?id=3394 was submitted to capture this.
[-- Attachment #2: Type: text/html, Size: 1062 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
2021-05-15 0:04 ` Ni, Ray
@ 2021-05-16 1:39 ` Laszlo Ersek
2021-05-18 7:51 ` Ni, Ray
0 siblings, 1 reply; 10+ messages in thread
From: Laszlo Ersek @ 2021-05-16 1:39 UTC (permalink / raw)
To: devel, ray.ni
On 05/15/21 02:04, Ni, Ray wrote:
> Laszlo,
> Do you think that another API is also needed: GetPhysicalAddressWidth() that returns number 36/52?
No. The GetPhysicalAddressBits() function that I proposed already returns this information. It has three outputs: the number of bits (that is, the width), as return value, and the two optional output parameters.
So if you only need the the bit count, call
GetPhysicalAddressBits (NULL, NULL);
These calculations are so cheap and small that keeping them in a single function makes a lot of sense in my opinion.
> physical address width is needed by (besides those that rely on the width for mask calculation):
> UefiCpuPkg\CpuMpPei\CpuPaging.c
> UefiCpuPkg\PiSmmCpuDxeSmm\X64\PageTbl.c
> MdeModulePkg\Core\DxeIplPeim\X64\VirtualMemory.c
> MdeModulePkg\Universal\Acpi\S3SaveStateDxe\AcpiS3ContextSave.c
> MdeModulePkg\Universal\CapsulePei\UefiCapsule.c
> MdePkg\Library\SmmIoLib\SmmIoLib.c
> OvmfPkg\XenPlatformPei\MemDetect.c
> UefiCpuPkg\Universal\Acpi\S3Resume2Pei\S3Resume.c
> UefiPayloadPkg\UefiPayloadEntry\X64\VirtualMemory.c
Ah, I couldn't find those because the AsmCpuid() calls in them don't even use the symbolic names for 0x80000008 (CPUID_VIR_PHY_ADDRESS_SIZE) and for the least significant byte of EAX on output (CPUID_VIR_PHY_ADDRESS_SIZE_EAX.Bits.PhysicalAddressBits).
So it's even worse (much worse) than I expected :(
Because of the MdePkg and MdeModulePkg dependencies, we can't even put the helper in UefiCpuPkg; it must go into MdePkg (possibly BaseLib, I'm not sure).
>
>
> GetPhysicalAddressMask() can call GetPhysicalAddressWidth().
To me two functions are not really justified, because the address width, and the bit masks are so closely related. But I'm also not too opposed to having two functions.
>
> Since it's a large-scale change but the SMM high MMIO access bug is critical/urgent, I prefer to firstly push this bug fix change and then work on the new APIs.
>
> https://bugzilla.tianocore.org/show_bug.cgi?id=3394 was submitted to capture this.
For a critical bugfix, I would prefer not mixing the actual fix with the introduction of the symbolic names. Your patch currently fixes three things at the same time: (1) coding style (it replaces magic constants with macros / type names), (2) a bug in calculation, (3) a missing CPUID "maximum function" check.
Maybe writing a separate patch for each of these is unjustified, but I was really unhappy to see that the commit message said nothing about (1) and (3), and I had to hunt down (2) between the other changes.
The minimal fix -- that is, the fix for (2) -- would be just one line:
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
index fd6583f9d172..4592b76fe595 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
@@ -1920,7 +1920,7 @@ InitializeMpServiceData (
//
AsmCpuid (0x80000008, (UINT32*)&Index, NULL, NULL, NULL);
gPhyMask = LShiftU64 (1, (UINT8)Index) - 1;
- gPhyMask &= (1ull << 48) - EFI_PAGE_SIZE;
+ gPhyMask &= 0xfffffffffffff000ULL;
//
// Create page tables
I don't like that the patch currently does three things but only documents one.
That said, if you are out of time, feel free to go ahead with Eric's R-b.
Thanks
Laszlo
>
>
>
>
>
>
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
2021-05-16 1:39 ` Laszlo Ersek
@ 2021-05-18 7:51 ` Ni, Ray
2021-05-18 18:42 ` Laszlo Ersek
0 siblings, 1 reply; 10+ messages in thread
From: Ni, Ray @ 2021-05-18 7:51 UTC (permalink / raw)
To: Laszlo Ersek, devel@edk2.groups.io
> -----Original Message-----
> From: Laszlo Ersek <lersek@redhat.com>
> Sent: Sunday, May 16, 2021 9:39 AM
> To: devel@edk2.groups.io; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
>
> On 05/15/21 02:04, Ni, Ray wrote:
> > Laszlo,
> > Do you think that another API is also needed: GetPhysicalAddressWidth() that returns number 36/52?
>
> No. The GetPhysicalAddressBits() function that I proposed already returns this information. It has three outputs: the number of
> bits (that is, the width), as return value, and the two optional output parameters.
>
> So if you only need the the bit count, call
>
> GetPhysicalAddressBits (NULL, NULL);
>
> These calculations are so cheap and small that keeping them in a single function makes a lot of sense in my opinion.
I wasn't aware of the return value of the API. with your API, there is no need for another API to retrieve the address size.
> For a critical bugfix, I would prefer not mixing the actual fix with the introduction of the symbolic names. Your patch currently
> fixes three things at the same time: (1) coding style (it replaces magic constants with macros / type names), (2) a bug in
> calculation, (3) a missing CPUID "maximum function" check.
>
> Maybe writing a separate patch for each of these is unjustified, but I was really unhappy to see that the commit message said
> nothing about (1) and (3), and I had to hunt down (2) between the other changes.
>
> The minimal fix -- that is, the fix for (2) -- would be just one line:
>
> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
> index fd6583f9d172..4592b76fe595 100644
> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
> @@ -1920,7 +1920,7 @@ InitializeMpServiceData (
> //
> AsmCpuid (0x80000008, (UINT32*)&Index, NULL, NULL, NULL);
> gPhyMask = LShiftU64 (1, (UINT8)Index) - 1;
> - gPhyMask &= (1ull << 48) - EFI_PAGE_SIZE;
> + gPhyMask &= 0xfffffffffffff000ULL;
>
> //
> // Create page tables
>
>
> I don't like that the patch currently does three things but only documents one.
Thanks for explaining why you don't think it's a good patch. I thought anytime changing a code,
I should try to make it better, functional better, looks better.
I will follow your suggestion next time for bug fixes.
>
> That said, if you are out of time, feel free to go ahead with Eric's R-b.
Indeed. thanks for the understanding.
>
> Thanks
> Laszlo
>
>
>
> >
> >
> >
> >
> >
> >
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
2021-05-18 7:51 ` Ni, Ray
@ 2021-05-18 18:42 ` Laszlo Ersek
2021-05-20 4:28 ` Ni, Ray
2021-05-20 11:11 ` Michael Brown
0 siblings, 2 replies; 10+ messages in thread
From: Laszlo Ersek @ 2021-05-18 18:42 UTC (permalink / raw)
To: Ni, Ray, devel@edk2.groups.io
On 05/18/21 09:51, Ni, Ray wrote:
>
>
>> -----Original Message-----
>> From: Laszlo Ersek <lersek@redhat.com>
>> Sent: Sunday, May 16, 2021 9:39 AM
>> To: devel@edk2.groups.io; Ni, Ray <ray.ni@intel.com>
>> Subject: Re: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
>>
>> On 05/15/21 02:04, Ni, Ray wrote:
>>> Laszlo,
>>> Do you think that another API is also needed: GetPhysicalAddressWidth() that returns number 36/52?
>>
>> No. The GetPhysicalAddressBits() function that I proposed already returns this information. It has three outputs: the number of
>> bits (that is, the width), as return value, and the two optional output parameters.
>>
>> So if you only need the the bit count, call
>>
>> GetPhysicalAddressBits (NULL, NULL);
>>
>> These calculations are so cheap and small that keeping them in a single function makes a lot of sense in my opinion.
>
> I wasn't aware of the return value of the API. with your API, there is no need for another API to retrieve the address size.
>
>> For a critical bugfix, I would prefer not mixing the actual fix with the introduction of the symbolic names. Your patch currently
>> fixes three things at the same time: (1) coding style (it replaces magic constants with macros / type names), (2) a bug in
>> calculation, (3) a missing CPUID "maximum function" check.
>>
>> Maybe writing a separate patch for each of these is unjustified, but I was really unhappy to see that the commit message said
>> nothing about (1) and (3), and I had to hunt down (2) between the other changes.
>>
>> The minimal fix -- that is, the fix for (2) -- would be just one line:
>>
>> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
>> index fd6583f9d172..4592b76fe595 100644
>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
>> @@ -1920,7 +1920,7 @@ InitializeMpServiceData (
>> //
>> AsmCpuid (0x80000008, (UINT32*)&Index, NULL, NULL, NULL);
>> gPhyMask = LShiftU64 (1, (UINT8)Index) - 1;
>> - gPhyMask &= (1ull << 48) - EFI_PAGE_SIZE;
>> + gPhyMask &= 0xfffffffffffff000ULL;
>>
>> //
>> // Create page tables
>>
>>
>> I don't like that the patch currently does three things but only documents one.
>
> Thanks for explaining why you don't think it's a good patch. I thought anytime changing a code,
> I should try to make it better, functional better, looks better.
My only point was that separate concerns should be implemented in
separate patches, or at least (if they are really difficult, or
overkill, to isolate) that they should be documented.
Please try to think with your reviewers' mindsets in mind, when
preparing a patch (commit message and code both). The question the patch
author has to ask themselves is not only "how do I implement this", but
also "how do I explain this to my reviewers".
I read the subject line and the commit message. Those make me anticipate
some magic constant (related to 48) in the code. But that's not what I
see in the code. I see new macros, new control flow, new variables, new
indentation. The actual purpose of the patch (as documented in the
commit message) is just a tiny fraction of the whole code change, and
the commit message does not prepare the reader for it. *That* is what's
wrong. Improving code wherever you go is great, but all that effort
needs to be structured correctly, or at least justified in natural language.
Patches exist primarily for humans to read, and secondarily for
computers to execute. If we don't believe in that, then edk2 will never
become a true open source, community project. (In my opinion anyway.)
Thanks
Laszlo
>
> I will follow your suggestion next time for bug fixes.
>
>>
>> That said, if you are out of time, feel free to go ahead with Eric's R-b.
> Indeed. thanks for the understanding.
>
>>
>> Thanks
>> Laszlo
>>
>>
>>
>>>
>>>
>>>
>>>
>>>
>>>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
2021-05-18 18:42 ` Laszlo Ersek
@ 2021-05-20 4:28 ` Ni, Ray
2021-05-20 7:50 ` Laszlo Ersek
2021-05-20 11:11 ` Michael Brown
1 sibling, 1 reply; 10+ messages in thread
From: Ni, Ray @ 2021-05-20 4:28 UTC (permalink / raw)
To: Laszlo Ersek, devel@edk2.groups.io
>
> My only point was that separate concerns should be implemented in
> separate patches, or at least (if they are really difficult, or
> overkill, to isolate) that they should be documented.
>
> Please try to think with your reviewers' mindsets in mind, when
> preparing a patch (commit message and code both). The question the patch
> author has to ask themselves is not only "how do I implement this", but
> also "how do I explain this to my reviewers".
>
> I read the subject line and the commit message. Those make me anticipate
> some magic constant (related to 48) in the code. But that's not what I
> see in the code. I see new macros, new control flow, new variables, new
> indentation. The actual purpose of the patch (as documented in the
> commit message) is just a tiny fraction of the whole code change, and
> the commit message does not prepare the reader for it. *That* is what's
> wrong. Improving code wherever you go is great, but all that effort
> needs to be structured correctly, or at least justified in natural language.
>
> Patches exist primarily for humans to read, and secondarily for
> computers to execute. If we don't believe in that, then edk2 will never
> become a true open source, community project. (In my opinion anyway.)
>
I admit my patch assumes the reviewers should be very familiar to how CPUID "protocol" works.
In fact, there are two kinds of reviewers at least:
1. domain reviewers
2. consumers as reviewers
I didn't consider the second kind of reviewers.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
2021-05-20 4:28 ` Ni, Ray
@ 2021-05-20 7:50 ` Laszlo Ersek
0 siblings, 0 replies; 10+ messages in thread
From: Laszlo Ersek @ 2021-05-20 7:50 UTC (permalink / raw)
To: Ni, Ray, devel@edk2.groups.io
Hi Ray,
On 05/20/21 06:28, Ni, Ray wrote:
>>
>> My only point was that separate concerns should be implemented in
>> separate patches, or at least (if they are really difficult, or
>> overkill, to isolate) that they should be documented.
>>
>> Please try to think with your reviewers' mindsets in mind, when
>> preparing a patch (commit message and code both). The question the patch
>> author has to ask themselves is not only "how do I implement this", but
>> also "how do I explain this to my reviewers".
>>
>> I read the subject line and the commit message. Those make me anticipate
>> some magic constant (related to 48) in the code. But that's not what I
>> see in the code. I see new macros, new control flow, new variables, new
>> indentation. The actual purpose of the patch (as documented in the
>> commit message) is just a tiny fraction of the whole code change, and
>> the commit message does not prepare the reader for it. *That* is what's
>> wrong. Improving code wherever you go is great, but all that effort
>> needs to be structured correctly, or at least justified in natural language.
>>
>> Patches exist primarily for humans to read, and secondarily for
>> computers to execute. If we don't believe in that, then edk2 will never
>> become a true open source, community project. (In my opinion anyway.)
>>
>
> I admit my patch assumes the reviewers should be very familiar to how CPUID "protocol" works.
> In fact, there are two kinds of reviewers at least:
> 1. domain reviewers
> 2. consumers as reviewers
>
> I didn't consider the second kind of reviewers.
>
I *am* (somewhat) familiar with how CPUID works; I do know that the max
supported function is supposed to be checked before a particular
(optional) function is exercised. (The max supported function may or may
not be cached in a variable or whatever, but that's beside the point here.)
The problem is that these are two *distinct* issues in the existent
code. One, a violation of the *generic* CPUID "protocol" -- there was no
check for the availability of the particular function. Two, the bad
masking that is *specific* to the function exercised.
Your patch fixes both issues at the same time, which is questionable
practice.
And even if we agree that these two issues are conceptually so close to
each other that they don't deserve separate patches, they absolutely
deserve separate *mentions* in the commit message. It's not that you
need to teach the CPUID protocol to readers in the commit message.
Instead, you need to prepare your knowledgeable readers too, in the
commit message, that you are going to *deal* with the generic CPUID
protocol in this patch, which otherwise mainly intends to fix the bad
masking.
(And then there's the third, again independent, action of replacing
magic numbers with symbolic names.)
So there really are three *valid* approaches to solving *just* this
particular issue that you were working on:
(1) The one-liner mask fix. This is the most surgical (localized) fix,
easy to port to other branches and repositories. It is *strictly* an
improvement, makes nothing worse, so it's perfectly fine to have a
patchlike this.
(2) The mask fix plus the CPUID protocol fix (check max supported
function). Two patches, in any order you like.
(3) The mask fix, the CPUID protocol fix, and the coding style fix.
Three patches, in any order whatsoever that you like.
Implementing (3), but with all three patches squashed into one, is just
barely acceptable, and only if the commit message documents each action
separately.
Open development is all about discipline. You look at the code, you find
the bug, but you realize there are *other* issues with the code too.
That's where *discipline* comes into the picture. You sit down and
figure out what exactly you want to do. You choose one of the approaches
(1), (2) and (3). Maybe your business requirements and schedule dictate
(1). Maybe you have a bit more time and you can implement (3). Either is
fine. Jumbling all three actions together and not preparing reviewers --
even knowledgeable reviewers -- for it is *not* fine.
I can't emphasize discipline enough. That's where you say, "yes, I can
see that we use naked magic numbers here, and that the CPUID protocol is
not observed. But we need an urgent fix, so I'm *not* going to touch
those issues *even if I could do so*, because it messes up the
boundaries between the issues, and makes understanding the changes
difficult". Or else, you can say, "I am definitely going to fix all this
mess, but I'm going to do it carefully, taking one step at a time --
more precisely, taking *my reviewers* through it one step at a time,
because even though I have the complete picture in my mind right now,
they don't, and even I won't, in six months".
I've been harping on this kind of self-discipline for almost a decade
now; it's mind-boggling for me to see that it just never sticks.
The worst you can do to a reviewer is to *surprise them* in the code
part of a patch.
Well, I'm sorry for obsessing about this again.
Laszlo
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation
2021-05-18 18:42 ` Laszlo Ersek
2021-05-20 4:28 ` Ni, Ray
@ 2021-05-20 11:11 ` Michael Brown
1 sibling, 0 replies; 10+ messages in thread
From: Michael Brown @ 2021-05-20 11:11 UTC (permalink / raw)
To: devel, lersek, Ni, Ray
On 18/05/2021 19:42, Laszlo Ersek wrote:
> On 05/18/21 09:51, Ni, Ray wrote:
>> Thanks for explaining why you don't think it's a good patch. I thought anytime changing a code,
>> I should try to make it better, functional better, looks better.
>
> My only point was that separate concerns should be implemented in
> separate patches, or at least (if they are really difficult, or
> overkill, to isolate) that they should be documented.
>
> Please try to think with your reviewers' mindsets in mind, when
> preparing a patch (commit message and code both). The question the patch
> author has to ask themselves is not only "how do I implement this", but
> also "how do I explain this to my reviewers".
(Apologies in advance for intruding.)
Ray: I think you may be neglecting one half of the problem.
When making a code change, there are (at least) two requirements:
1. The new version of the code must make sense. You are definitely
achieving this: as you say, "make it better, functional better, looks
better". This is good.
2. The *change* between the old and new versions of the code (i.e. the
patch and accompanying commit message) must also make sense. This is
the requirement that I think Laszlo would like you to meet.
It's not viable for anyone to meaningfully review code unless both of
these requirements are met.
Thanks,
Michael
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-05-20 11:11 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-05-12 4:53 [PATCH] UefiCpuPkg/PiSmmCpu: Remove hardcode 48 address size limitation Ni, Ray
2021-05-13 3:32 ` Dong, Eric
2021-05-14 10:55 ` [edk2-devel] " Laszlo Ersek
2021-05-15 0:04 ` Ni, Ray
2021-05-16 1:39 ` Laszlo Ersek
2021-05-18 7:51 ` Ni, Ray
2021-05-18 18:42 ` Laszlo Ersek
2021-05-20 4:28 ` Ni, Ray
2021-05-20 7:50 ` Laszlo Ersek
2021-05-20 11:11 ` Michael Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox