From b143fa7491bf9029ccd46c05d7d2267b3c2e2775 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Thu, 4 Apr 2019 17:16:39 +0200 Subject: [PATCH] plat: marvell: sip: make sure that comphy init will use correct address The argument passed via x1 is used as a base address for comphy related routines. Nevertheless validation of this address wasn't good enough and allowed some non comphy related addresses to slip over. To overcome this issue make sure that the address passed via SMC points to valid CP range and allow to proceed comphy initializations only with correct comphy offset. This could be fixed in a different way e.g. by passing CP id from the caller, but since this API is already used with various Linux, U-Boot and UEFI versions it can't be changed. Signed-off-by: Grzegorz Jaszczyk Change-Id: Ia74dbc36efcfbefc4a102d31191e6af5808c4a82 --- plat/marvell/common/mrvl_sip_svc.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/plat/marvell/common/mrvl_sip_svc.c b/plat/marvell/common/mrvl_sip_svc.c index df211059b..36cada193 100644 --- a/plat/marvell/common/mrvl_sip_svc.c +++ b/plat/marvell/common/mrvl_sip_svc.c @@ -15,6 +15,7 @@ #include #include "comphy/phy-comphy-cp110.h" +#include /* #define DEBUG_COMPHY */ #ifdef DEBUG_COMPHY @@ -38,12 +39,24 @@ #define MAX_LANE_NR 6 #define MVEBU_COMPHY_OFFSET 0x441000 -#define MVEBU_SD_OFFSET 0x120000 +#define MVEBU_CP_BASE_MASK (~0xffffff) /* This macro is used to identify COMPHY related calls from SMC function ID */ #define is_comphy_fid(fid) \ ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_DIG_RESET) +_Bool is_cp_range_valid(u_register_t *addr) +{ + int cp_nr; + + *addr &= MVEBU_CP_BASE_MASK; + for (cp_nr = 0; cp_nr < CP_NUM; cp_nr++) { + if (*addr == MVEBU_CP_REGS_BASE(cp_nr)) + return true; + } + + return false; +} uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, u_register_t x1, @@ -59,20 +72,17 @@ uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, debug("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx, x3 0x%lx\n", __func__, smc_fid, x1, x2, x3); + if (is_comphy_fid(smc_fid)) { - - /* some systems passes SD phys address instead of COMPHY phys - * address - convert it - */ - if (x1 & MVEBU_SD_OFFSET) - x1 = (x1 & ~0xffffff) + MVEBU_COMPHY_OFFSET; - - if ((x1 & 0xffffff) != MVEBU_COMPHY_OFFSET) { + /* validate address passed via x1 */ + if (!is_cp_range_valid(&x1)) { ERROR("%s: Wrong smc (0x%x) address: %lx\n", __func__, smc_fid, x1); SMC_RET1(handle, SMC_UNK); } + x1 += MVEBU_COMPHY_OFFSET; + if (x2 >= MAX_LANE_NR) { ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n", __func__, smc_fid, x2);