1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2016 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 5 */ 6 7 #include <linux/device.h> 8 #include <net/genetlink.h> 9 #include <net/sock.h> 10 #include "devl_internal.h" 11 12 struct devlink_info_req { 13 struct sk_buff *msg; 14 void (*version_cb)(const char *version_name, 15 enum devlink_info_version_type version_type, 16 void *version_cb_priv); 17 void *version_cb_priv; 18 }; 19 20 struct devlink_reload_combination { 21 enum devlink_reload_action action; 22 enum devlink_reload_limit limit; 23 }; 24 25 static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = { 26 { 27 /* can't reinitialize driver with no down time */ 28 .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 29 .limit = DEVLINK_RELOAD_LIMIT_NO_RESET, 30 }, 31 }; 32 33 static bool 34 devlink_reload_combination_is_invalid(enum devlink_reload_action action, 35 enum devlink_reload_limit limit) 36 { 37 int i; 38 39 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) 40 if (devlink_reload_invalid_combinations[i].action == action && 41 devlink_reload_invalid_combinations[i].limit == limit) 42 return true; 43 return false; 44 } 45 46 static bool 47 devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action) 48 { 49 return test_bit(action, &devlink->ops->reload_actions); 50 } 51 52 static bool 53 devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit) 54 { 55 return test_bit(limit, &devlink->ops->reload_limits); 56 } 57 58 static int devlink_reload_stat_put(struct sk_buff *msg, 59 enum devlink_reload_limit limit, u32 value) 60 { 61 struct nlattr *reload_stats_entry; 62 63 reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY); 64 if (!reload_stats_entry) 65 return -EMSGSIZE; 66 67 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || 68 nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value)) 69 goto nla_put_failure; 70 nla_nest_end(msg, reload_stats_entry); 71 return 0; 72 73 nla_put_failure: 74 nla_nest_cancel(msg, reload_stats_entry); 75 return -EMSGSIZE; 76 } 77 78 static int 79 devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote) 80 { 81 struct nlattr *reload_stats_attr, *act_info, *act_stats; 82 int i, j, stat_idx; 83 u32 value; 84 85 if (!is_remote) 86 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS); 87 else 88 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS); 89 90 if (!reload_stats_attr) 91 return -EMSGSIZE; 92 93 for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { 94 if ((!is_remote && 95 !devlink_reload_action_is_supported(devlink, i)) || 96 i == DEVLINK_RELOAD_ACTION_UNSPEC) 97 continue; 98 act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO); 99 if (!act_info) 100 goto nla_put_failure; 101 102 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i)) 103 goto action_info_nest_cancel; 104 act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS); 105 if (!act_stats) 106 goto action_info_nest_cancel; 107 108 for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { 109 /* Remote stats are shown even if not locally supported. 110 * Stats of actions with unspecified limit are shown 111 * though drivers don't need to register unspecified 112 * limit. 113 */ 114 if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC && 115 !devlink_reload_limit_is_supported(devlink, j)) || 116 devlink_reload_combination_is_invalid(i, j)) 117 continue; 118 119 stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i; 120 if (!is_remote) 121 value = devlink->stats.reload_stats[stat_idx]; 122 else 123 value = devlink->stats.remote_reload_stats[stat_idx]; 124 if (devlink_reload_stat_put(msg, j, value)) 125 goto action_stats_nest_cancel; 126 } 127 nla_nest_end(msg, act_stats); 128 nla_nest_end(msg, act_info); 129 } 130 nla_nest_end(msg, reload_stats_attr); 131 return 0; 132 133 action_stats_nest_cancel: 134 nla_nest_cancel(msg, act_stats); 135 action_info_nest_cancel: 136 nla_nest_cancel(msg, act_info); 137 nla_put_failure: 138 nla_nest_cancel(msg, reload_stats_attr); 139 return -EMSGSIZE; 140 } 141 142 static int devlink_nl_nested_fill(struct sk_buff *msg, struct devlink *devlink) 143 { 144 unsigned long rel_index; 145 void *unused; 146 int err; 147 148 xa_for_each(&devlink->nested_rels, rel_index, unused) { 149 err = devlink_rel_devlink_handle_put(msg, devlink, 150 rel_index, 151 DEVLINK_ATTR_NESTED_DEVLINK, 152 NULL); 153 if (err) 154 return err; 155 } 156 return 0; 157 } 158 159 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink, 160 enum devlink_command cmd, u32 portid, 161 u32 seq, int flags) 162 { 163 struct nlattr *dev_stats; 164 void *hdr; 165 166 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 167 if (!hdr) 168 return -EMSGSIZE; 169 170 if (devlink_nl_put_handle(msg, devlink)) 171 goto nla_put_failure; 172 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed)) 173 goto nla_put_failure; 174 175 dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS); 176 if (!dev_stats) 177 goto nla_put_failure; 178 179 if (devlink_reload_stats_put(msg, devlink, false)) 180 goto dev_stats_nest_cancel; 181 if (devlink_reload_stats_put(msg, devlink, true)) 182 goto dev_stats_nest_cancel; 183 184 nla_nest_end(msg, dev_stats); 185 186 if (devlink_nl_nested_fill(msg, devlink)) 187 goto nla_put_failure; 188 189 genlmsg_end(msg, hdr); 190 return 0; 191 192 dev_stats_nest_cancel: 193 nla_nest_cancel(msg, dev_stats); 194 nla_put_failure: 195 genlmsg_cancel(msg, hdr); 196 return -EMSGSIZE; 197 } 198 199 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd) 200 { 201 struct sk_buff *msg; 202 int err; 203 204 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL); 205 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)); 206 207 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 208 if (!msg) 209 return; 210 211 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0); 212 if (err) { 213 nlmsg_free(msg); 214 return; 215 } 216 217 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 218 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 219 } 220 221 int devlink_nl_get_doit(struct sk_buff *skb, struct genl_info *info) 222 { 223 struct devlink *devlink = info->user_ptr[0]; 224 struct sk_buff *msg; 225 int err; 226 227 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 228 if (!msg) 229 return -ENOMEM; 230 231 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 232 info->snd_portid, info->snd_seq, 0); 233 if (err) { 234 nlmsg_free(msg); 235 return err; 236 } 237 238 return genlmsg_reply(msg, info); 239 } 240 241 static int 242 devlink_nl_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 243 struct netlink_callback *cb, int flags) 244 { 245 return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 246 NETLINK_CB(cb->skb).portid, 247 cb->nlh->nlmsg_seq, flags); 248 } 249 250 int devlink_nl_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) 251 { 252 return devlink_nl_dumpit(msg, cb, devlink_nl_get_dump_one); 253 } 254 255 static void devlink_rel_notify_cb(struct devlink *devlink, u32 obj_index) 256 { 257 devlink_notify(devlink, DEVLINK_CMD_NEW); 258 } 259 260 static void devlink_rel_cleanup_cb(struct devlink *devlink, u32 obj_index, 261 u32 rel_index) 262 { 263 xa_erase(&devlink->nested_rels, rel_index); 264 } 265 266 int devl_nested_devlink_set(struct devlink *devlink, 267 struct devlink *nested_devlink) 268 { 269 u32 rel_index; 270 int err; 271 272 err = devlink_rel_nested_in_add(&rel_index, devlink->index, 0, 273 devlink_rel_notify_cb, 274 devlink_rel_cleanup_cb, 275 nested_devlink); 276 if (err) 277 return err; 278 return xa_insert(&devlink->nested_rels, rel_index, 279 xa_mk_value(0), GFP_KERNEL); 280 } 281 EXPORT_SYMBOL_GPL(devl_nested_devlink_set); 282 283 void devlink_notify_register(struct devlink *devlink) 284 { 285 devlink_notify(devlink, DEVLINK_CMD_NEW); 286 devlink_linecards_notify_register(devlink); 287 devlink_ports_notify_register(devlink); 288 devlink_trap_policers_notify_register(devlink); 289 devlink_trap_groups_notify_register(devlink); 290 devlink_traps_notify_register(devlink); 291 devlink_rates_notify_register(devlink); 292 devlink_regions_notify_register(devlink); 293 devlink_params_notify_register(devlink); 294 } 295 296 void devlink_notify_unregister(struct devlink *devlink) 297 { 298 devlink_params_notify_unregister(devlink); 299 devlink_regions_notify_unregister(devlink); 300 devlink_rates_notify_unregister(devlink); 301 devlink_traps_notify_unregister(devlink); 302 devlink_trap_groups_notify_unregister(devlink); 303 devlink_trap_policers_notify_unregister(devlink); 304 devlink_ports_notify_unregister(devlink); 305 devlink_linecards_notify_unregister(devlink); 306 devlink_notify(devlink, DEVLINK_CMD_DEL); 307 } 308 309 static void devlink_reload_failed_set(struct devlink *devlink, 310 bool reload_failed) 311 { 312 if (devlink->reload_failed == reload_failed) 313 return; 314 devlink->reload_failed = reload_failed; 315 devlink_notify(devlink, DEVLINK_CMD_NEW); 316 } 317 318 bool devlink_is_reload_failed(const struct devlink *devlink) 319 { 320 return devlink->reload_failed; 321 } 322 EXPORT_SYMBOL_GPL(devlink_is_reload_failed); 323 324 static void 325 __devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats, 326 enum devlink_reload_limit limit, u32 actions_performed) 327 { 328 unsigned long actions = actions_performed; 329 int stat_idx; 330 int action; 331 332 for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) { 333 stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action; 334 reload_stats[stat_idx]++; 335 } 336 devlink_notify(devlink, DEVLINK_CMD_NEW); 337 } 338 339 static void 340 devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit, 341 u32 actions_performed) 342 { 343 __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit, 344 actions_performed); 345 } 346 347 /** 348 * devlink_remote_reload_actions_performed - Update devlink on reload actions 349 * performed which are not a direct result of devlink reload call. 350 * 351 * This should be called by a driver after performing reload actions in case it was not 352 * a result of devlink reload call. For example fw_activate was performed as a result 353 * of devlink reload triggered fw_activate on another host. 354 * The motivation for this function is to keep data on reload actions performed on this 355 * function whether it was done due to direct devlink reload call or not. 356 * 357 * @devlink: devlink 358 * @limit: reload limit 359 * @actions_performed: bitmask of actions performed 360 */ 361 void devlink_remote_reload_actions_performed(struct devlink *devlink, 362 enum devlink_reload_limit limit, 363 u32 actions_performed) 364 { 365 if (WARN_ON(!actions_performed || 366 actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 367 actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) || 368 limit > DEVLINK_RELOAD_LIMIT_MAX)) 369 return; 370 371 __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit, 372 actions_performed); 373 } 374 EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed); 375 376 static struct net *devlink_netns_get(struct sk_buff *skb, 377 struct genl_info *info) 378 { 379 struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID]; 380 struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD]; 381 struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID]; 382 struct net *net; 383 384 if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) { 385 NL_SET_ERR_MSG(info->extack, "multiple netns identifying attributes specified"); 386 return ERR_PTR(-EINVAL); 387 } 388 389 if (netns_pid_attr) { 390 net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr)); 391 } else if (netns_fd_attr) { 392 net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr)); 393 } else if (netns_id_attr) { 394 net = get_net_ns_by_id(sock_net(skb->sk), 395 nla_get_u32(netns_id_attr)); 396 if (!net) 397 net = ERR_PTR(-EINVAL); 398 } else { 399 WARN_ON(1); 400 net = ERR_PTR(-EINVAL); 401 } 402 if (IS_ERR(net)) { 403 NL_SET_ERR_MSG(info->extack, "Unknown network namespace"); 404 return ERR_PTR(-EINVAL); 405 } 406 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { 407 put_net(net); 408 return ERR_PTR(-EPERM); 409 } 410 return net; 411 } 412 413 static void devlink_reload_netns_change(struct devlink *devlink, 414 struct net *curr_net, 415 struct net *dest_net) 416 { 417 /* Userspace needs to be notified about devlink objects 418 * removed from original and entering new network namespace. 419 * The rest of the devlink objects are re-created during 420 * reload process so the notifications are generated separatelly. 421 */ 422 devlink_notify_unregister(devlink); 423 write_pnet(&devlink->_net, dest_net); 424 devlink_notify_register(devlink); 425 devlink_rel_nested_in_notify(devlink); 426 } 427 428 static void devlink_reload_reinit_sanity_check(struct devlink *devlink) 429 { 430 WARN_ON(!list_empty(&devlink->trap_policer_list)); 431 WARN_ON(!list_empty(&devlink->trap_group_list)); 432 WARN_ON(!list_empty(&devlink->trap_list)); 433 WARN_ON(!list_empty(&devlink->dpipe_table_list)); 434 WARN_ON(!list_empty(&devlink->sb_list)); 435 WARN_ON(!list_empty(&devlink->rate_list)); 436 WARN_ON(!list_empty(&devlink->linecard_list)); 437 WARN_ON(!xa_empty(&devlink->ports)); 438 } 439 440 int devlink_reload(struct devlink *devlink, struct net *dest_net, 441 enum devlink_reload_action action, 442 enum devlink_reload_limit limit, 443 u32 *actions_performed, struct netlink_ext_ack *extack) 444 { 445 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; 446 struct net *curr_net; 447 int err; 448 449 /* Make sure the reload operations are invoked with the device lock 450 * held to allow drivers to trigger functionality that expects it 451 * (e.g., PCI reset) and to close possible races between these 452 * operations and probe/remove. 453 */ 454 device_lock_assert(devlink->dev); 455 456 memcpy(remote_reload_stats, devlink->stats.remote_reload_stats, 457 sizeof(remote_reload_stats)); 458 459 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack); 460 if (err) 461 return err; 462 463 curr_net = devlink_net(devlink); 464 if (dest_net && !net_eq(dest_net, curr_net)) 465 devlink_reload_netns_change(devlink, curr_net, dest_net); 466 467 if (action == DEVLINK_RELOAD_ACTION_DRIVER_REINIT) { 468 devlink_params_driverinit_load_new(devlink); 469 devlink_reload_reinit_sanity_check(devlink); 470 } 471 472 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack); 473 devlink_reload_failed_set(devlink, !!err); 474 if (err) 475 return err; 476 477 WARN_ON(!(*actions_performed & BIT(action))); 478 /* Catch driver on updating the remote action within devlink reload */ 479 WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats, 480 sizeof(remote_reload_stats))); 481 devlink_reload_stats_update(devlink, limit, *actions_performed); 482 return 0; 483 } 484 485 static int 486 devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed, 487 enum devlink_command cmd, struct genl_info *info) 488 { 489 struct sk_buff *msg; 490 void *hdr; 491 492 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 493 if (!msg) 494 return -ENOMEM; 495 496 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd); 497 if (!hdr) 498 goto free_msg; 499 500 if (devlink_nl_put_handle(msg, devlink)) 501 goto nla_put_failure; 502 503 if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed, 504 actions_performed)) 505 goto nla_put_failure; 506 genlmsg_end(msg, hdr); 507 508 return genlmsg_reply(msg, info); 509 510 nla_put_failure: 511 genlmsg_cancel(msg, hdr); 512 free_msg: 513 nlmsg_free(msg); 514 return -EMSGSIZE; 515 } 516 517 int devlink_nl_reload_doit(struct sk_buff *skb, struct genl_info *info) 518 { 519 struct devlink *devlink = info->user_ptr[0]; 520 enum devlink_reload_action action; 521 enum devlink_reload_limit limit; 522 struct net *dest_net = NULL; 523 u32 actions_performed; 524 int err; 525 526 err = devlink_resources_validate(devlink, NULL, info); 527 if (err) { 528 NL_SET_ERR_MSG(info->extack, "resources size validation failed"); 529 return err; 530 } 531 532 if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION]) 533 action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]); 534 else 535 action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT; 536 537 if (!devlink_reload_action_is_supported(devlink, action)) { 538 NL_SET_ERR_MSG(info->extack, "Requested reload action is not supported by the driver"); 539 return -EOPNOTSUPP; 540 } 541 542 limit = DEVLINK_RELOAD_LIMIT_UNSPEC; 543 if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) { 544 struct nla_bitfield32 limits; 545 u32 limits_selected; 546 547 limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]); 548 limits_selected = limits.value & limits.selector; 549 if (!limits_selected) { 550 NL_SET_ERR_MSG(info->extack, "Invalid limit selected"); 551 return -EINVAL; 552 } 553 for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++) 554 if (limits_selected & BIT(limit)) 555 break; 556 /* UAPI enables multiselection, but currently it is not used */ 557 if (limits_selected != BIT(limit)) { 558 NL_SET_ERR_MSG(info->extack, "Multiselection of limit is not supported"); 559 return -EOPNOTSUPP; 560 } 561 if (!devlink_reload_limit_is_supported(devlink, limit)) { 562 NL_SET_ERR_MSG(info->extack, "Requested limit is not supported by the driver"); 563 return -EOPNOTSUPP; 564 } 565 if (devlink_reload_combination_is_invalid(action, limit)) { 566 NL_SET_ERR_MSG(info->extack, "Requested limit is invalid for this action"); 567 return -EINVAL; 568 } 569 } 570 if (info->attrs[DEVLINK_ATTR_NETNS_PID] || 571 info->attrs[DEVLINK_ATTR_NETNS_FD] || 572 info->attrs[DEVLINK_ATTR_NETNS_ID]) { 573 dest_net = devlink_netns_get(skb, info); 574 if (IS_ERR(dest_net)) 575 return PTR_ERR(dest_net); 576 if (!net_eq(dest_net, devlink_net(devlink)) && 577 action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT) { 578 NL_SET_ERR_MSG_MOD(info->extack, 579 "Changing namespace is only supported for reinit action"); 580 return -EOPNOTSUPP; 581 } 582 } 583 584 err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack); 585 586 if (dest_net) 587 put_net(dest_net); 588 589 if (err) 590 return err; 591 /* For backward compatibility generate reply only if attributes used by user */ 592 if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) 593 return 0; 594 595 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed, 596 DEVLINK_CMD_RELOAD, info); 597 } 598 599 bool devlink_reload_actions_valid(const struct devlink_ops *ops) 600 { 601 const struct devlink_reload_combination *comb; 602 int i; 603 604 if (!devlink_reload_supported(ops)) { 605 if (WARN_ON(ops->reload_actions)) 606 return false; 607 return true; 608 } 609 610 if (WARN_ON(!ops->reload_actions || 611 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 612 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX))) 613 return false; 614 615 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) || 616 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX))) 617 return false; 618 619 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) { 620 comb = &devlink_reload_invalid_combinations[i]; 621 if (ops->reload_actions == BIT(comb->action) && 622 ops->reload_limits == BIT(comb->limit)) 623 return false; 624 } 625 return true; 626 } 627 628 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink, 629 enum devlink_command cmd, u32 portid, 630 u32 seq, int flags) 631 { 632 const struct devlink_ops *ops = devlink->ops; 633 enum devlink_eswitch_encap_mode encap_mode; 634 u8 inline_mode; 635 void *hdr; 636 int err = 0; 637 u16 mode; 638 639 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 640 if (!hdr) 641 return -EMSGSIZE; 642 643 err = devlink_nl_put_handle(msg, devlink); 644 if (err) 645 goto nla_put_failure; 646 647 if (ops->eswitch_mode_get) { 648 err = ops->eswitch_mode_get(devlink, &mode); 649 if (err) 650 goto nla_put_failure; 651 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode); 652 if (err) 653 goto nla_put_failure; 654 } 655 656 if (ops->eswitch_inline_mode_get) { 657 err = ops->eswitch_inline_mode_get(devlink, &inline_mode); 658 if (err) 659 goto nla_put_failure; 660 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, 661 inline_mode); 662 if (err) 663 goto nla_put_failure; 664 } 665 666 if (ops->eswitch_encap_mode_get) { 667 err = ops->eswitch_encap_mode_get(devlink, &encap_mode); 668 if (err) 669 goto nla_put_failure; 670 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode); 671 if (err) 672 goto nla_put_failure; 673 } 674 675 genlmsg_end(msg, hdr); 676 return 0; 677 678 nla_put_failure: 679 genlmsg_cancel(msg, hdr); 680 return err; 681 } 682 683 int devlink_nl_eswitch_get_doit(struct sk_buff *skb, struct genl_info *info) 684 { 685 struct devlink *devlink = info->user_ptr[0]; 686 struct sk_buff *msg; 687 int err; 688 689 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 690 if (!msg) 691 return -ENOMEM; 692 693 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET, 694 info->snd_portid, info->snd_seq, 0); 695 696 if (err) { 697 nlmsg_free(msg); 698 return err; 699 } 700 701 return genlmsg_reply(msg, info); 702 } 703 704 int devlink_nl_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info) 705 { 706 struct devlink *devlink = info->user_ptr[0]; 707 const struct devlink_ops *ops = devlink->ops; 708 enum devlink_eswitch_encap_mode encap_mode; 709 u8 inline_mode; 710 int err = 0; 711 u16 mode; 712 713 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) { 714 if (!ops->eswitch_mode_set) 715 return -EOPNOTSUPP; 716 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]); 717 err = devlink_rate_nodes_check(devlink, mode, info->extack); 718 if (err) 719 return err; 720 err = ops->eswitch_mode_set(devlink, mode, info->extack); 721 if (err) 722 return err; 723 } 724 725 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) { 726 if (!ops->eswitch_inline_mode_set) 727 return -EOPNOTSUPP; 728 inline_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]); 729 err = ops->eswitch_inline_mode_set(devlink, inline_mode, 730 info->extack); 731 if (err) 732 return err; 733 } 734 735 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { 736 if (!ops->eswitch_encap_mode_set) 737 return -EOPNOTSUPP; 738 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); 739 err = ops->eswitch_encap_mode_set(devlink, encap_mode, 740 info->extack); 741 if (err) 742 return err; 743 } 744 745 return 0; 746 } 747 748 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn) 749 { 750 if (!req->msg) 751 return 0; 752 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn); 753 } 754 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); 755 756 int devlink_info_board_serial_number_put(struct devlink_info_req *req, 757 const char *bsn) 758 { 759 if (!req->msg) 760 return 0; 761 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, 762 bsn); 763 } 764 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); 765 766 static int devlink_info_version_put(struct devlink_info_req *req, int attr, 767 const char *version_name, 768 const char *version_value, 769 enum devlink_info_version_type version_type) 770 { 771 struct nlattr *nest; 772 int err; 773 774 if (req->version_cb) 775 req->version_cb(version_name, version_type, 776 req->version_cb_priv); 777 778 if (!req->msg) 779 return 0; 780 781 nest = nla_nest_start_noflag(req->msg, attr); 782 if (!nest) 783 return -EMSGSIZE; 784 785 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME, 786 version_name); 787 if (err) 788 goto nla_put_failure; 789 790 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE, 791 version_value); 792 if (err) 793 goto nla_put_failure; 794 795 nla_nest_end(req->msg, nest); 796 797 return 0; 798 799 nla_put_failure: 800 nla_nest_cancel(req->msg, nest); 801 return err; 802 } 803 804 int devlink_info_version_fixed_put(struct devlink_info_req *req, 805 const char *version_name, 806 const char *version_value) 807 { 808 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED, 809 version_name, version_value, 810 DEVLINK_INFO_VERSION_TYPE_NONE); 811 } 812 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); 813 814 int devlink_info_version_stored_put(struct devlink_info_req *req, 815 const char *version_name, 816 const char *version_value) 817 { 818 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 819 version_name, version_value, 820 DEVLINK_INFO_VERSION_TYPE_NONE); 821 } 822 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); 823 824 int devlink_info_version_stored_put_ext(struct devlink_info_req *req, 825 const char *version_name, 826 const char *version_value, 827 enum devlink_info_version_type version_type) 828 { 829 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 830 version_name, version_value, 831 version_type); 832 } 833 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext); 834 835 int devlink_info_version_running_put(struct devlink_info_req *req, 836 const char *version_name, 837 const char *version_value) 838 { 839 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 840 version_name, version_value, 841 DEVLINK_INFO_VERSION_TYPE_NONE); 842 } 843 EXPORT_SYMBOL_GPL(devlink_info_version_running_put); 844 845 int devlink_info_version_running_put_ext(struct devlink_info_req *req, 846 const char *version_name, 847 const char *version_value, 848 enum devlink_info_version_type version_type) 849 { 850 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 851 version_name, version_value, 852 version_type); 853 } 854 EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext); 855 856 static int devlink_nl_driver_info_get(struct device_driver *drv, 857 struct devlink_info_req *req) 858 { 859 if (!drv) 860 return 0; 861 862 if (drv->name[0]) 863 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, 864 drv->name); 865 866 return 0; 867 } 868 869 static int 870 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink, 871 enum devlink_command cmd, u32 portid, 872 u32 seq, int flags, struct netlink_ext_ack *extack) 873 { 874 struct device *dev = devlink_to_dev(devlink); 875 struct devlink_info_req req = {}; 876 void *hdr; 877 int err; 878 879 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 880 if (!hdr) 881 return -EMSGSIZE; 882 883 err = -EMSGSIZE; 884 if (devlink_nl_put_handle(msg, devlink)) 885 goto err_cancel_msg; 886 887 req.msg = msg; 888 if (devlink->ops->info_get) { 889 err = devlink->ops->info_get(devlink, &req, extack); 890 if (err) 891 goto err_cancel_msg; 892 } 893 894 err = devlink_nl_driver_info_get(dev->driver, &req); 895 if (err) 896 goto err_cancel_msg; 897 898 genlmsg_end(msg, hdr); 899 return 0; 900 901 err_cancel_msg: 902 genlmsg_cancel(msg, hdr); 903 return err; 904 } 905 906 int devlink_nl_info_get_doit(struct sk_buff *skb, struct genl_info *info) 907 { 908 struct devlink *devlink = info->user_ptr[0]; 909 struct sk_buff *msg; 910 int err; 911 912 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 913 if (!msg) 914 return -ENOMEM; 915 916 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 917 info->snd_portid, info->snd_seq, 0, 918 info->extack); 919 if (err) { 920 nlmsg_free(msg); 921 return err; 922 } 923 924 return genlmsg_reply(msg, info); 925 } 926 927 static int 928 devlink_nl_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 929 struct netlink_callback *cb, int flags) 930 { 931 int err; 932 933 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 934 NETLINK_CB(cb->skb).portid, 935 cb->nlh->nlmsg_seq, flags, 936 cb->extack); 937 if (err == -EOPNOTSUPP) 938 err = 0; 939 return err; 940 } 941 942 int devlink_nl_info_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) 943 { 944 return devlink_nl_dumpit(msg, cb, devlink_nl_info_get_dump_one); 945 } 946 947 static int devlink_nl_flash_update_fill(struct sk_buff *msg, 948 struct devlink *devlink, 949 enum devlink_command cmd, 950 struct devlink_flash_notify *params) 951 { 952 void *hdr; 953 954 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd); 955 if (!hdr) 956 return -EMSGSIZE; 957 958 if (devlink_nl_put_handle(msg, devlink)) 959 goto nla_put_failure; 960 961 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS) 962 goto out; 963 964 if (params->status_msg && 965 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG, 966 params->status_msg)) 967 goto nla_put_failure; 968 if (params->component && 969 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, 970 params->component)) 971 goto nla_put_failure; 972 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, 973 params->done, DEVLINK_ATTR_PAD)) 974 goto nla_put_failure; 975 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, 976 params->total, DEVLINK_ATTR_PAD)) 977 goto nla_put_failure; 978 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, 979 params->timeout, DEVLINK_ATTR_PAD)) 980 goto nla_put_failure; 981 982 out: 983 genlmsg_end(msg, hdr); 984 return 0; 985 986 nla_put_failure: 987 genlmsg_cancel(msg, hdr); 988 return -EMSGSIZE; 989 } 990 991 static void __devlink_flash_update_notify(struct devlink *devlink, 992 enum devlink_command cmd, 993 struct devlink_flash_notify *params) 994 { 995 struct sk_buff *msg; 996 int err; 997 998 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE && 999 cmd != DEVLINK_CMD_FLASH_UPDATE_END && 1000 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS); 1001 1002 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) 1003 return; 1004 1005 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1006 if (!msg) 1007 return; 1008 1009 err = devlink_nl_flash_update_fill(msg, devlink, cmd, params); 1010 if (err) 1011 goto out_free_msg; 1012 1013 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 1014 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 1015 return; 1016 1017 out_free_msg: 1018 nlmsg_free(msg); 1019 } 1020 1021 static void devlink_flash_update_begin_notify(struct devlink *devlink) 1022 { 1023 struct devlink_flash_notify params = {}; 1024 1025 __devlink_flash_update_notify(devlink, 1026 DEVLINK_CMD_FLASH_UPDATE, 1027 ¶ms); 1028 } 1029 1030 static void devlink_flash_update_end_notify(struct devlink *devlink) 1031 { 1032 struct devlink_flash_notify params = {}; 1033 1034 __devlink_flash_update_notify(devlink, 1035 DEVLINK_CMD_FLASH_UPDATE_END, 1036 ¶ms); 1037 } 1038 1039 void devlink_flash_update_status_notify(struct devlink *devlink, 1040 const char *status_msg, 1041 const char *component, 1042 unsigned long done, 1043 unsigned long total) 1044 { 1045 struct devlink_flash_notify params = { 1046 .status_msg = status_msg, 1047 .component = component, 1048 .done = done, 1049 .total = total, 1050 }; 1051 1052 __devlink_flash_update_notify(devlink, 1053 DEVLINK_CMD_FLASH_UPDATE_STATUS, 1054 ¶ms); 1055 } 1056 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify); 1057 1058 void devlink_flash_update_timeout_notify(struct devlink *devlink, 1059 const char *status_msg, 1060 const char *component, 1061 unsigned long timeout) 1062 { 1063 struct devlink_flash_notify params = { 1064 .status_msg = status_msg, 1065 .component = component, 1066 .timeout = timeout, 1067 }; 1068 1069 __devlink_flash_update_notify(devlink, 1070 DEVLINK_CMD_FLASH_UPDATE_STATUS, 1071 ¶ms); 1072 } 1073 EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); 1074 1075 struct devlink_flash_component_lookup_ctx { 1076 const char *lookup_name; 1077 bool lookup_name_found; 1078 }; 1079 1080 static void 1081 devlink_flash_component_lookup_cb(const char *version_name, 1082 enum devlink_info_version_type version_type, 1083 void *version_cb_priv) 1084 { 1085 struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv; 1086 1087 if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT || 1088 lookup_ctx->lookup_name_found) 1089 return; 1090 1091 lookup_ctx->lookup_name_found = 1092 !strcmp(lookup_ctx->lookup_name, version_name); 1093 } 1094 1095 static int devlink_flash_component_get(struct devlink *devlink, 1096 struct nlattr *nla_component, 1097 const char **p_component, 1098 struct netlink_ext_ack *extack) 1099 { 1100 struct devlink_flash_component_lookup_ctx lookup_ctx = {}; 1101 struct devlink_info_req req = {}; 1102 const char *component; 1103 int ret; 1104 1105 if (!nla_component) 1106 return 0; 1107 1108 component = nla_data(nla_component); 1109 1110 if (!devlink->ops->info_get) { 1111 NL_SET_ERR_MSG_ATTR(extack, nla_component, 1112 "component update is not supported by this device"); 1113 return -EOPNOTSUPP; 1114 } 1115 1116 lookup_ctx.lookup_name = component; 1117 req.version_cb = devlink_flash_component_lookup_cb; 1118 req.version_cb_priv = &lookup_ctx; 1119 1120 ret = devlink->ops->info_get(devlink, &req, NULL); 1121 if (ret) 1122 return ret; 1123 1124 if (!lookup_ctx.lookup_name_found) { 1125 NL_SET_ERR_MSG_ATTR(extack, nla_component, 1126 "selected component is not supported by this device"); 1127 return -EINVAL; 1128 } 1129 *p_component = component; 1130 return 0; 1131 } 1132 1133 int devlink_nl_flash_update_doit(struct sk_buff *skb, struct genl_info *info) 1134 { 1135 struct nlattr *nla_overwrite_mask, *nla_file_name; 1136 struct devlink_flash_update_params params = {}; 1137 struct devlink *devlink = info->user_ptr[0]; 1138 const char *file_name; 1139 u32 supported_params; 1140 int ret; 1141 1142 if (!devlink->ops->flash_update) 1143 return -EOPNOTSUPP; 1144 1145 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME)) 1146 return -EINVAL; 1147 1148 ret = devlink_flash_component_get(devlink, 1149 info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT], 1150 ¶ms.component, info->extack); 1151 if (ret) 1152 return ret; 1153 1154 supported_params = devlink->ops->supported_flash_update_params; 1155 1156 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK]; 1157 if (nla_overwrite_mask) { 1158 struct nla_bitfield32 sections; 1159 1160 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) { 1161 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask, 1162 "overwrite settings are not supported by this device"); 1163 return -EOPNOTSUPP; 1164 } 1165 sections = nla_get_bitfield32(nla_overwrite_mask); 1166 params.overwrite_mask = sections.value & sections.selector; 1167 } 1168 1169 nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]; 1170 file_name = nla_data(nla_file_name); 1171 ret = request_firmware(¶ms.fw, file_name, devlink->dev); 1172 if (ret) { 1173 NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, 1174 "failed to locate the requested firmware file"); 1175 return ret; 1176 } 1177 1178 devlink_flash_update_begin_notify(devlink); 1179 ret = devlink->ops->flash_update(devlink, ¶ms, info->extack); 1180 devlink_flash_update_end_notify(devlink); 1181 1182 release_firmware(params.fw); 1183 1184 return ret; 1185 } 1186 1187 static void __devlink_compat_running_version(struct devlink *devlink, 1188 char *buf, size_t len) 1189 { 1190 struct devlink_info_req req = {}; 1191 const struct nlattr *nlattr; 1192 struct sk_buff *msg; 1193 int rem, err; 1194 1195 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1196 if (!msg) 1197 return; 1198 1199 req.msg = msg; 1200 err = devlink->ops->info_get(devlink, &req, NULL); 1201 if (err) 1202 goto free_msg; 1203 1204 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) { 1205 const struct nlattr *kv; 1206 int rem_kv; 1207 1208 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING) 1209 continue; 1210 1211 nla_for_each_nested(kv, nlattr, rem_kv) { 1212 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE) 1213 continue; 1214 1215 strlcat(buf, nla_data(kv), len); 1216 strlcat(buf, " ", len); 1217 } 1218 } 1219 free_msg: 1220 nlmsg_free(msg); 1221 } 1222 1223 void devlink_compat_running_version(struct devlink *devlink, 1224 char *buf, size_t len) 1225 { 1226 if (!devlink->ops->info_get) 1227 return; 1228 1229 devl_lock(devlink); 1230 if (devl_is_registered(devlink)) 1231 __devlink_compat_running_version(devlink, buf, len); 1232 devl_unlock(devlink); 1233 } 1234 1235 int devlink_compat_flash_update(struct devlink *devlink, const char *file_name) 1236 { 1237 struct devlink_flash_update_params params = {}; 1238 int ret; 1239 1240 devl_lock(devlink); 1241 if (!devl_is_registered(devlink)) { 1242 ret = -ENODEV; 1243 goto out_unlock; 1244 } 1245 1246 if (!devlink->ops->flash_update) { 1247 ret = -EOPNOTSUPP; 1248 goto out_unlock; 1249 } 1250 1251 ret = request_firmware(¶ms.fw, file_name, devlink->dev); 1252 if (ret) 1253 goto out_unlock; 1254 1255 devlink_flash_update_begin_notify(devlink); 1256 ret = devlink->ops->flash_update(devlink, ¶ms, NULL); 1257 devlink_flash_update_end_notify(devlink); 1258 1259 release_firmware(params.fw); 1260 out_unlock: 1261 devl_unlock(devlink); 1262 1263 return ret; 1264 } 1265 1266 static int 1267 devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink, 1268 u32 portid, u32 seq, int flags, 1269 struct netlink_ext_ack *extack) 1270 { 1271 struct nlattr *selftests; 1272 void *hdr; 1273 int err; 1274 int i; 1275 1276 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, 1277 DEVLINK_CMD_SELFTESTS_GET); 1278 if (!hdr) 1279 return -EMSGSIZE; 1280 1281 err = -EMSGSIZE; 1282 if (devlink_nl_put_handle(msg, devlink)) 1283 goto err_cancel_msg; 1284 1285 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); 1286 if (!selftests) 1287 goto err_cancel_msg; 1288 1289 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; 1290 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { 1291 if (devlink->ops->selftest_check(devlink, i, extack)) { 1292 err = nla_put_flag(msg, i); 1293 if (err) 1294 goto err_cancel_msg; 1295 } 1296 } 1297 1298 nla_nest_end(msg, selftests); 1299 genlmsg_end(msg, hdr); 1300 return 0; 1301 1302 err_cancel_msg: 1303 genlmsg_cancel(msg, hdr); 1304 return err; 1305 } 1306 1307 int devlink_nl_selftests_get_doit(struct sk_buff *skb, struct genl_info *info) 1308 { 1309 struct devlink *devlink = info->user_ptr[0]; 1310 struct sk_buff *msg; 1311 int err; 1312 1313 if (!devlink->ops->selftest_check) 1314 return -EOPNOTSUPP; 1315 1316 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1317 if (!msg) 1318 return -ENOMEM; 1319 1320 err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid, 1321 info->snd_seq, 0, info->extack); 1322 if (err) { 1323 nlmsg_free(msg); 1324 return err; 1325 } 1326 1327 return genlmsg_reply(msg, info); 1328 } 1329 1330 static int devlink_nl_selftests_get_dump_one(struct sk_buff *msg, 1331 struct devlink *devlink, 1332 struct netlink_callback *cb, 1333 int flags) 1334 { 1335 if (!devlink->ops->selftest_check) 1336 return 0; 1337 1338 return devlink_nl_selftests_fill(msg, devlink, 1339 NETLINK_CB(cb->skb).portid, 1340 cb->nlh->nlmsg_seq, flags, 1341 cb->extack); 1342 } 1343 1344 int devlink_nl_selftests_get_dumpit(struct sk_buff *skb, 1345 struct netlink_callback *cb) 1346 { 1347 return devlink_nl_dumpit(skb, cb, devlink_nl_selftests_get_dump_one); 1348 } 1349 1350 static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id, 1351 enum devlink_selftest_status test_status) 1352 { 1353 struct nlattr *result_attr; 1354 1355 result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT); 1356 if (!result_attr) 1357 return -EMSGSIZE; 1358 1359 if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) || 1360 nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS, 1361 test_status)) 1362 goto nla_put_failure; 1363 1364 nla_nest_end(skb, result_attr); 1365 return 0; 1366 1367 nla_put_failure: 1368 nla_nest_cancel(skb, result_attr); 1369 return -EMSGSIZE; 1370 } 1371 1372 static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = { 1373 [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG }, 1374 }; 1375 1376 int devlink_nl_selftests_run_doit(struct sk_buff *skb, struct genl_info *info) 1377 { 1378 struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1]; 1379 struct devlink *devlink = info->user_ptr[0]; 1380 struct nlattr *attrs, *selftests; 1381 struct sk_buff *msg; 1382 void *hdr; 1383 int err; 1384 int i; 1385 1386 if (!devlink->ops->selftest_run || !devlink->ops->selftest_check) 1387 return -EOPNOTSUPP; 1388 1389 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS)) 1390 return -EINVAL; 1391 1392 attrs = info->attrs[DEVLINK_ATTR_SELFTESTS]; 1393 1394 err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs, 1395 devlink_selftest_nl_policy, info->extack); 1396 if (err < 0) 1397 return err; 1398 1399 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1400 if (!msg) 1401 return -ENOMEM; 1402 1403 err = -EMSGSIZE; 1404 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, 1405 &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN); 1406 if (!hdr) 1407 goto free_msg; 1408 1409 if (devlink_nl_put_handle(msg, devlink)) 1410 goto genlmsg_cancel; 1411 1412 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); 1413 if (!selftests) 1414 goto genlmsg_cancel; 1415 1416 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; 1417 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { 1418 enum devlink_selftest_status test_status; 1419 1420 if (nla_get_flag(tb[i])) { 1421 if (!devlink->ops->selftest_check(devlink, i, 1422 info->extack)) { 1423 if (devlink_selftest_result_put(msg, i, 1424 DEVLINK_SELFTEST_STATUS_SKIP)) 1425 goto selftests_nest_cancel; 1426 continue; 1427 } 1428 1429 test_status = devlink->ops->selftest_run(devlink, i, 1430 info->extack); 1431 if (devlink_selftest_result_put(msg, i, test_status)) 1432 goto selftests_nest_cancel; 1433 } 1434 } 1435 1436 nla_nest_end(msg, selftests); 1437 genlmsg_end(msg, hdr); 1438 return genlmsg_reply(msg, info); 1439 1440 selftests_nest_cancel: 1441 nla_nest_cancel(msg, selftests); 1442 genlmsg_cancel: 1443 genlmsg_cancel(msg, hdr); 1444 free_msg: 1445 nlmsg_free(msg); 1446 return err; 1447 } 1448