mlx4_arg_parse() checks errno without clearing it first, so a stale value left by earlier code rejects a valid argument, while a malformed value such as "abc" sets no errno at all and is silently taken as zero. The end pointer is never checked, so "1junk" is accepted.
Base 0 was used, so a leading zero silently selected octal. The PCI_SLOT_NAME parser is left alone: it reads sysfs rather than a device argument. mr_ext_memseg_en is a boolean, so make the mlx4_conf field bool and parse it with rte_kvargs_handle_bool(). mlx4_arg_parse() serves several keys through a cast function pointer, so the boolean gets a call of its own and the generic loop skips it. The one bit field it is later copied into stays as it is. Signed-off-by: Stephen Hemminger <[email protected]> --- drivers/net/mlx4/mlx4.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index 28f1116891..1e64230e35 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -70,7 +70,7 @@ struct mlx4_conf { uint32_t present; /**< Bit-field for existing ports. */ uint32_t enabled; /**< Bit-field for user-enabled ports. */ } ports; - int mr_ext_memseg_en; + bool mr_ext_memseg_en; /** Whether memseg should be extended for MR creation. */ }; @@ -532,12 +532,10 @@ mlx4_ibv_device_to_pci_addr(const struct ibv_device *device, static int mlx4_arg_parse(const char *key, const char *val, struct mlx4_conf *conf) { - unsigned long tmp; + uint64_t tmp; - errno = 0; - tmp = strtoul(val, NULL, 0); - if (errno) { - rte_errno = errno; + if (rte_kvargs_to_uint(val, 0, UINT32_MAX, &tmp) < 0) { + rte_errno = EINVAL; WARN("%s: \"%s\" is not a valid integer", key, val); return -rte_errno; } @@ -545,18 +543,16 @@ mlx4_arg_parse(const char *key, const char *val, struct mlx4_conf *conf) uint32_t ports = rte_log2_u32(conf->ports.present + 1); if (tmp >= ports) { - ERROR("port index %lu outside range [0,%" PRIu32 ")", - tmp, ports); + ERROR("port index %u outside range [0,%u)", + (unsigned int)tmp, ports); return -EINVAL; } if (!(conf->ports.present & (1 << tmp))) { rte_errno = EINVAL; - ERROR("invalid port index %lu", tmp); + ERROR("invalid port index %u", (unsigned int)tmp); return -rte_errno; } conf->ports.enabled |= 1 << tmp; - } else if (strcmp(MLX4_MR_EXT_MEMSEG_EN_KVARG, key) == 0) { - conf->mr_ext_memseg_en = !!tmp; } else { rte_errno = EINVAL; WARN("%s: unknown parameter", key); @@ -590,8 +586,21 @@ mlx4_args(struct rte_devargs *devargs, struct mlx4_conf *conf) ERROR("failed to parse kvargs"); return -rte_errno; } + /* + * mr_ext_memseg_en is a boolean and has a handler of its own; the + * loop below covers the arguments which mlx4_arg_parse() handles. + */ + ret = rte_kvargs_process_opt(kvlist, MLX4_MR_EXT_MEMSEG_EN_KVARG, + rte_kvargs_handle_bool, + &conf->mr_ext_memseg_en); + if (ret != 0) + goto free_kvlist; + /* Process parameters. */ for (i = 0; pmd_mlx4_init_params[i]; ++i) { + if (strcmp(pmd_mlx4_init_params[i], + MLX4_MR_EXT_MEMSEG_EN_KVARG) == 0) + continue; arg_count = rte_kvargs_count(kvlist, pmd_mlx4_init_params[i]); while (arg_count-- > 0) { ret = rte_kvargs_process(kvlist, @@ -783,7 +792,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) struct rte_eth_dev *prev_dev = NULL; struct mlx4_conf conf = { .ports.present = 0, - .mr_ext_memseg_en = 1, + .mr_ext_memseg_en = true, }; unsigned int vf; int i; -- 2.53.0

