| @@ -335,32 +335,20 @@ unlock: · 334 unmodified lines |
| 335 | 335 | rcu_read_unlock(); |
| 336 | 336 | } |
| 337 | 337 | |
| 338 | | −static int klp_disable_func(struct klp_func *func) |
| 338 | +static void klp_disable_func(struct klp_func *func) |
| 339 | 339 | { |
| 340 | 340 | struct klp_ops *ops; |
| 341 | | − int ret; |
| 342 | | − |
| 343 | | − if (WARN_ON(func->state != KLP_ENABLED)) |
| 344 | | − return -EINVAL; |
| 345 | 341 | |
| 346 | | − if (WARN_ON(!func->old_addr)) |
| 347 | | − return -EINVAL; |
| 342 | + WARN_ON(func->state != KLP_ENABLED); |
| 343 | + WARN_ON(!func->old_addr); |
| 348 | 344 | |
| 349 | 345 | ops = klp_find_ops(func->old_addr); |
| 350 | 346 | if (WARN_ON(!ops)) |
| 351 | | − return -EINVAL; |
| 347 | + return; |
| 352 | 348 | |
| 353 | 349 | if (list_is_singular(&ops->func_stack)) { |
| 354 | | − ret = unregister_ftrace_function(&ops->fops); |
| 355 | | − if (ret) { |
| 356 | | − pr_err("failed to unregister ftrace handler for function '%s' (%d)\n", |
| 357 | | − func->old_name, ret); |
| 358 | | − return ret; |
| 359 | | − } |
| 360 | | − |
| 361 | | − ret = ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0); |
| 362 | | − if (ret) |
| 363 | | − pr_warn("function unregister succeeded but failed to clear the filter\n"); |
| 350 | + WARN_ON(unregister_ftrace_function(&ops->fops)); |
| 351 | + WARN_ON(ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0)); |
| 364 | 352 | |
| 365 | 353 | list_del_rcu(&func->stack_node); |
| 366 | 354 | list_del(&ops->node); |
| @@ -370,8 +358,6 @@ static int klp_disable_func(struct klp_func *func) · 3 unmodified lines |
| 370 | 358 | } |
| 371 | 359 | |
| 372 | 360 | func->state = KLP_DISABLED; |
| 373 | | − |
| 374 | | − return 0; |
| 375 | 361 | } |
| 376 | 362 | |
| 377 | 363 | static int klp_enable_func(struct klp_func *func) |
| @@ -432,23 +418,15 @@ err: · 54 unmodified lines |
| 432 | 418 | return ret; |
| 433 | 419 | } |
| 434 | 420 | |
| 435 | | −static int klp_disable_object(struct klp_object *obj) |
| 421 | +static void klp_disable_object(struct klp_object *obj) |
| 436 | 422 | { |
| 437 | 423 | struct klp_func *func; |
| 438 | | − int ret; |
| 439 | 424 | |
| 440 | | − for (func = obj->funcs; func->old_name; func++) { |
| 441 | | − if (func->state != KLP_ENABLED) |
| 442 | | − continue; |
| 443 | | − |
| 444 | | − ret = klp_disable_func(func); |
| 445 | | − if (ret) |
| 446 | | − return ret; |
| 447 | | − } |
| 425 | + for (func = obj->funcs; func->old_name; func++) |
| 426 | + if (func->state == KLP_ENABLED) |
| 427 | + klp_disable_func(func); |
| 448 | 428 | |
| 449 | 429 | obj->state = KLP_DISABLED; |
| 450 | | − |
| 451 | | − return 0; |
| 452 | 430 | } |
| 453 | 431 | |
| 454 | 432 | static int klp_enable_object(struct klp_object *obj) |
| @@ -464,22 +442,19 @@ static int klp_enable_object(struct klp_object *obj) · 9 unmodified lines |
| 464 | 442 | |
| 465 | 443 | for (func = obj->funcs; func->old_name; func++) { |
| 466 | 444 | ret = klp_enable_func(func); |
| 467 | | − if (ret) |
| 468 | | − goto unregister; |
| 445 | + if (ret) { |
| 446 | + klp_disable_object(obj); |
| 447 | + return ret; |
| 448 | + } |
| 469 | 449 | } |
| 470 | 450 | obj->state = KLP_ENABLED; |
| 471 | 451 | |
| 472 | 452 | return 0; |
| 473 | | − |
| 474 | | −unregister: |
| 475 | | − WARN_ON(klp_disable_object(obj)); |
| 476 | | − return ret; |
| 477 | 453 | } |
| 478 | 454 | |
| 479 | 455 | static int __klp_disable_patch(struct klp_patch *patch) |
| 480 | 456 | { |
| 481 | 457 | struct klp_object *obj; |
| 482 | | − int ret; |
| 483 | 458 | |
| 484 | 459 | /* enforce stacking: only the last enabled patch can be disabled */ |
| 485 | 460 | if (!list_is_last(&patch->list, &klp_patches) && |
| @@ -489,12 +464,8 @@ static int __klp_disable_patch(struct klp_patch *patch) · 3 unmodified lines |
| 489 | 464 | pr_notice("disabling patch '%s'\n", patch->mod->name); |
| 490 | 465 | |
| 491 | 466 | for (obj = patch->objs; obj->funcs; obj++) { |
| 492 | | − if (obj->state != KLP_ENABLED) |
| 493 | | − continue; |
| 494 | | − |
| 495 | | − ret = klp_disable_object(obj); |
| 496 | | − if (ret) |
| 497 | | − return ret; |
| 467 | + if (obj->state == KLP_ENABLED) |
| 468 | + klp_disable_object(obj); |
| 498 | 469 | } |
| 499 | 470 | |
| 500 | 471 | patch->state = KLP_DISABLED; |
| @@ -553,8 +524,6 @@ static int __klp_enable_patch(struct klp_patch *patch) · 52 unmodified lines |
| 553 | 524 | pr_notice("enabling patch '%s'\n", patch->mod->name); |
| 554 | 525 | |
| 555 | 526 | for (obj = patch->objs; obj->funcs; obj++) { |
| 556 | | − klp_find_object_module(obj); |
| 557 | | − |
| 558 | 527 | if (!klp_is_object_loaded(obj)) |
| 559 | 528 | continue; |
| 560 | 529 | |
| @@ -945,7 +914,6 @@ static void klp_module_notify_going(struct klp_patch *patch, · 384 unmodified lines |
| 945 | 914 | { |
| 946 | 915 | struct module *pmod = patch->mod; |
| 947 | 916 | struct module *mod = obj->mod; |
| 948 | | − int ret; |
| 949 | 917 | |
| 950 | 918 | if (patch->state == KLP_DISABLED) |
| 951 | 919 | goto disabled; |
| @@ -953,10 +921,7 @@ static void klp_module_notify_going(struct klp_patch *patch, · 1 unmodified line |
| 953 | 921 | pr_notice("reverting patch '%s' on unloading module '%s'\n", |
| 954 | 922 | pmod->name, mod->name); |
| 955 | 923 | |
| 956 | | − ret = klp_disable_object(obj); |
| 957 | | − if (ret) |
| 958 | | − pr_warn("failed to revert patch '%s' on module '%s' (%d)\n", |
| 959 | | − pmod->name, mod->name, ret); |
| 924 | + klp_disable_object(obj); |
| 960 | 925 | |
| 961 | 926 | disabled: |
| 962 | 927 | klp_free_object_loaded(obj); |