On 11/14/23 17:11, Ranbir Singh wrote: > > > On Mon, Nov 13, 2023 at 10:03 PM Laszlo Ersek <ler...@redhat.com > <mailto:ler...@redhat.com>> wrote: > > On 11/9/23 18:39, Ranbir Singh wrote: > > From: Ranbir Singh <ranbir.sin...@dell.com> > > > > The function SubmitResources has a switch-case code in which the > > case ACPI_ADDRESS_SPACE_TYPE_MEM: which falls through to > > case ACPI_ADDRESS_SPACE_TYPE_IO: to include additional common check. > > > > While this may be intentional, it may not be evident to any > general code > > reader/developer or static analyis tool why there is no break in > between. > > > > SubmitResources function is supposed to handle only Mem or IO > resources. > > So, update the ResType parameter check reflecting that and > re-model the > > switch-case code in contention using just one if condition to further > > handle other parameter checks specific to ACPI_ADDRESS_SPACE_TYPE_MEM. > > This leads to mostly indentation level code changes. Few ASSERT's > later > > present are henceforth not required. > > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4212 > <https://bugzilla.tianocore.org/show_bug.cgi?id=4212> > > > > Cc: Ray Ni <ray...@intel.com <mailto:ray...@intel.com>> > > Signed-off-by: Ranbir Singh <rsi...@ventanamicro.com > <mailto:rsi...@ventanamicro.com>> > > --- > > MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 60 > +++++++++----------- > > 1 file changed, 26 insertions(+), 34 deletions(-) > > I have applied this patch locally, and displayed it with > > git show -W -b > > Let me make comments on that: > > > /** > > > > Submits the I/O and memory resource requirements for the > specified PCI Root Bridge. > > > > @param This The > EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. > > - @param RootBridgeHandle The PCI Root Bridge whose I/O and > memory resource requirements. > > + @param RootBridgeHandle The PCI Root Bridge whose I/O and > memory resource requirements > > are being submitted. > > @param Configuration The pointer to the PCI I/O and PCI > memory resource descriptor. > > > > @retval EFI_SUCCESS Succeed. > > @retval EFI_INVALID_PARAMETER Wrong parameters passed in. > > **/ > > @@ -1460,137 +1460,129 @@ EFIAPI > > SubmitResources ( > > IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, > > IN EFI_HANDLE > RootBridgeHandle, > > IN VOID *Configuration > > ) > > { > > LIST_ENTRY *Link; > > PCI_HOST_BRIDGE_INSTANCE *HostBridge; > > PCI_ROOT_BRIDGE_INSTANCE *RootBridge; > > EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; > > PCI_RESOURCE_TYPE Type; > > > > // > > // Check the input parameter: Configuration > > // > > if (Configuration == NULL) { > > return EFI_INVALID_PARAMETER; > > } > > > > HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This); > > for (Link = GetFirstNode (&HostBridge->RootBridges) > > ; !IsNull (&HostBridge->RootBridges, Link) > > ; Link = GetNextNode (&HostBridge->RootBridges, Link) > > ) > > { > > RootBridge = ROOT_BRIDGE_FROM_LINK (Link); > > if (RootBridgeHandle == RootBridge->Handle) { > > DEBUG ((DEBUG_INFO, "PciHostBridge: SubmitResources for > %s\n", RootBridge->DevicePathStr)); > > // > > // Check the resource descriptors. > > // If the Configuration includes one or more invalid > resource descriptors, all the resource > > // descriptors are ignored and the function returns > EFI_INVALID_PARAMETER. > > // > > for (Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR > *)Configuration; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; > Descriptor++) { > > - if (Descriptor->ResType > ACPI_ADDRESS_SPACE_TYPE_BUS) { > > + if ((Descriptor->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) > && (Descriptor->ResType != ACPI_ADDRESS_SPACE_TYPE_IO)) { > > return EFI_INVALID_PARAMETER; > > } > > This is a slight logic change. > > Previously, the code did the following: > > - Any resource types that were different from MEM, IO, and BUS, would be > rejected with EFI_INVALID_PARAMETER. > > - MEM and IO would be handled. > > - BUS resource types would trigger an ASSERT(). > > In effect, the code claimed that BUS resource types were *impossible* > here, due to prior filtering or whatever. > > The logic change is that now we reject BUS resource types explicitly. > > I think that's not ideal. Here's why: > > - If the preexistent ASSERT() about BUS resource types being impossible > was right, then now we are occluding that fact, and pretending / > suggesting that BUS types are something we *should* handle. This > creates a confusion about data flow. > > - If the preexistent ASSERT() about BUS resource types being impossible > was wrong (i.e., dependent on input data, we could actuall trigger the > ASSERT()), then this change is very welcome, but *then* it is a bugfix > in its own right! And therefore should be documented separately. > > Anyway. I'm getting exhausted. > > > My interpretation was SubmitResources function is supposed to handle > only Mem or IO resources, so > ACPI_ADDRESS_SPACE_TYPE_BUS check should > actually have been >= ACPI_ADDRESS_SPACE_TYPE_BUS. The function header > also states Mem or IO resources only and hence I considered it documented. > > Also, considering only the RELEASE builds, if ResType comes as > ACPI_ADDRESS_SPACE_TYPE_BUS (even if hypothetically), then switch block > code lands in default, the ASSERT there is compiled out and after break > normal execution will carry on which at the following code point in the > for loop also contains ASSERT but that also gets compiled out (I am > talking RELEASE build only behaviour here) leading to it getting treated > as IO which doesn't seem correct at all to me. > > ... > } else { > ASSERT (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_IO); > Type = TypeIo; > } > > There was no other handling in the function wrt BUS resource types. > > If the BUS resource needs to be ASSERT'ed as before, then it can be done > by including one more if check. However, I don't think code should > progress ahead (even if hypothetically and inadvertently) to treating it > as IO. > > > > > > DEBUG (( > > DEBUG_INFO, > > " %s: Granularity/SpecificFlag = %ld / %02x%s\n", > > mAcpiAddressSpaceTypeStr[Descriptor->ResType], > > Descriptor->AddrSpaceGranularity, > > Descriptor->SpecificFlag, > > (Descriptor->SpecificFlag & > EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0 > ? L" (Prefetchable)" : L"" > > )); > > DEBUG ((DEBUG_INFO, " Length/Alignment = 0x%lx / > 0x%lx\n", Descriptor->AddrLen, Descriptor->AddrRangeMax)); > > - switch (Descriptor->ResType) { > > - case ACPI_ADDRESS_SPACE_TYPE_MEM: > > + > > + if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { > > if ((Descriptor->AddrSpaceGranularity != 32) && > (Descriptor->AddrSpaceGranularity != 64)) { > > return EFI_INVALID_PARAMETER; > > } > > > > if ((Descriptor->AddrSpaceGranularity == 32) && > (Descriptor->AddrLen >= SIZE_4GB)) { > > return EFI_INVALID_PARAMETER; > > } > > > > // > > // If the PCI root bridge does not support separate > windows for nonprefetchable and > > // prefetchable memory, then the PCI bus driver needs > to include requests for > > // prefetchable memory in the nonprefetchable memory pool. > > // > > if (((RootBridge->AllocationAttributes & > EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) && > > ((Descriptor->SpecificFlag & > EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0) > > ) > > { > > return EFI_INVALID_PARAMETER; > > } > > + } > > > > - case ACPI_ADDRESS_SPACE_TYPE_IO: > > // > > // Check aligment, it should be of the form 2^n-1 > > // > > if (GetPowerOfTwo64 (Descriptor->AddrRangeMax + 1) != > (Descriptor->AddrRangeMax + 1)) { > > return EFI_INVALID_PARAMETER; > > } > > - > > - break; > > - default: > > - ASSERT (FALSE); > > - break; > > - } > > } > > The patch is good and clever thus far. We restrict the types we handle > to MEM and IO. Then we have a block of code that runs only for MEM, and > then another that -- due to being unrestricted -- runs for both MEM and > IO. > > > > > if (Descriptor->Desc != ACPI_END_TAG_DESCRIPTOR) { > > return EFI_INVALID_PARAMETER; > > } > > > > for (Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR > *)Configuration; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; > Descriptor++) { > > if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { > > if (Descriptor->AddrSpaceGranularity == 32) { > > if ((Descriptor->SpecificFlag & > EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0) { > > Type = TypePMem32; > > } else { > > Type = TypeMem32; > > } > > } else { > > - ASSERT (Descriptor->AddrSpaceGranularity == 64); > > if ((Descriptor->SpecificFlag & > EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0) { > > Type = TypePMem64; > > } else { > > Type = TypeMem64; > > } > > } > > } else { > > - ASSERT (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_IO); > > Type = TypeIo; > > } > > But the removal of these ASSERT()s is hard to justify. > > Yes, these predicates are always TRUE at this point, due to checks > performed above. > > But that's *exactly the reason* for including an ASSERT() in the code! > To remind the reader that a (perhaps non-obvious) predicate always holds > at that location! > > So, the argument > > ASSERT(X) is unneeded because X always holds > > is backwards. You do an ASSERT(X) *because* X always holds, and X is > non-trivial! > > The only reason for removing an ASSERT(X) is that X, while true, is > *trivial*. > > > In this particular case, we do indeed explicitly restrict > Descriptor->AddrSpaceGranularity to 32 or 64 above, on the MEM branch. > > We also ensure that the only resource type other than MEM can be IO. > > In other words, the assertions are true. > > Now the question is: are those true statements *trivial*? If they are > trivial, then removing them is OK. If they are not trivial, then they > are worth keeping. > > In my opinion, they are worth keeping. They are *reminders* that we > performed those checks above. > > But I'm not going to die on this hill, so if you don't want to respin: > > Reviewed-by: Laszlo Ersek <ler...@redhat.com <mailto:ler...@redhat.com>> > > Laszlo > > > Yes, I felt that to be trivial given the checks are already in place in > the same function earlier. > However, I am open to re-spin and restore these ASSERT's.
I'd like you to respin the patch for two reasons, then: - More importantly: you've demonstrated that the change regarding BUS handling is a bugfix. As requested before, please mention it in the commit message explicitly. (I do agree we can keep the logic change in the same patch.) - Less importantly: keeping these last two ASSERT()s would be nice, then. Thanks! Laszlo > > > > > > RootBridge->ResAllocNode[Type].Length = > Descriptor->AddrLen; > > RootBridge->ResAllocNode[Type].Alignment = > Descriptor->AddrRangeMax; > > RootBridge->ResAllocNode[Type].Status = ResSubmitted; > > } > > > > RootBridge->ResourceSubmitted = TRUE; > > return EFI_SUCCESS; > > } > > } > > > > return EFI_INVALID_PARAMETER; > > } > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#111244): https://edk2.groups.io/g/devel/message/111244 Mute This Topic: https://groups.io/mt/102490514/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/9847357/21656/1706620634/xyzzy [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-