RE: [EXT] [PATCH v2 6/6] soc/fsl/qe: qe.c: fold qe_get_num_of_snums into qe_snums_init

From: Qiang Zhao
Date: Wed May 08 2019 - 22:37:08 EST


On 2019/5/1 17:29, Rasmus Villemoes <rasmus.villemoes@xxxxxxxxx> wrote:

> -----Original Message-----
> From: Rasmus Villemoes <rasmus.villemoes@xxxxxxxxx>
> Sent: 2019å5æ1æ 17:29
> To: devicetree@xxxxxxxxxxxxxxx; Qiang Zhao <qiang.zhao@xxxxxxx>; Leo Li
> <leoyang.li@xxxxxxx>
> Cc: linuxppc-dev@xxxxxxxxxxxxxxxx; linux-arm-kernel@xxxxxxxxxxxxxxxxxxx;
> linux-kernel@xxxxxxxxxxxxxxx; Rob Herring <robh+dt@xxxxxxxxxx>; Scott Wood
> <oss@xxxxxxxxxxxx>; Christophe Leroy <christophe.leroy@xxxxxx>; Mark
> Rutland <mark.rutland@xxxxxxx>; Rasmus Villemoes
> <Rasmus.Villemoes@xxxxxxxxx>
> Subject: [PATCH v2 6/6] soc/fsl/qe: qe.c: fold qe_get_num_of_snums into
> qe_snums_init
>
> The comment "No QE ever has fewer than 28 SNUMs" is false; e.g. the
> MPC8309 has 14. The code path returning -EINVAL is also a recipe for instant
> disaster, since the caller (qe_snums_init) uncritically assigns the return value to
> the unsigned qe_num_of_snum, and would thus proceed to attempt to copy
> 4GB from snum_init_46[] to the snum[] array.
>
> So fold the handling of the legacy fsl,qe-num-snums into qe_snums_init, and
> make sure we do not end up using the snum_init_46 array in cases other than
> the two where we know it makes sense.
>
> Signed-off-by: Rasmus Villemoes <rasmus.villemoes@xxxxxxxxx>
> ---

Reviewed-by: Qiang Zhao <qiang.zhao@xxxxxxx>

> drivers/soc/fsl/qe/qe.c | 46 ++++++++++++++---------------------------
> 1 file changed, 16 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index
> 325d689cbf5c..276d7d78ebfc 100644
> --- a/drivers/soc/fsl/qe/qe.c
> +++ b/drivers/soc/fsl/qe/qe.c
> @@ -308,24 +308,33 @@ static void qe_snums_init(void)
> int i;
>
> bitmap_zero(snum_state, QE_NUM_OF_SNUM);
> + qe_num_of_snum = 28; /* The default number of snum for threads
> + is 28 */
> qe = qe_get_device_node();
> if (qe) {
> i = of_property_read_variable_u8_array(qe, "fsl,qe-snums",
> snums, 1,
> QE_NUM_OF_SNUM);
> - of_node_put(qe);
> if (i > 0) {
> + of_node_put(qe);
> qe_num_of_snum = i;
> return;
> }
> + /*
> + * Fall back to legacy binding of using the value of
> + * fsl,qe-num-snums to choose one of the static arrays
> + * above.
> + */
> + of_property_read_u32(qe, "fsl,qe-num-snums",
> &qe_num_of_snum);
> + of_node_put(qe);
> }
>
> - qe_num_of_snum = qe_get_num_of_snums();
> -
> - if (qe_num_of_snum == 76)
> + if (qe_num_of_snum == 76) {
> snum_init = snum_init_76;
> - else
> + } else if (qe_num_of_snum == 28 || qe_num_of_snum == 46) {
> snum_init = snum_init_46;
> -
> + } else {
> + pr_err("QE: unsupported value of fsl,qe-num-snums: %u\n",
> qe_num_of_snum);
> + return;
> + }
> memcpy(snums, snum_init, qe_num_of_snum); }
>
> @@ -641,30 +650,7 @@ EXPORT_SYMBOL(qe_get_num_of_risc);
>
> unsigned int qe_get_num_of_snums(void)
> {
> - struct device_node *qe;
> - int size;
> - unsigned int num_of_snums;
> - const u32 *prop;
> -
> - num_of_snums = 28; /* The default number of snum for threads is 28
> */
> - qe = qe_get_device_node();
> - if (!qe)
> - return num_of_snums;
> -
> - prop = of_get_property(qe, "fsl,qe-num-snums", &size);
> - if (prop && size == sizeof(*prop)) {
> - num_of_snums = *prop;
> - if ((num_of_snums < 28) || (num_of_snums >
> QE_NUM_OF_SNUM)) {
> - /* No QE ever has fewer than 28 SNUMs */
> - pr_err("QE: number of snum is invalid\n");
> - of_node_put(qe);
> - return -EINVAL;
> - }
> - }
> -
> - of_node_put(qe);
> -
> - return num_of_snums;
> + return qe_num_of_snum;
> }
> EXPORT_SYMBOL(qe_get_num_of_snums);
>
> --
> 2.20.1

Best Regards
Qiang Zhao