diff --git a/platform/generic/andes/andes_pma.c b/platform/generic/andes/andes_pma.c
index ba9a35b..cdc06ac 100644
--- a/platform/generic/andes/andes_pma.c
+++ b/platform/generic/andes/andes_pma.c
@@ -69,10 +69,10 @@ static void set_pmaxcfg(int entry_id, char flags)
 	csr_write_num(pmacfg_addr, pmacfg_val);
 }
 
-static void decode_pmaaddrx(int entry_id, unsigned long *start,
+static bool decode_pmaaddrx(int entry_id, unsigned long *start,
 			    unsigned long *size)
 {
-	unsigned long pmaaddr;
+	unsigned long addr, pmaaddr;
 	int k;
 
 	/**
@@ -81,9 +81,23 @@ static void decode_pmaaddrx(int entry_id, unsigned long *start,
 	 * start = 4 * ($pmaaddr - (size / 8) + 1)
 	 */
 	pmaaddr = csr_read_num(CSR_PMAADDR0 + entry_id);
+	if (pmaaddr == ~0UL)
+		return false;
+
 	k = sbi_ffz(pmaaddr);
-	*size = 1 << (k + 3);
-	*start = (pmaaddr - (1 << k) + 1) << 2;
+	if (k >= __riscv_xlen - 3)
+		return false;
+
+	addr = pmaaddr - (1UL << k) + 1;
+	if (addr > (~0UL >> 2))
+		return false;
+
+	*size = 1UL << (k + 3);
+	*start = addr << 2;
+	if (*start > ~0UL - (*size - 1))
+		return false;
+
+	return true;
 }
 
 static bool has_pma_region_overlap(unsigned long start, unsigned long size)
@@ -97,7 +111,8 @@ static bool has_pma_region_overlap(unsigned long start, unsigned long size)
 		if (is_pma_entry_disable(pmaxcfg))
 			continue;
 
-		decode_pmaaddrx(i, &_start, &_size);
+		if (!decode_pmaaddrx(i, &_start, &_size))
+			return true;
 		_end = _start + _size - 1;
 
 		if (MAX(start, _start) <= MIN(end, _end)) {
@@ -352,7 +367,8 @@ int andes_sbi_free_pma(unsigned long pa)
 		if (is_pma_entry_disable(pmaxcfg))
 			continue;
 
-		decode_pmaaddrx(i, &start, &size);
+		if (!decode_pmaaddrx(i, &start, &size))
+			return SBI_ERR_FAILED;
 		if (start != pa)
 			continue;
 
