From 586cbfe5ffb74f7ce65ffacef619502db5624211 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 25 Jun 2018 09:08:37 +0200 Subject: [PATCH 1/2] ppu_v1: Fix get*_operating_mode() Cast to (enum ppu_v1_opmode) after the right shift and not before. The value before the right shift is not a valid enumeration value resulting in a casting error. Change-Id: I599c1d3b3c15df9b4845d52939eb620c536b6161 Signed-off-by: Ronald Cron --- module/ppu_v1/src/ppu_v1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/ppu_v1/src/ppu_v1.c b/module/ppu_v1/src/ppu_v1.c index 38406525b..262db28b5 100644 --- a/module/ppu_v1/src/ppu_v1.c +++ b/module/ppu_v1/src/ppu_v1.c @@ -130,7 +130,7 @@ enum ppu_v1_opmode ppu_v1_get_operating_mode(struct ppu_v1_reg *ppu) assert(ppu != NULL); return (enum ppu_v1_opmode) - (ppu->PWSR & PPU_V1_PWSR_OP_STATUS) >> PPU_V1_PWSR_OP_STATUS_POS; + ((ppu->PWSR & PPU_V1_PWSR_OP_STATUS) >> PPU_V1_PWSR_OP_STATUS_POS); } enum ppu_v1_opmode ppu_v1_get_programmed_operating_mode(struct ppu_v1_reg *ppu) @@ -138,7 +138,7 @@ enum ppu_v1_opmode ppu_v1_get_programmed_operating_mode(struct ppu_v1_reg *ppu) assert(ppu != NULL); return (enum ppu_v1_opmode) - (ppu->PWPR & PPU_V1_PWPR_OP_POLICY) >> PPU_V1_PWPR_OP_POLICY_POS; + ((ppu->PWPR & PPU_V1_PWPR_OP_POLICY) >> PPU_V1_PWPR_OP_POLICY_POS); } bool ppu_v1_is_dynamic_enabled(struct ppu_v1_reg *ppu) -- GitLab From 4d3b7ef53d5b571b43158b951b41406692c8654b Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 28 May 2018 14:05:28 +0200 Subject: [PATCH 2/2] power_domain: Fix parent position computation Fix an out of bound access to an array when computing the parent position of a power domain at the highest possible level (MOD_PD_LEVEL_COUNT - 1). Change-Id: I320ecd321cd9f1e9c86878038a08a3591bd0a07a Signed-off-by: Ronald Cron --- module/power_domain/src/mod_power_domain.c | 25 +++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/module/power_domain/src/mod_power_domain.c b/module/power_domain/src/mod_power_domain.c index 8f3b8a907..53048ebb9 100644 --- a/module/power_domain/src/mod_power_domain.c +++ b/module/power_domain/src/mod_power_domain.c @@ -296,13 +296,6 @@ static const unsigned int mod_pd_cs_level_state_shift[MOD_PD_LEVEL_COUNT] = { static struct mod_pd_ctx mod_pd_ctx; static const char driver_error_msg[] = "[PD] Driver error %s (%d) in %s @%d\n"; -static const unsigned int tree_pos_level_shift[MOD_PD_LEVEL_COUNT] = { - MOD_PD_TREE_POS_LEVEL_0_SHIFT, - MOD_PD_TREE_POS_LEVEL_1_SHIFT, - MOD_PD_TREE_POS_LEVEL_2_SHIFT, - MOD_PD_TREE_POS_LEVEL_3_SHIFT -}; - static const char * const default_state_name_table[] = { "OFF", "ON", "SLEEP", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" @@ -326,14 +319,22 @@ static enum mod_pd_level get_level_from_tree_pos(uint64_t tree_pos) static uint64_t compute_parent_tree_pos_from_tree_pos(uint64_t tree_pos) { + unsigned int parent_level; + uint64_t tree_pos_mask; uint64_t parent_tree_pos; - unsigned int level; - level = get_level_from_tree_pos(tree_pos); + parent_level = get_level_from_tree_pos(tree_pos) + 1; + + /* + * Create a mask of bits for levels strictly lower than 'parent_level'. We + * use this mask below for clearing off in 'tree_pos' the levels strictly + * lower than 'parent_level'. + */ + tree_pos_mask = (UINT64_C(1) << + (parent_level * MOD_PD_TREE_POS_BITS_PER_LEVEL)) - 1; - parent_tree_pos = (tree_pos & - (~((((uint64_t)1) << tree_pos_level_shift[level+1])-1))) - + (((uint64_t)1) << MOD_PD_TREE_POS_LEVEL_SHIFT); + parent_tree_pos = (tree_pos & (~tree_pos_mask)) + + (UINT64_C(1) << MOD_PD_TREE_POS_LEVEL_SHIFT); return parent_tree_pos; } -- GitLab