[PATCH] platform: generic/starfive: deny S-mode access to the JH7110 firmware alias

Anup Patel anup at brainfault.org
Mon Nov 2 00:01:03 PST 2026


On Mon, Sep 28, 2026 at 8:54 AM Zhongyi Cheng
<zhongyicheng241 at mails.ucas.ac.cn> wrote:
>
> 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>

LGTM.

Reviewed-by: Anup Patel <anup at brainfault.org>

Applied this patch to the riscv/opensbi repo.

Thanks,
Anup


> ---
>  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
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi



More information about the opensbi mailing list