Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sysctl: Replace unidirectional INT converter macros with functions

Replace SYSCTL_USER_TO_KERN_INT_CONV and SYSCTL_KERN_TO_USER_INT_CONV
macros with function implementing the same logic.This makes debugging
easier and aligns with the functions preference described in
coding-style.rst. Update all jiffies converters to use explicit function
implementations instead of macro-generated versions.

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

+165 -67
+7 -49
include/linux/sysctl.h
··· 74 74 #define SYSCTL_KERN_TO_USER(dir) (!dir) 75 75 76 76 #ifdef CONFIG_PROC_SYSCTL 77 - #define SYSCTL_USER_TO_KERN_INT_CONV(name, u_ptr_op) \ 78 - int sysctl_user_to_kern_int_conv##name(const bool *negp, \ 79 - const unsigned long *u_ptr,\ 80 - int *k_ptr) \ 81 - { \ 82 - unsigned long u = u_ptr_op(*u_ptr); \ 83 - if (*negp) { \ 84 - if (u > (unsigned long) INT_MAX + 1) \ 85 - return -EINVAL; \ 86 - WRITE_ONCE(*k_ptr, -u); \ 87 - } else { \ 88 - if (u > (unsigned long) INT_MAX) \ 89 - return -EINVAL; \ 90 - WRITE_ONCE(*k_ptr, u); \ 91 - } \ 92 - return 0; \ 93 - } 94 - 95 - #define SYSCTL_KERN_TO_USER_INT_CONV(name, k_ptr_op) \ 96 - int sysctl_kern_to_user_int_conv##name(bool *negp, \ 97 - unsigned long *u_ptr, \ 98 - const int *k_ptr) \ 99 - { \ 100 - int val = READ_ONCE(*k_ptr); \ 101 - if (val < 0) { \ 102 - *negp = true; \ 103 - *u_ptr = -k_ptr_op((unsigned long)val); \ 104 - } else { \ 105 - *negp = false; \ 106 - *u_ptr = k_ptr_op((unsigned long)val); \ 107 - } \ 108 - return 0; \ 109 - } 110 - 111 77 /** 112 78 * To range check on a converted value, use a temp k_ptr 113 79 * When checking range, value should be within (tbl->extra1, tbl->extra2) ··· 101 135 return user_to_kern(negp, u_ptr, k_ptr); \ 102 136 return 0; \ 103 137 } 104 - #else // CONFIG_PROC_SYSCTL 105 - #define SYSCTL_USER_TO_KERN_INT_CONV(name, u_ptr_op) \ 106 - int sysctl_user_to_kern_int_conv##name(const bool *negp, \ 107 - const unsigned long *u_ptr,\ 108 - int *k_ptr) \ 109 - { \ 110 - return -ENOSYS; \ 111 - } 112 138 113 - #define SYSCTL_KERN_TO_USER_INT_CONV(name, k_ptr_op) \ 114 - int sysctl_kern_to_user_int_conv##name(bool *negp, \ 115 - unsigned long *u_ptr, \ 116 - const int *k_ptr) \ 117 - { \ 118 - return -ENOSYS; \ 119 - } 139 + #else // CONFIG_PROC_SYSCTL 120 140 121 141 #define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user, \ 122 142 k_ptr_range_check) \ ··· 122 170 int proc_dostring(const struct ctl_table *, int, void *, size_t *, loff_t *); 123 171 int proc_dobool(const struct ctl_table *table, int write, void *buffer, 124 172 size_t *lenp, loff_t *ppos); 173 + 125 174 int proc_dointvec(const struct ctl_table *, int, void *, size_t *, loff_t *); 126 175 int proc_dointvec_minmax(const struct ctl_table *table, int dir, void *buffer, 127 176 size_t *lenp, loff_t *ppos); ··· 130 177 size_t *lenp, loff_t *ppos, 131 178 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, 132 179 int dir, const struct ctl_table *table)); 180 + int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp, 181 + ulong (*k_ptr_op)(const ulong)); 182 + int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp, 183 + ulong (*u_ptr_op)(const ulong)); 184 + 133 185 int proc_douintvec(const struct ctl_table *, int, void *, size_t *, loff_t *); 134 186 int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer, 135 187 size_t *lenp, loff_t *ppos);
+67 -2
kernel/sysctl.c
··· 458 458 proc_uint_u2k_conv, proc_uint_k2u_conv); 459 459 } 460 460 461 - static SYSCTL_USER_TO_KERN_INT_CONV(, SYSCTL_CONV_IDENTITY) 462 - static SYSCTL_KERN_TO_USER_INT_CONV(, SYSCTL_CONV_IDENTITY) 461 + /** 462 + * proc_int_k2u_conv_kop - Assign kernel value to a user space pointer 463 + * @u_ptr: pointer to user space variable 464 + * @k_ptr: pointer to kernel variable 465 + * @negp: assigned %TRUE if the converted kernel value is negative; 466 + * %FALSE otherweise 467 + * @k_ptr_op: execute this function before assigning to u_ptr 468 + * 469 + * Uses READ_ONCE to get value from k_ptr. Executes k_ptr_op before assigning 470 + * to u_ptr if not NULL. Does **not** check for overflow. 471 + * 472 + * Returns: 0 on success. 473 + */ 474 + int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp, 475 + ulong (*k_ptr_op)(const ulong)) 476 + { 477 + int val = READ_ONCE(*k_ptr); 478 + 479 + if (val < 0) { 480 + *negp = true; 481 + *u_ptr = k_ptr_op ? -k_ptr_op((ulong)val) : -(ulong)val; 482 + } else { 483 + *negp = false; 484 + *u_ptr = k_ptr_op ? k_ptr_op((ulong)val) : (ulong) val; 485 + } 486 + return 0; 487 + } 488 + 489 + /** 490 + * proc_int_u2k_conv_uop - Assign user value to a kernel pointer 491 + * @u_ptr: pointer to user space variable 492 + * @k_ptr: pointer to kernel variable 493 + * @negp: If %TRUE, the converted user value is made negative. 494 + * @u_ptr_op: execute this function before assigning to k_ptr 495 + * 496 + * Uses WRITE_ONCE to assign value to k_ptr. Executes u_ptr_op if 497 + * not NULL. Check for overflow with UINT_MAX. 498 + * 499 + * Returns: 0 on success. 500 + */ 501 + int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp, 502 + ulong (*u_ptr_op)(const ulong)) 503 + { 504 + ulong u = u_ptr_op ? u_ptr_op(*u_ptr) : *u_ptr; 505 + 506 + if (*negp) { 507 + if (u > (ulong) INT_MAX + 1) 508 + return -EINVAL; 509 + WRITE_ONCE(*k_ptr, -u); 510 + } else { 511 + if (u > (ulong) INT_MAX) 512 + return -EINVAL; 513 + WRITE_ONCE(*k_ptr, u); 514 + } 515 + return 0; 516 + } 517 + 518 + static int sysctl_user_to_kern_int_conv(const bool *negp, const ulong *u_ptr, 519 + int *k_ptr) 520 + { 521 + return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, NULL); 522 + } 523 + 524 + static int sysctl_kern_to_user_int_conv(bool *negp, ulong *u_ptr, const int *k_ptr) 525 + { 526 + return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, NULL); 527 + } 463 528 464 529 static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv, 465 530 sysctl_kern_to_user_int_conv, false)
+91 -16
kernel/time/jiffies.c
··· 100 100 __clocksource_register(&refined_jiffies); 101 101 } 102 102 103 - #define SYSCTL_CONV_MULT_HZ(val) ((val) * HZ) 104 - #define SYSCTL_CONV_DIV_HZ(val) ((val) / HZ) 103 + #ifdef CONFIG_PROC_SYSCTL 104 + static ulong mult_hz(const ulong val) 105 + { 106 + return val * HZ; 107 + } 105 108 106 - static SYSCTL_USER_TO_KERN_INT_CONV(_hz, SYSCTL_CONV_MULT_HZ) 107 - static SYSCTL_KERN_TO_USER_INT_CONV(_hz, SYSCTL_CONV_DIV_HZ) 108 - static SYSCTL_USER_TO_KERN_INT_CONV(_userhz, clock_t_to_jiffies) 109 - static SYSCTL_KERN_TO_USER_INT_CONV(_userhz, jiffies_to_clock_t) 110 - static SYSCTL_USER_TO_KERN_INT_CONV(_ms, msecs_to_jiffies) 111 - static SYSCTL_KERN_TO_USER_INT_CONV(_ms, jiffies_to_msecs) 109 + static ulong div_hz(const ulong val) 110 + { 111 + return val / HZ; 112 + } 112 113 113 - static SYSCTL_INT_CONV_CUSTOM(_jiffies, sysctl_user_to_kern_int_conv_hz, 114 - sysctl_kern_to_user_int_conv_hz, false) 114 + static int sysctl_u2k_int_conv_hz(const bool *negp, const ulong *u_ptr, int *k_ptr) 115 + { 116 + return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, mult_hz); 117 + } 118 + 119 + static int sysctl_k2u_int_conv_hz(bool *negp, ulong *u_ptr, const int *k_ptr) 120 + { 121 + return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, div_hz); 122 + } 123 + 124 + static int sysctl_u2k_int_conv_userhz(const bool *negp, const ulong *u_ptr, int *k_ptr) 125 + { 126 + return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, clock_t_to_jiffies); 127 + } 128 + 129 + static ulong sysctl_jiffies_to_clock_t(const ulong val) 130 + { 131 + return jiffies_to_clock_t(val); 132 + } 133 + 134 + static int sysctl_k2u_int_conv_userhz(bool *negp, ulong *u_ptr, const int *k_ptr) 135 + { 136 + return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, sysctl_jiffies_to_clock_t); 137 + } 138 + 139 + static ulong sysctl_msecs_to_jiffies(const ulong val) 140 + { 141 + return msecs_to_jiffies(val); 142 + } 143 + 144 + static int sysctl_u2k_int_conv_ms(const bool *negp, const ulong *u_ptr, int *k_ptr) 145 + { 146 + return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, sysctl_msecs_to_jiffies); 147 + } 148 + 149 + static ulong sysctl_jiffies_to_msecs(const ulong val) 150 + { 151 + return jiffies_to_msecs(val); 152 + } 153 + 154 + static int sysctl_k2u_int_conv_ms(bool *negp, ulong *u_ptr, const int *k_ptr) 155 + { 156 + return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, sysctl_jiffies_to_msecs); 157 + } 158 + 159 + 160 + static SYSCTL_INT_CONV_CUSTOM(_jiffies, sysctl_u2k_int_conv_hz, 161 + sysctl_k2u_int_conv_hz, false) 115 162 static SYSCTL_INT_CONV_CUSTOM(_userhz_jiffies, 116 - sysctl_user_to_kern_int_conv_userhz, 117 - sysctl_kern_to_user_int_conv_userhz, false) 118 - static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies, sysctl_user_to_kern_int_conv_ms, 119 - sysctl_kern_to_user_int_conv_ms, false) 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) 120 167 static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies_minmax, 121 - sysctl_user_to_kern_int_conv_ms, 122 - sysctl_kern_to_user_int_conv_ms, true) 168 + sysctl_u2k_int_conv_ms, 169 + sysctl_k2u_int_conv_ms, true) 170 + 171 + #else // CONFIG_PROC_SYSCTL 172 + static int do_proc_int_conv_jiffies(bool *negp, ulong *u_ptr, int *k_ptr, 173 + int dir, const struct ctl_table *tbl) 174 + { 175 + return -ENOSYS; 176 + } 177 + 178 + static int do_proc_int_conv_userhz_jiffies(bool *negp, ulong *u_ptr, 179 + int *k_ptr, int dir, 180 + const struct ctl_table *tbl) 181 + { 182 + return -ENOSYS; 183 + } 184 + 185 + static int do_proc_int_conv_ms_jiffies(bool *negp, ulong *u_ptr, int *k_ptr, 186 + int dir, const struct ctl_table *tbl) 187 + { 188 + return -ENOSYS; 189 + } 190 + 191 + static int do_proc_int_conv_ms_jiffies_minmax(bool *negp, ulong *u_ptr, 192 + int *k_ptr, int dir, 193 + const struct ctl_table *tbl) 194 + { 195 + return -ENOSYS; 196 + } 197 + #endif 123 198 124 199 /** 125 200 * proc_dointvec_jiffies - read a vector of integers as seconds