Skip to content

fix(pcie): restore BAR memory after PCI_IN_13 Check_1 - #664

Open
La1itchauhan wants to merge 1 commit into
ARM-software:mainfrom
La1itchauhan:fix/650-restore-bar-memory
Open

La1itchauhan wants to merge 1 commit into
ARM-software:mainfrom
La1itchauhan:fix/650-restore-bar-memory

Conversation

@La1itchauhan

Copy link
Copy Markdown
Contributor

Description

In Check_1 of p004 (non-prefetchable) and p005 (prefetchable), the test writes KNOWN_DATA (0xABABABAB) to the start of the Root Port's memory window at base + mem_offset to verify that in-range memory access completes without an exception or data abort.

Although old_value was read prior to writing, it was never restored back to memory upon completing the check or on exception recovery. For devices where the endpoint BAR hosts the MSI-X table at offset 0 (where pal_pcie_mem_get_offset() defaults to 0x10), this leaves 0xABABABAB in entry 1's Message Lower Address.

Subsequent tests in the test suite that inspect live MSI-X tables (such as PCI_MSI_2 / test 897 and S_L3GI_02 / test 846) then fail to resolve the corrupted vector through the ITS mappings and report false test failures.

Key Changes:

  1. Normal Path Immediate Restore: Write old_value back to mem_base + mem_offset immediately after the in-window readback check in both p004.c and p005.c.
  2. Exception Path Guard & Coherency: Guard exception recovery using volatile uint32_t restore_pending and volatile uint32_t old_value (read into temporary tmp to avoid discarded qualifier warnings). In exception_return:, after Root Port window registers are restored (TYPE1_NP_MEM / TYPE1_P_MEM), restore old_value at ori_mem_base + mem_offset. restore_pending is cleared prior to issuing the write to prevent recursive exception loops in case of access aborts.
  3. Safe Context & Base Initialization: In p005.c, initialize ori_mem_base = mem_base; and refresh branch_stack_pointer = val_pe_save_exception_return_context(); before Check_1 (aligning with p004.c) so that any exception during Check_1 targets the correct original base on the current device. The duplicate ori_mem_base = mem_base; prior to Check_2 is retained for Check_2 logic.

Note on Platform Ports / PAL:

As discussed in #650, PAL implementers should also ensure that pal_pcie_mem_get_offset() returns an offset within BAR memory that is safe to access and overwrite without corrupting device configuration or capability structures (such as MSI-X tables). Restoring original BAR contents in the ACS test ensures test hygiene and robustness regardless of table layout.

Fixes #650


Test Plan

  • Compile-tested only: Verified compilation with aarch64-linux-gnu-gcc -Wall -Wextra -Werror -DTARGET_BAREMETAL across test_pool/pcie/p004.c and test_pool/pcie/p005.c with zero warnings and zero errors.
  • Verified disassembly under both -O0 and -O2 to confirm old_value and restore_pending stack-slot reloads at exception_return:.
  • Verified git diff --check passes cleanly with no whitespace or style issues.
  • (Compile-tested only; baremetal platform execution with MSI-X table at offset 0 not available in local dev environment).

In Check_1 of p004 (non-prefetchable) and p005 (prefetchable), the test
writes KNOWN_DATA (0xABABABAB) to the endpoint BAR at base + mem_offset
to verify that in-window memory access does not abort. While old_value
is read before the write, it was never restored.

When the endpoint BAR hosts the MSI-X table at offset 0 (with default
mem_offset 0x10), this leaves 0xABABABAB in entry 1's Message Address.
Subsequent compliance rules (e.g. PCI_MSI_2 / S_L3GI_02) that walk the
live MSI-X tables fail to resolve the corrupted entry and report false
failures.

1. Restore old_value back to mem_base + mem_offset immediately after the
   in-window check readback.
2. Guard the exception-recovery path with volatile restore_pending and
   old_value (both modified after the exception-return context is saved),
   clearing the flag before the restore write to prevent re-entrant fault
   loops. Read into a temporary buffer to preserve qualifier safety.
3. At exception_return, ensure the Root Port window configuration is
   restored first before writing old_value back to ori_mem_base + mem_offset.
4. In p005, initialize ori_mem_base and save exception return context
   before Check_1 so that any exception during Check_1 targets the valid
   device base. (The subsequent ori_mem_base assignment before Check_2 is
   retained for existing Check_2 logic).

Fixes ARM-software#650

Signed-off-by: Lalit Chauhan <chauhanlalitofficial@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

p004/p005 (PCI_IN_13) leave 0xABABABAB in endpoint BAR memory, corrupting the MSI-X table so later PCI_MSI_2 / S_L3GI_02 fail

1 participant