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

of/reconfig: Always use the same structure for notifiers

The OF_RECONFIG notifier callback uses a different structure depending
on whether it is a node change or a property change. This is silly, and
not very safe. Rework the code to use the same data structure regardless
of the type of notifier.

Signed-off-by: Grant Likely <grant.likely@linaro.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Cc: <linuxppc-dev@lists.ozlabs.org>

+54 -49
+1 -2
arch/powerpc/mm/numa.c
··· 1711 1711 static int dt_update_callback(struct notifier_block *nb, 1712 1712 unsigned long action, void *data) 1713 1713 { 1714 - struct of_prop_reconfig *update; 1714 + struct of_reconfig_data *update = data; 1715 1715 int rc = NOTIFY_DONE; 1716 1716 1717 1717 switch (action) { 1718 1718 case OF_RECONFIG_UPDATE_PROPERTY: 1719 - update = (struct of_prop_reconfig *)data; 1720 1719 if (!of_prop_cmp(update->dn->type, "cpu") && 1721 1720 !of_prop_cmp(update->prop->name, "ibm,associativity")) { 1722 1721 u32 core_id;
+4 -3
arch/powerpc/platforms/pseries/hotplug-cpu.c
··· 340 340 } 341 341 342 342 static int pseries_smp_notifier(struct notifier_block *nb, 343 - unsigned long action, void *node) 343 + unsigned long action, void *data) 344 344 { 345 + struct of_reconfig_data *rd = data; 345 346 int err = 0; 346 347 347 348 switch (action) { 348 349 case OF_RECONFIG_ATTACH_NODE: 349 - err = pseries_add_processor(node); 350 + err = pseries_add_processor(rd->dn); 350 351 break; 351 352 case OF_RECONFIG_DETACH_NODE: 352 - pseries_remove_processor(node); 353 + pseries_remove_processor(rd->dn); 353 354 break; 354 355 } 355 356 return notifier_from_errno(err);
+7 -8
arch/powerpc/platforms/pseries/hotplug-memory.c
··· 183 183 return (ret < 0) ? -EINVAL : 0; 184 184 } 185 185 186 - static int pseries_update_drconf_memory(struct of_prop_reconfig *pr) 186 + static int pseries_update_drconf_memory(struct of_reconfig_data *pr) 187 187 { 188 188 struct of_drconf_cell *new_drmem, *old_drmem; 189 189 unsigned long memblock_size; ··· 232 232 } 233 233 234 234 static int pseries_memory_notifier(struct notifier_block *nb, 235 - unsigned long action, void *node) 235 + unsigned long action, void *data) 236 236 { 237 - struct of_prop_reconfig *pr; 237 + struct of_reconfig_data *rd = data; 238 238 int err = 0; 239 239 240 240 switch (action) { 241 241 case OF_RECONFIG_ATTACH_NODE: 242 - err = pseries_add_mem_node(node); 242 + err = pseries_add_mem_node(rd->dn); 243 243 break; 244 244 case OF_RECONFIG_DETACH_NODE: 245 - err = pseries_remove_mem_node(node); 245 + err = pseries_remove_mem_node(rd->dn); 246 246 break; 247 247 case OF_RECONFIG_UPDATE_PROPERTY: 248 - pr = (struct of_prop_reconfig *)node; 249 - if (!strcmp(pr->prop->name, "ibm,dynamic-memory")) 250 - err = pseries_update_drconf_memory(pr); 248 + if (!strcmp(rd->prop->name, "ibm,dynamic-memory")) 249 + err = pseries_update_drconf_memory(rd); 251 250 break; 252 251 } 253 252 return notifier_from_errno(err);
+3 -2
arch/powerpc/platforms/pseries/iommu.c
··· 1251 1251 .notifier_call = iommu_mem_notifier, 1252 1252 }; 1253 1253 1254 - static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) 1254 + static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *data) 1255 1255 { 1256 1256 int err = NOTIFY_OK; 1257 - struct device_node *np = node; 1257 + struct of_reconfig_data *rd = data; 1258 + struct device_node *np = rd->dn; 1258 1259 struct pci_dn *pci = PCI_DN(np); 1259 1260 struct direct_window *window; 1260 1261
+3 -2
arch/powerpc/platforms/pseries/setup.c
··· 251 251 " interrupt-controller\n"); 252 252 } 253 253 254 - static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) 254 + static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *data) 255 255 { 256 - struct device_node *np = node; 256 + struct of_reconfig_data *rd = data; 257 + struct device_node *np = rd->dn; 257 258 struct pci_dn *pci = NULL; 258 259 int err = NOTIFY_OK; 259 260
+2 -2
drivers/crypto/nx/nx-842.c
··· 1009 1009 * notifier_to_errno() to decode this value 1010 1010 */ 1011 1011 static int nx842_OF_notifier(struct notifier_block *np, unsigned long action, 1012 - void *update) 1012 + void *data) 1013 1013 { 1014 - struct of_prop_reconfig *upd = update; 1014 + struct of_reconfig_data *upd = data; 1015 1015 struct nx842_devdata *local_devdata; 1016 1016 struct device_node *node = NULL; 1017 1017
+21 -20
drivers/of/dynamic.c
··· 87 87 }; 88 88 #endif 89 89 90 - int of_reconfig_notify(unsigned long action, void *p) 90 + int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) 91 91 { 92 92 int rc; 93 93 #ifdef DEBUG 94 - struct device_node *dn = p; 95 - struct of_prop_reconfig *pr = p; 94 + struct of_reconfig_data *pr = p; 96 95 97 96 switch (action) { 98 97 case OF_RECONFIG_ATTACH_NODE: 99 98 case OF_RECONFIG_DETACH_NODE: 100 99 pr_debug("of/notify %-15s %s\n", action_names[action], 101 - dn->full_name); 100 + pr->dn->full_name); 102 101 break; 103 102 case OF_RECONFIG_ADD_PROPERTY: 104 103 case OF_RECONFIG_REMOVE_PROPERTY: ··· 121 122 * Returns 0 on device going from enabled to disabled, 1 on device 122 123 * going from disabled to enabled and -1 on no change. 123 124 */ 124 - int of_reconfig_get_state_change(unsigned long action, void *arg) 125 + int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr) 125 126 { 126 - struct device_node *dn; 127 - struct property *prop, *old_prop; 128 - struct of_prop_reconfig *pr; 127 + struct property *prop, *old_prop = NULL; 129 128 int is_status, status_state, old_status_state, prev_state, new_state; 130 129 131 130 /* figure out if a device should be created or destroyed */ 132 - dn = NULL; 133 - prop = old_prop = NULL; 134 131 switch (action) { 135 132 case OF_RECONFIG_ATTACH_NODE: 136 133 case OF_RECONFIG_DETACH_NODE: 137 - dn = arg; 138 - prop = of_find_property(dn, "status", NULL); 134 + prop = of_find_property(pr->dn, "status", NULL); 139 135 break; 140 136 case OF_RECONFIG_ADD_PROPERTY: 141 137 case OF_RECONFIG_REMOVE_PROPERTY: 142 - pr = arg; 143 - dn = pr->dn; 144 138 prop = pr->prop; 145 139 break; 146 140 case OF_RECONFIG_UPDATE_PROPERTY: 147 - pr = arg; 148 - dn = pr->dn; 149 141 prop = pr->prop; 150 142 old_prop = pr->old_prop; 151 143 break; ··· 202 212 int of_property_notify(int action, struct device_node *np, 203 213 struct property *prop, struct property *oldprop) 204 214 { 205 - struct of_prop_reconfig pr; 215 + struct of_reconfig_data pr; 206 216 207 217 /* only call notifiers if the node is attached */ 208 218 if (!of_node_is_attached(np)) ··· 240 250 */ 241 251 int of_attach_node(struct device_node *np) 242 252 { 253 + struct of_reconfig_data rd; 243 254 unsigned long flags; 255 + 256 + memset(&rd, 0, sizeof(rd)); 257 + rd.dn = np; 244 258 245 259 mutex_lock(&of_mutex); 246 260 raw_spin_lock_irqsave(&devtree_lock, flags); ··· 254 260 __of_attach_node_sysfs(np); 255 261 mutex_unlock(&of_mutex); 256 262 257 - of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np); 263 + of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd); 258 264 259 265 return 0; 260 266 } ··· 292 298 */ 293 299 int of_detach_node(struct device_node *np) 294 300 { 301 + struct of_reconfig_data rd; 295 302 unsigned long flags; 296 303 int rc = 0; 304 + 305 + memset(&rd, 0, sizeof(rd)); 306 + rd.dn = np; 297 307 298 308 mutex_lock(&of_mutex); 299 309 raw_spin_lock_irqsave(&devtree_lock, flags); ··· 307 309 __of_detach_node_sysfs(np); 308 310 mutex_unlock(&of_mutex); 309 311 310 - of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np); 312 + of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd); 311 313 312 314 return rc; 313 315 } ··· 503 505 504 506 static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert) 505 507 { 508 + struct of_reconfig_data rd; 506 509 struct of_changeset_entry ce_inverted; 507 510 int ret; 508 511 ··· 515 516 switch (ce->action) { 516 517 case OF_RECONFIG_ATTACH_NODE: 517 518 case OF_RECONFIG_DETACH_NODE: 518 - ret = of_reconfig_notify(ce->action, ce->np); 519 + memset(&rd, 0, sizeof(rd)); 520 + rd.dn = ce->np; 521 + ret = of_reconfig_notify(ce->action, &rd); 519 522 break; 520 523 case OF_RECONFIG_ADD_PROPERTY: 521 524 case OF_RECONFIG_REMOVE_PROPERTY:
+13 -10
include/linux/of.h
··· 73 73 uint32_t args[MAX_PHANDLE_ARGS]; 74 74 }; 75 75 76 + struct of_reconfig_data { 77 + struct device_node *dn; 78 + struct property *prop; 79 + struct property *old_prop; 80 + }; 81 + 76 82 /* initialize a node */ 77 83 extern struct kobj_type of_node_ktype; 78 84 static inline void of_node_init(struct device_node *node) ··· 323 317 #define OF_RECONFIG_ADD_PROPERTY 0x0003 324 318 #define OF_RECONFIG_REMOVE_PROPERTY 0x0004 325 319 #define OF_RECONFIG_UPDATE_PROPERTY 0x0005 326 - 327 - struct of_prop_reconfig { 328 - struct device_node *dn; 329 - struct property *prop; 330 - struct property *old_prop; 331 - }; 332 320 333 321 extern int of_attach_node(struct device_node *); 334 322 extern int of_detach_node(struct device_node *); ··· 892 892 #ifdef CONFIG_OF_DYNAMIC 893 893 extern int of_reconfig_notifier_register(struct notifier_block *); 894 894 extern int of_reconfig_notifier_unregister(struct notifier_block *); 895 - extern int of_reconfig_notify(unsigned long, void *); 896 - extern int of_reconfig_get_state_change(unsigned long action, void *arg); 895 + extern int of_reconfig_notify(unsigned long, struct of_reconfig_data *rd); 896 + extern int of_reconfig_get_state_change(unsigned long action, 897 + struct of_reconfig_data *arg); 897 898 898 899 extern void of_changeset_init(struct of_changeset *ocs); 899 900 extern void of_changeset_destroy(struct of_changeset *ocs); ··· 942 941 { 943 942 return -EINVAL; 944 943 } 945 - static inline int of_reconfig_notify(unsigned long action, void *arg) 944 + static inline int of_reconfig_notify(unsigned long action, 945 + struct of_reconfig_data *arg) 946 946 { 947 947 return -EINVAL; 948 948 } 949 - static inline int of_reconfig_get_state_change(unsigned long action, void *arg) 949 + static inline int of_reconfig_get_state_change(unsigned long action, 950 + struct of_reconfig_data *arg) 950 951 { 951 952 return -EINVAL; 952 953 }