[PATCH 56/62] baseband/la12xx: use kvargs numeric helpers
From: Stephen Hemminger <stephen@networkplumber.org>
Date: 2026-09-14 05:54:47
Subsystem:
the rest · Maintainer:
Linus Torvalds
parse_u16_arg() stored through a uint16_t pointer and parse_integer_arg()
through a uint32_t pointer, but both device arguments are 8 bit fields:
queues_num is a uint8_t and modem_id an int8_t, and they are adjacent in
struct bbdev_la12xx_params. Parsing either argument therefore wrote past
the field and corrupted its neighbour.
parse_u16_arg() did nothing beyond a range checked store, so drop it and
pass rte_kvargs_handle_u8() directly, which also gives queues_num the
width it actually has.
The modem id keeps a handler of its own. parse_integer_arg() rejected
both ends of the range, and a plain rte_kvargs_handle_i8() would accept
anything down to -128 while the caller only checks the upper bound, so
"modem=-5" would be stored and only fail later in open_ipc_dev(). The
new handler bounds it to -1..LA12XX_MAX_MODEM-1, keeping -1 which
la12xx_bbdev_create() uses to mean "derive the modem id from the device
id", and replaces the caller's upper bound check.
The handler now rejects an out of range modem id, where the old check
did a "goto exit" with ret still zero. The probe also checks the result
of parse_bbdev_la12xx_params(), which it used to discard, so a bad modem
id or queue count now fails the probe instead of only being logged.
Fixes: ee36ba0f3042 ("baseband/la12xx: add devargs option for max queues")
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
drivers/baseband/la12xx/bbdev_la12xx.c | 60 +++++++++-----------------
1 file changed, 20 insertions(+), 40 deletions(-)
diff --git a/drivers/baseband/la12xx/bbdev_la12xx.c b/drivers/baseband/la12xx/bbdev_la12xx.c
index 1116dacc4b..b9199189e7 100644
--- a/drivers/baseband/la12xx/bbdev_la12xx.c
+++ b/drivers/baseband/la12xx/bbdev_la12xx.c@@ -912,44 +912,25 @@ setup_la12xx_dev(struct rte_bbdev *dev) return ret; } -static inline int -parse_u16_arg(const char *key, const char *value, void *extra_args) -{ - uint16_t *u16 = extra_args; - - uint64_t result; - if ((value == NULL) || (extra_args == NULL)) - return -EINVAL; - errno = 0; - result = strtoul(value, NULL, 0); - if ((result >= (1 << 16)) || (errno != 0)) { - rte_bbdev_log(ERR, "Invalid value %" PRIu64 " for %s", - result, key); - return -ERANGE; - } - *u16 = (uint16_t)result; - return 0; -} - -/* Parse integer from integer argument */ +/* + * Parse the modem id. + * + * A dedicated handler is needed because -1 is meaningful here: it leaves the + * modem id unset, and la12xx_bbdev_create() then derives it from the device + * id. rte_kvargs_handle_i8() alone would also accept anything down to -128. + */ static int -parse_integer_arg(const char *key __rte_unused, - const char *value, void *extra_args) +parse_modem_id(const char *key, const char *value, void *extra_args) { - int i; - char *end; - - errno = 0; + int64_t modem_id; - i = strtol(value, &end, 10); - if (*end != 0 || errno != 0 || i < 0 || i > LA12XX_MAX_MODEM) { - rte_bbdev_log(ERR, "Supported Port IDS are 0 to %d", - LA12XX_MAX_MODEM - 1); + if (rte_kvargs_to_int(value, -1, LA12XX_MAX_MODEM - 1, &modem_id) < 0) { + rte_bbdev_log(ERR, "Invalid %s, must be -1..%u", key, + LA12XX_MAX_MODEM - 1); return -EINVAL; } - *((uint32_t *)extra_args) = i; - + *(int8_t *)extra_args = modem_id; return 0; }
@@ -970,20 +951,16 @@ parse_bbdev_la12xx_params(struct bbdev_la12xx_params *params, return -EFAULT; ret = rte_kvargs_process(kvlist, bbdev_la12xx_valid_params[0], - &parse_u16_arg, ¶ms->queues_num); + rte_kvargs_handle_u8, ¶ms->queues_num); if (ret < 0) goto exit; ret = rte_kvargs_process(kvlist, bbdev_la12xx_valid_params[1], - &parse_integer_arg, + parse_modem_id, ¶ms->modem_id); - - if (params->modem_id >= LA12XX_MAX_MODEM) { - rte_bbdev_log(ERR, "Invalid modem id, must be < %u", - LA12XX_MAX_MODEM); + if (ret < 0) goto exit; - } } exit:
@@ -1062,6 +1039,7 @@ la12xx_bbdev_probe(struct rte_vdev_device *vdev) }; const char *name; const char *input_args; + int ret; PMD_INIT_FUNC_TRACE();
@@ -1073,7 +1051,9 @@ la12xx_bbdev_probe(struct rte_vdev_device *vdev) return -EINVAL; input_args = rte_vdev_device_args(vdev); - parse_bbdev_la12xx_params(&init_params, input_args); + ret = parse_bbdev_la12xx_params(&init_params, input_args); + if (ret < 0) + return ret; return la12xx_bbdev_create(vdev, &init_params); }
--
2.53.0