@@ -8323,12 +8323,42 @@ enum {
83238323 BTF_MODULE_F_LIVE = (1 << 0 ),
83248324};
83258325
8326+ #if IS_ENABLED (CONFIG_SYSFS )
8327+ struct bin_attribute * sysfs_btf_add (struct kobject * kobj , const char * name ,
8328+ void * data , size_t data_size )
8329+ {
8330+ struct bin_attribute * attr = kzalloc (sizeof (* attr ), GFP_KERNEL );
8331+ int err ;
8332+
8333+ if (!attr )
8334+ return ERR_PTR (- ENOMEM );
8335+
8336+ sysfs_bin_attr_init (attr );
8337+ attr -> attr .name = name ;
8338+ attr -> attr .mode = 0444 ;
8339+ attr -> size = data_size ;
8340+ attr -> private = data ;
8341+ attr -> read = sysfs_bin_attr_simple_read ;
8342+
8343+ err = sysfs_create_bin_file (kobj , attr );
8344+ if (err ) {
8345+ pr_warn ("failed to register module [%s] BTF in sysfs : %d\n" , name , err );
8346+ kfree (attr );
8347+ return ERR_PTR (err );
8348+ }
8349+ return attr ;
8350+ }
8351+
8352+ #endif
8353+
83268354#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
83278355struct btf_module {
83288356 struct list_head list ;
83298357 struct module * module ;
83308358 struct btf * btf ;
83318359 struct bin_attribute * sysfs_attr ;
8360+ void * btf_extra_data ;
8361+ struct bin_attribute * sysfs_extra_attr ;
83328362 int flags ;
83338363};
83348364
@@ -8342,12 +8372,12 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op,
83428372{
83438373 struct btf_module * btf_mod , * tmp ;
83448374 struct module * mod = module ;
8345- struct btf * btf ;
8375+ struct bin_attribute * attr ;
8376+ struct btf * btf = NULL ;
83468377 int err = 0 ;
83478378
8348- if (mod -> btf_data_size == 0 ||
8349- (op != MODULE_STATE_COMING && op != MODULE_STATE_LIVE &&
8350- op != MODULE_STATE_GOING ))
8379+ if (op != MODULE_STATE_COMING && op != MODULE_STATE_LIVE &&
8380+ op != MODULE_STATE_GOING )
83518381 goto out ;
83528382
83538383 switch (op ) {
@@ -8357,8 +8387,10 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op,
83578387 err = - ENOMEM ;
83588388 goto out ;
83598389 }
8360- btf = btf_parse_module (mod -> name , mod -> btf_data , mod -> btf_data_size ,
8361- mod -> btf_base_data , mod -> btf_base_data_size );
8390+ if (mod -> btf_data_size > 0 ) {
8391+ btf = btf_parse_module (mod -> name , mod -> btf_data , mod -> btf_data_size ,
8392+ mod -> btf_base_data , mod -> btf_base_data_size );
8393+ }
83628394 if (IS_ERR (btf )) {
83638395 kfree (btf_mod );
83648396 if (!IS_ENABLED (CONFIG_MODULE_ALLOW_BTF_MISMATCH )) {
@@ -8370,7 +8402,8 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op,
83708402 }
83718403 goto out ;
83728404 }
8373- err = btf_alloc_id (btf );
8405+ if (btf )
8406+ err = btf_alloc_id (btf );
83748407 if (err ) {
83758408 btf_free (btf );
83768409 kfree (btf_mod );
@@ -8384,32 +8417,45 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op,
83848417 list_add (& btf_mod -> list , & btf_modules );
83858418 mutex_unlock (& btf_module_mutex );
83868419
8387- if (IS_ENABLED (CONFIG_SYSFS )) {
8388- struct bin_attribute * attr ;
8389-
8390- attr = kzalloc (sizeof (* attr ), GFP_KERNEL );
8391- if (!attr )
8392- goto out ;
8393-
8394- sysfs_bin_attr_init (attr );
8395- attr -> attr .name = btf -> name ;
8396- attr -> attr .mode = 0444 ;
8397- attr -> size = btf -> data_size ;
8398- attr -> private = btf -> data ;
8399- attr -> read = sysfs_bin_attr_simple_read ;
8400-
8401- err = sysfs_create_bin_file (btf_kobj , attr );
8402- if (err ) {
8403- pr_warn ("failed to register module [%s] BTF in sysfs: %d\n" ,
8404- mod -> name , err );
8405- kfree (attr );
8406- err = 0 ;
8420+ if (IS_ENABLED (CONFIG_SYSFS ) && btf ) {
8421+ attr = sysfs_btf_add (btf_kobj , btf -> name , btf -> data , btf -> data_size );
8422+ if (IS_ERR (attr )) {
8423+ err = PTR_ERR (attr );
84078424 goto out ;
84088425 }
8409-
84108426 btf_mod -> sysfs_attr = attr ;
84118427 }
8428+ #if IS_ENABLED (CONFIG_DEBUG_INFO_BTF_EXTRA )
8429+ if (mod -> btf_extra_data_size > 0 ) {
8430+ const char * name = mod -> name ;
8431+ void * data ;
84128432
8433+ /* vmlinux .BTF.extra is SHF_ALLOC; other modules
8434+ * are not, so for them we need to kvmemdup() the data.
8435+ */
8436+ if (strcmp (mod -> name , "btf_extra" ) == 0 ) {
8437+ name = "vmlinux" ;
8438+ data = mod -> btf_extra_data ;
8439+ } else {
8440+ data = kvmemdup (mod -> btf_extra_data , mod -> btf_extra_data_size ,
8441+ GFP_KERNEL | __GFP_NOWARN );
8442+ if (!data ) {
8443+ err = - ENOMEM ;
8444+ goto out ;
8445+ }
8446+ btf_mod -> btf_extra_data = data ;
8447+ }
8448+ attr = sysfs_btf_add (btf_extra_kobj , name , data ,
8449+ mod -> btf_extra_data_size );
8450+ if (IS_ERR (attr )) {
8451+ err = PTR_ERR (attr );
8452+ kfree (btf_mod -> sysfs_attr );
8453+ kvfree (btf_mod -> btf_extra_data );
8454+ goto out ;
8455+ }
8456+ btf_mod -> sysfs_extra_attr = attr ;
8457+ }
8458+ #endif
84138459 break ;
84148460 case MODULE_STATE_LIVE :
84158461 mutex_lock (& btf_module_mutex );
@@ -8431,9 +8477,15 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op,
84318477 list_del (& btf_mod -> list );
84328478 if (btf_mod -> sysfs_attr )
84338479 sysfs_remove_bin_file (btf_kobj , btf_mod -> sysfs_attr );
8434- purge_cand_cache (btf_mod -> btf );
8435- btf_put (btf_mod -> btf );
8436- kfree (btf_mod -> sysfs_attr );
8480+ if (btf_mod -> btf_extra_data )
8481+ kvfree (btf_mod -> btf_extra_data );
8482+ if (btf_mod -> sysfs_extra_attr )
8483+ sysfs_remove_bin_file (btf_extra_kobj , btf_mod -> sysfs_extra_attr );
8484+ if (btf_mod -> btf ) {
8485+ purge_cand_cache (btf_mod -> btf );
8486+ btf_put (btf_mod -> btf );
8487+ kfree (btf_mod -> sysfs_attr );
8488+ }
84378489 kfree (btf_mod );
84388490 break ;
84398491 }
0 commit comments