Extract input validation code, from param_set_dyndbg_module_classes()
(the sys-node >handler) to new: ddebug_classparam_clamp_input(kp),
call it from former.  It takes kernel-param arg, so it can complain
about "foo: bad input".

Reuse ddparam_clamp_input(kp) in ddebug_sync_classbits(),
to validate inputs from parent's params, just like our own.
To support that reuse, alter ddebug_sync_classbits() and caller to
pass kp instead of kp->arg.

Signed-off-by: Jim Cromie <jim.cro...@gmail.com>
---
 lib/dynamic_debug.c | 66 ++++++++++++++++++++++++++++++---------------
 1 file changed, 45 insertions(+), 21 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index c4d7a70a0723..63420f90bcb1 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -655,6 +655,30 @@ static int ddebug_apply_class_bitmap(const struct 
ddebug_class_param *dcp,
 
 #define CLASSMAP_BITMASK(width) ((1UL << (width)) - 1)
 
+static void ddebug_class_param_clamp_input(unsigned long *inrep, const struct 
kernel_param *kp)
+{
+       const struct ddebug_class_param *dcp = kp->arg;
+       const struct ddebug_class_map *map = dcp->map;
+
+       switch (map->map_type) {
+       case DD_CLASS_TYPE_DISJOINT_BITS:
+               /* expect bits. mask and warn if too many */
+               if (*inrep & ~CLASSMAP_BITMASK(map->length)) {
+                       pr_warn("%s: input: 0x%lx exceeds mask: 0x%lx, 
masking\n",
+                               KP_NAME(kp), *inrep, 
CLASSMAP_BITMASK(map->length));
+                       *inrep &= CLASSMAP_BITMASK(map->length);
+               }
+               break;
+       case DD_CLASS_TYPE_LEVEL_NUM:
+               /* input is bitpos, of highest verbosity to be enabled */
+               if (*inrep > map->length) {
+                       pr_warn("%s: level:%ld exceeds max:%d, clamping\n",
+                               KP_NAME(kp), *inrep, map->length);
+                       *inrep = map->length;
+               }
+               break;
+       }
+}
 static int param_set_dyndbg_module_classes(const char *instr,
                                           const struct kernel_param *kp,
                                           const char *modnm)
@@ -673,26 +697,15 @@ static int param_set_dyndbg_module_classes(const char 
*instr,
                pr_err("expecting numeric input, not: %s > %s\n", instr, 
KP_NAME(kp));
                return -EINVAL;
        }
+       ddebug_class_param_clamp_input(&inrep, kp);
 
        switch (map->map_type) {
        case DD_CLASS_TYPE_DISJOINT_BITS:
-               /* expect bits. mask and warn if too many */
-               if (inrep & ~CLASSMAP_BITMASK(map->length)) {
-                       pr_warn("%s: input: 0x%lx exceeds mask: 0x%lx, 
masking\n",
-                               KP_NAME(kp), inrep, 
CLASSMAP_BITMASK(map->length));
-                       inrep &= CLASSMAP_BITMASK(map->length);
-               }
                v2pr_info("bits:0x%lx > %s.%s\n", inrep, modnm ?: "*", 
KP_NAME(kp));
                totct += ddebug_apply_class_bitmap(dcp, &inrep, *dcp->bits, 
modnm);
                *dcp->bits = inrep;
                break;
        case DD_CLASS_TYPE_LEVEL_NUM:
-               /* input is bitpos, of highest verbosity to be enabled */
-               if (inrep > map->length) {
-                       pr_warn("%s: level:%ld exceeds max:%d, clamping\n",
-                               KP_NAME(kp), inrep, map->length);
-                       inrep = map->length;
-               }
                old_bits = CLASSMAP_BITMASK(*dcp->lvl);
                new_bits = CLASSMAP_BITMASK(inrep);
                v2pr_info("lvl:%ld bits:0x%lx > %s\n", inrep, new_bits, 
KP_NAME(kp));
@@ -1155,16 +1168,27 @@ static const char * const ddebug_classmap_typenames[] = 
{
                  ddebug_classmap_typenames[_cm->map_type]);            \
        })
 
-static void ddebug_sync_classbits(const struct ddebug_class_param *dcp, const 
char *modname)
+static void ddebug_sync_classbits(const struct kernel_param *kp, const char 
*modname)
 {
-       /* clamp initial bitvec, mask off hi-bits */
-       if (*dcp->bits & ~CLASSMAP_BITMASK(dcp->map->length)) {
-               *dcp->bits &= CLASSMAP_BITMASK(dcp->map->length);
-               v2pr_info("preset classbits: %lx\n", *dcp->bits);
+       struct ddebug_class_param *dcp = kp->arg;
+       unsigned long new_bits;
+
+       ddebug_class_param_clamp_input(dcp->bits, kp);
+
+       switch (dcp->map->map_type) {
+       case DD_CLASS_TYPE_DISJOINT_BITS:
+               v2pr_info("%s: classbits: 0x%lx\n", KP_NAME(kp), *dcp->bits);
+               ddebug_apply_class_bitmap(dcp, dcp->bits, 0UL, modname);
+               break;
+       case DD_CLASS_TYPE_LEVEL_NUM:
+               new_bits = CLASSMAP_BITMASK(*dcp->lvl);
+               v2pr_info("%s: lvl:%ld bits:0x%lx\n", KP_NAME(kp), *dcp->lvl, 
new_bits);
+               ddebug_apply_class_bitmap(dcp, &new_bits, 0UL, modname);
+               break;
+       default:
+               pr_err("bad map type %d\n", dcp->map->map_type);
+               return;
        }
-       /* force class'd prdbgs (in USEr module) to match (DEFINEr module) 
class-param */
-       ddebug_apply_class_bitmap(dcp, dcp->bits, ~0, modname);
-       ddebug_apply_class_bitmap(dcp, dcp->bits, 0, modname);
 }
 
 static void ddebug_match_apply_kparam(const struct kernel_param *kp,
@@ -1181,7 +1205,7 @@ static void ddebug_match_apply_kparam(const struct 
kernel_param *kp,
        if (map == dcp->map) {
                v2pr_info("found kp:%s =0x%lx", kp->name, *dcp->bits);
                vpr_cm_info(map, "mapped to:");
-               ddebug_sync_classbits(dcp, modnm);
+               ddebug_sync_classbits(kp, modnm);
        }
 }
 
-- 
2.41.0

Reply via email to