summaryrefslogtreecommitdiffstats
path: root/lib/debugobjects.c
diff options
context:
space:
mode:
authorDu, Changbin <changbin.du@intel.com>2016-05-19 20:09:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-19 22:12:14 -0400
commitb9fdac7f660609abb157500e468d2165b3c9cf08 (patch)
tree37d3b704f52b46dfb6d9ebb24611870dbb2b93be /lib/debugobjects.c
parent8bad1cd0e1edd124c0f05f925762ef84e6047586 (diff)
debugobjects: insulate non-fixup logic related to static obj from fixup callbacks
When activating a static object we need make sure that the object is tracked in the object tracker. If it is a non-static object then the activation is illegal. In previous implementation, each subsystem need take care of this in their fixup callbacks. Actually we can put it into debugobjects core. Thus we can save duplicated code, and have *pure* fixup callbacks. To achieve this, a new callback "is_static_object" is introduced to let the type specific code decide whether a object is static or not. If yes, we take it into object tracker, otherwise give warning and invoke fixup callback. This change has paassed debugobjects selftest, and I also do some test with all debugobjects supports enabled. At last, I have a concern about the fixups that can it change the object which is in incorrect state on fixup? Because the 'addr' may not point to any valid object if a non-static object is not tracked. Then Change such object can overwrite someone's memory and cause unexpected behaviour. For example, the timer_fixup_activate bind timer to function stub_timer. Link: http://lkml.kernel.org/r/1462576157-14539-1-git-send-email-changbin.du@intel.com [changbin.du@intel.com: improve code comments where invoke the new is_static_object callback] Link: http://lkml.kernel.org/r/1462777431-8171-1-git-send-email-changbin.du@intel.com Signed-off-by: Du, Changbin <changbin.du@intel.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Josh Triplett <josh@kernel.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tejun Heo <tj@kernel.org> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/debugobjects.c')
-rw-r--r--lib/debugobjects.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 2f07c8c697b8..a8e12601eb37 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -431,14 +431,21 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr)
431 431
432 raw_spin_unlock_irqrestore(&db->lock, flags); 432 raw_spin_unlock_irqrestore(&db->lock, flags);
433 /* 433 /*
434 * This happens when a static object is activated. We 434 * We are here when a static object is activated. We
435 * let the type specific code decide whether this is 435 * let the type specific code confirm whether this is
436 * true or not. 436 * true or not. if true, we just make sure that the
437 * static object is tracked in the object tracker. If
438 * not, this must be a bug, so we try to fix it up.
437 */ 439 */
438 if (debug_object_fixup(descr->fixup_activate, addr, 440 if (descr->is_static_object && descr->is_static_object(addr)) {
439 ODEBUG_STATE_NOTAVAILABLE)) { 441 /* track this static object */
442 debug_object_init(addr, descr);
443 debug_object_activate(addr, descr);
444 } else {
440 debug_print_object(&o, "activate"); 445 debug_print_object(&o, "activate");
441 return -EINVAL; 446 ret = debug_object_fixup(descr->fixup_activate, addr,
447 ODEBUG_STATE_NOTAVAILABLE);
448 return ret ? 0 : -EINVAL;
442 } 449 }
443 return 0; 450 return 0;
444} 451}
@@ -602,12 +609,18 @@ void debug_object_assert_init(void *addr, struct debug_obj_descr *descr)
602 609
603 raw_spin_unlock_irqrestore(&db->lock, flags); 610 raw_spin_unlock_irqrestore(&db->lock, flags);
604 /* 611 /*
605 * Maybe the object is static. Let the type specific 612 * Maybe the object is static, and we let the type specific
606 * code decide what to do. 613 * code confirm. Track this static object if true, else invoke
614 * fixup.
607 */ 615 */
608 if (debug_object_fixup(descr->fixup_assert_init, addr, 616 if (descr->is_static_object && descr->is_static_object(addr)) {
609 ODEBUG_STATE_NOTAVAILABLE)) 617 /* Track this static object */
618 debug_object_init(addr, descr);
619 } else {
610 debug_print_object(&o, "assert_init"); 620 debug_print_object(&o, "assert_init");
621 debug_object_fixup(descr->fixup_assert_init, addr,
622 ODEBUG_STATE_NOTAVAILABLE);
623 }
611 return; 624 return;
612 } 625 }
613 626
@@ -792,6 +805,13 @@ struct self_test {
792 805
793static __initdata struct debug_obj_descr descr_type_test; 806static __initdata struct debug_obj_descr descr_type_test;
794 807
808static bool __init is_static_object(void *addr)
809{
810 struct self_test *obj = addr;
811
812 return obj->static_init;
813}
814
795/* 815/*
796 * fixup_init is called when: 816 * fixup_init is called when:
797 * - an active object is initialized 817 * - an active object is initialized
@@ -813,7 +833,7 @@ static bool __init fixup_init(void *addr, enum debug_obj_state state)
813/* 833/*
814 * fixup_activate is called when: 834 * fixup_activate is called when:
815 * - an active object is activated 835 * - an active object is activated
816 * - an unknown object is activated (might be a statically initialized object) 836 * - an unknown non-static object is activated
817 */ 837 */
818static bool __init fixup_activate(void *addr, enum debug_obj_state state) 838static bool __init fixup_activate(void *addr, enum debug_obj_state state)
819{ 839{
@@ -821,13 +841,7 @@ static bool __init fixup_activate(void *addr, enum debug_obj_state state)
821 841
822 switch (state) { 842 switch (state) {
823 case ODEBUG_STATE_NOTAVAILABLE: 843 case ODEBUG_STATE_NOTAVAILABLE:
824 if (obj->static_init == 1) {
825 debug_object_init(obj, &descr_type_test);
826 debug_object_activate(obj, &descr_type_test);
827 return false;
828 }
829 return true; 844 return true;
830
831 case ODEBUG_STATE_ACTIVE: 845 case ODEBUG_STATE_ACTIVE:
832 debug_object_deactivate(obj, &descr_type_test); 846 debug_object_deactivate(obj, &descr_type_test);
833 debug_object_activate(obj, &descr_type_test); 847 debug_object_activate(obj, &descr_type_test);
@@ -916,6 +930,7 @@ out:
916 930
917static __initdata struct debug_obj_descr descr_type_test = { 931static __initdata struct debug_obj_descr descr_type_test = {
918 .name = "selftest", 932 .name = "selftest",
933 .is_static_object = is_static_object,
919 .fixup_init = fixup_init, 934 .fixup_init = fixup_init,
920 .fixup_activate = fixup_activate, 935 .fixup_activate = fixup_activate,
921 .fixup_destroy = fixup_destroy, 936 .fixup_destroy = fixup_destroy,