[PATCH] platform: generic/andes: fix 32-bit shift overflow in decode_pmaaddrx()
Anup Patel
anup at brainfault.org
Mon Aug 31 22:31:46 PDT 2026
On Wed, Jul 29, 2026 at 2:53 PM Randolph <randolph at andestech.com> wrote:
>
> decode_pmaaddrx() reconstructs the NAPOT region start and size from a
> pmaaddr CSR value using "1 << (k + 3)" and "1 << k". The integer
> literal 1 has type int, so these shifts are performed in 32-bit
> precision. Shifting a 32-bit value by 32 or more bits is undefined
> behavior, and on RV64 the compiler emits sllw, which truncates the
> shift amount modulo 32.
>
> As a result, any PMA region with size >= 4 GiB (k >= 29) is decoded
> incorrectly. For example, on the Andes QiLai SoC the PCIe region
> 0x1000000000 - 0x17ffffffff (pmaaddr = 0x4ffffffff, k = 32) is decoded
> as an 8-byte region at 0x13fffffffc.
>
> This is not merely cosmetic: decode_pmaaddrx() is used by
> has_pma_region_overlap() and andes_sbi_free_pma(), so overlap checks
> are performed against bogus ranges and freeing such an entry by its
> physical address always fails.
>
> Promote the shifts to unsigned long so they are performed in the
> native register width.
>
> Fixes: aa56084c4dfb ("platform: generic: andes: add a new Andes SBI call to set up a PMA entry")
> Signed-off-by: Randolph Lin <randolph at andestech.com>
LGTM.
Reviewed-by: Anup Patel <anup at brainfault.org>
Applied this patch to the riscv/opensbi repo.
Thanks,
Anup
> ---
> platform/generic/andes/andes_pma.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/platform/generic/andes/andes_pma.c b/platform/generic/andes/andes_pma.c
> index ba9a35bb..28d33a2f 100644
> --- a/platform/generic/andes/andes_pma.c
> +++ b/platform/generic/andes/andes_pma.c
> @@ -82,8 +82,8 @@ static void decode_pmaaddrx(int entry_id, unsigned long *start,
> */
> pmaaddr = csr_read_num(CSR_PMAADDR0 + entry_id);
> k = sbi_ffz(pmaaddr);
> - *size = 1 << (k + 3);
> - *start = (pmaaddr - (1 << k) + 1) << 2;
> + *size = 1UL << (k + 3);
> + *start = (pmaaddr - (1UL << k) + 1) << 2;
> }
>
> static bool has_pma_region_overlap(unsigned long start, unsigned long size)
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
More information about the opensbi
mailing list