sysctl: replace SYSCTL_INT_CONV_CUSTOM macro with functions

Remove SYSCTL_INT_CONV_CUSTOM and replace it with proc_int_conv. This
converter function expects a negp argument as it can take on negative
values. Update all jiffies converters to use explicit function calls.
Remove SYSCTL_CONV_IDENTITY as it is no longer used.

Signed-off-by: Joel Granados <joel.granados@kernel.org>

+76 -56
+4 -42
include/linux/sysctl.h
··· 59 59 #define SYSCTL_LONG_ONE ((void *)&sysctl_long_vals[1]) 60 60 #define SYSCTL_LONG_MAX ((void *)&sysctl_long_vals[2]) 61 61 62 - #define SYSCTL_CONV_IDENTITY(val) (val) 63 62 /** 64 63 * 65 64 * "dir" originates from read_iter (dir = 0) or write_iter (dir = 1) ··· 71 72 */ 72 73 #define SYSCTL_USER_TO_KERN(dir) (!!(dir)) 73 74 #define SYSCTL_KERN_TO_USER(dir) (!dir) 74 - 75 - #ifdef CONFIG_PROC_SYSCTL 76 - /** 77 - * To range check on a converted value, use a temp k_ptr 78 - * When checking range, value should be within (tbl->extra1, tbl->extra2) 79 - */ 80 - #define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user, \ 81 - k_ptr_range_check) \ 82 - int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\ 83 - int dir, const struct ctl_table *tbl) \ 84 - { \ 85 - if (SYSCTL_KERN_TO_USER(dir)) \ 86 - return kern_to_user(negp, u_ptr, k_ptr); \ 87 - \ 88 - if (k_ptr_range_check) { \ 89 - int tmp_k, ret; \ 90 - if (!tbl) \ 91 - return -EINVAL; \ 92 - ret = user_to_kern(negp, u_ptr, &tmp_k); \ 93 - if (ret) \ 94 - return ret; \ 95 - if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) || \ 96 - (tbl->extra2 && *(int *)tbl->extra2 < tmp_k)) \ 97 - return -EINVAL; \ 98 - WRITE_ONCE(*k_ptr, tmp_k); \ 99 - } else \ 100 - return user_to_kern(negp, u_ptr, k_ptr); \ 101 - return 0; \ 102 - } 103 - 104 - #else // CONFIG_PROC_SYSCTL 105 - 106 - #define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user, \ 107 - k_ptr_range_check) \ 108 - int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\ 109 - int dir, const struct ctl_table *tbl) \ 110 - { \ 111 - return -ENOSYS; \ 112 - } 113 - 114 - #endif // CONFIG_PROC_SYSCTL 115 75 116 76 extern const unsigned long sysctl_long_vals[]; 117 77 ··· 92 134 ulong (*k_ptr_op)(const ulong)); 93 135 int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp, 94 136 ulong (*u_ptr_op)(const ulong)); 137 + int proc_int_conv(bool *negp, ulong *u_ptr, int *k_ptr, int dir, 138 + const struct ctl_table *tbl, bool k_ptr_range_check, 139 + int (*user_to_kern)(const bool *negp, const ulong *u_ptr, int *k_ptr), 140 + int (*kern_to_user)(bool *negp, ulong *u_ptr, const int *k_ptr)); 95 141 96 142 int proc_douintvec(const struct ctl_table *, int, void *, size_t *, loff_t *); 97 143 int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer,
+43 -4
kernel/sysctl.c
··· 515 515 return 0; 516 516 } 517 517 518 + int proc_int_conv(bool *negp, ulong *u_ptr, int *k_ptr, int dir, 519 + const struct ctl_table *tbl, bool k_ptr_range_check, 520 + int (*user_to_kern)(const bool *negp, const ulong *u_ptr, int *k_ptr), 521 + int (*kern_to_user)(bool *negp, ulong *u_ptr, const int *k_ptr)) 522 + { 523 + if (SYSCTL_KERN_TO_USER(dir)) 524 + return kern_to_user(negp, u_ptr, k_ptr); 525 + 526 + if (k_ptr_range_check) { 527 + int tmp_k, ret; 528 + 529 + if (!tbl) 530 + return -EINVAL; 531 + ret = user_to_kern(negp, u_ptr, &tmp_k); 532 + if (ret) 533 + return ret; 534 + if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) || 535 + (tbl->extra2 && *(int *)tbl->extra2 < tmp_k)) 536 + return -EINVAL; 537 + WRITE_ONCE(*k_ptr, tmp_k); 538 + } else 539 + return user_to_kern(negp, u_ptr, k_ptr); 540 + return 0; 541 + } 542 + 543 + 544 + 518 545 static int sysctl_user_to_kern_int_conv(const bool *negp, const ulong *u_ptr, 519 546 int *k_ptr) 520 547 { ··· 553 526 return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, NULL); 554 527 } 555 528 556 - static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv, 557 - sysctl_kern_to_user_int_conv, false) 558 - static SYSCTL_INT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_int_conv, 559 - sysctl_kern_to_user_int_conv, true) 529 + static int do_proc_int_conv(bool *negp, unsigned long *u_ptr, int *k_ptr, 530 + int dir, const struct ctl_table *tbl) 531 + { 532 + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false, 533 + sysctl_user_to_kern_int_conv, 534 + sysctl_kern_to_user_int_conv); 535 + 536 + } 537 + 538 + static int do_proc_int_conv_minmax(bool *negp, unsigned long *u_ptr, int *k_ptr, 539 + int dir, const struct ctl_table *tbl) 540 + { 541 + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, true, 542 + sysctl_user_to_kern_int_conv, 543 + sysctl_kern_to_user_int_conv); 544 + } 560 545 561 546 static const char proc_wspace_sep[] = { ' ', '\t', '\n' }; 562 547
+29 -10
kernel/time/jiffies.c
··· 156 156 return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, sysctl_jiffies_to_msecs); 157 157 } 158 158 159 + static int do_proc_int_conv_jiffies(bool *negp, ulong *u_ptr, int *k_ptr, 160 + int dir, const struct ctl_table *tbl) 161 + { 162 + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false, 163 + sysctl_u2k_int_conv_hz, sysctl_k2u_int_conv_hz); 164 + } 159 165 160 - static SYSCTL_INT_CONV_CUSTOM(_jiffies, sysctl_u2k_int_conv_hz, 161 - sysctl_k2u_int_conv_hz, false) 162 - static SYSCTL_INT_CONV_CUSTOM(_userhz_jiffies, 163 - sysctl_u2k_int_conv_userhz, 164 - sysctl_k2u_int_conv_userhz, false) 165 - static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies, sysctl_u2k_int_conv_ms, 166 - sysctl_k2u_int_conv_ms, false) 167 - static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies_minmax, 168 - sysctl_u2k_int_conv_ms, 169 - sysctl_k2u_int_conv_ms, true) 166 + static int do_proc_int_conv_userhz_jiffies(bool *negp, ulong *u_ptr, 167 + int *k_ptr, int dir, 168 + const struct ctl_table *tbl) 169 + { 170 + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false, 171 + sysctl_u2k_int_conv_userhz, 172 + sysctl_k2u_int_conv_userhz); 173 + } 174 + 175 + static int do_proc_int_conv_ms_jiffies(bool *negp, ulong *u_ptr, int *k_ptr, 176 + int dir, const struct ctl_table *tbl) 177 + { 178 + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false, 179 + sysctl_u2k_int_conv_ms, sysctl_k2u_int_conv_ms); 180 + } 181 + 182 + static int do_proc_int_conv_ms_jiffies_minmax(bool *negp, ulong *u_ptr, 183 + int *k_ptr, int dir, 184 + const struct ctl_table *tbl) 185 + { 186 + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false, 187 + sysctl_u2k_int_conv_ms, sysctl_k2u_int_conv_ms); 188 + } 170 189 171 190 #else // CONFIG_PROC_SYSCTL 172 191 static int do_proc_int_conv_jiffies(bool *negp, ulong *u_ptr, int *k_ptr,