]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[riscv] Perform a writability test before applying relocations
authorMichael Brown <mcb30@ipxe.org>
Tue, 13 May 2025 16:36:53 +0000 (17:36 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 13 May 2025 16:42:53 +0000 (17:42 +0100)
If paging is not supported, then we will attempt to apply dynamic
relocations to fix up the runtime addresses.  If the image is
currently executing directly from flash memory, this can result in
effectively sending an undefined sequence of commands to the flash
device, which can cause unwanted side effects.

Perform an explicit writability test before applying relocations,
using a write value chosen to be safe for at least any devices
conforming to the JEDEC Common Flash Interface (CFI01).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/riscv/prefix/libprefix.S

index 69b9f9ba27e7284cb2abe73105b5ed35b037afe9..b011616da7662be8b7cc3daf5f0835423486b83c 100644 (file)
@@ -280,6 +280,23 @@ apply_relocs:
        beqz    a2, apply_relocs_done
        progress " reloc"
 
+       /* Test writability
+        *
+        * We do this to avoid accidentally sending an undefined
+        * sequence of commands to a flash device, if we are started
+        * from read-only memory with no paging support.
+        *
+        * We attempt to write an all-ones pattern, on the basis that
+        * this pattern will harmlessly cause any flash device
+        * conforming to the CFI01 specification to enter the default
+        * "read array" state.
+        */
+       la      t0, apply_relocs_test
+       li      t1, -1
+       STOREN  t1, (t0)
+       LOADN   t2, (t0)
+       bne     t1, t2, apply_relocs_failed
+
 apply_relocs_loop:
        /* Read new relocation record */
        LOADN   a3, (a0)
@@ -307,23 +324,35 @@ apply_relocs_loop:
        /* Loop until we have reached a terminator record (MSB=0, offset=0) */
        bnez    a3, apply_relocs_loop
 
-       /* Check that relocations were applied successfully
-        *
-        * Failure to apply relocations (if relocations were needed)
-        * is a fatal error.
-        */
+       /* Check that relocations were applied successfully */
        la      t0, _prefix
        LOADN   t1, prefix_virt
-       beq     t0, t1, apply_relocs_done
-       progress " failed\n"
-       j       reset_system
+       bne     t0, t1, apply_relocs_failed
 
 apply_relocs_done:
        /* Return to caller */
        progress " ok\n"
        ret
+
+apply_relocs_failed:
+       /* Failure to apply relocations (if relocations were needed)
+        * is a fatal error.
+        */
+       progress " failed\n"
+       j       reset_system
        .size   apply_relocs, . - apply_relocs
 
+       /* Writability test
+        *
+        * Placed within .data rather than .bss, since we need this to
+        * be within the range of the stored iPXE image.
+        */
+       .section ".data.apply_relocs_test", "aw", @progbits
+       .balign ( __riscv_xlen / 8 )
+apply_relocs_test:
+       .space  ( __riscv_xlen / 8 )
+       .size   apply_relocs_test, . - apply_relocs_test
+
 /*****************************************************************************
  *
  * Enable paging