[PATCH] platform: generic/starfive: deny S-mode access to the JH7110 firmware alias
Zhongyi Cheng
zhongyicheng241 at mails.ucas.ac.cn
Sun Sep 27 20:24:14 PDT 2026
The JH7110 DDR controller folds physical addresses beyond the 8GB DDR
window back into DRAM: PA (X + 0x200000000) resolves to the same cells
as PA X. PMP entries match the presented address, so an aliased S-mode
access to the firmware region bypasses the entry protecting the
firmware and matches the allow-everything root region, letting root
read and write the firmware through the alias.
Add a root domain memory region covering the alias of the firmware
image (fw_start + 0x200000000 .. fw_start + fw_size) with M-mode-only
permissions, in platform early_init() so that it is in place before
sbi_domain_finalize(). The region sorts before the allow-everything
region, so it gets a lower PMP entry index and denies S/U-mode access
to the firmware alias. The rest of the alias window is left untouched.
This follows the same approach as the RZ/Five ILM/DLM protection.
Verified on QEMU riscv64 (root region list and PMP encodings) and on a
VisionFive 2 board: S/U-mode accesses to both the alias (0x240000000)
and the firmware region (0x40000000) fault as expected after this
patch, while normal boot is unaffected.
Reported-by: Zhongyi Cheng <zhongyicheng241 at mails.ucas.ac.cn>
Signed-off-by: Zhongyi Cheng <zhongyicheng241 at mails.ucas.ac.cn>
---
platform/generic/starfive/jh7110.c | 38 ++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/platform/generic/starfive/jh7110.c b/platform/generic/starfive/jh7110.c
index 7008386a..07fbed5e 100644
--- a/platform/generic/starfive/jh7110.c
+++ b/platform/generic/starfive/jh7110.c
@@ -10,9 +10,12 @@
#include <libfdt.h>
#include <platform_override.h>
+#include <sbi/sbi_domain.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_bitops.h>
#include <sbi/sbi_hart.h>
+#include <sbi/sbi_math.h>
+#include <sbi/sbi_scratch.h>
#include <sbi/sbi_system.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_timer.h>
@@ -69,6 +72,13 @@ static u32 selected_hartid = -1;
#define I2C_APB_CLK_ENABLE_BIT BIT(31)
+/*
+ * Physical addresses beyond the 8GB DDR window fold back into DRAM on
+ * the JH7110 DDR controller: PA (X + JH7110_DRAM_ALIAS_OFFSET) resolves
+ * to the same cells as PA X (for X in the DDR window).
+ */
+#define JH7110_DRAM_ALIAS_OFFSET 0x200000000UL
+
static int pm_system_reset_check(u32 type, u32 reason)
{
switch (type) {
@@ -283,6 +293,33 @@ err:
return rc;
}
+/*
+ * Deny S/U-mode access to the alias of this firmware image.
+ *
+ * PMP entries match the presented address, so without extra protection
+ * an S/U-mode access through the alias window bypasses the entry
+ * protecting the firmware and matches the allow-everything root region.
+ * Add a root domain region covering firmware_alias_base .. fw_end so
+ * that it sorts before the allow-everything region and denies S/U-mode
+ * access to the firmware alias, while leaving the rest of the alias
+ * window untouched.
+ */
+static int starfive_jh7110_early_init(bool cold_boot)
+{
+ struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+ int rc;
+
+ rc = generic_early_init(cold_boot);
+ if (rc || !cold_boot)
+ return rc;
+
+ return sbi_domain_root_add_memrange(
+ scratch->fw_start + JH7110_DRAM_ALIAS_OFFSET,
+ scratch->fw_size,
+ 1UL << log2roundup(scratch->fw_size),
+ SBI_DOMAIN_MEMREGION_M_RWX);
+}
+
static int starfive_jh7110_final_init(bool cold_boot)
{
if (cold_boot) {
@@ -316,6 +353,7 @@ static int starfive_jh7110_platform_init(const void *fdt, int nodeoff,
}
generic_platform_ops.cold_boot_allowed = starfive_jh7110_cold_boot_allowed;
+ generic_platform_ops.early_init = starfive_jh7110_early_init;
generic_platform_ops.final_init = starfive_jh7110_final_init;
return 0;
--
2.54.0
More information about the opensbi
mailing list