@@ -3163,71 +3163,121 @@ static void btf_struct_log(struct btf_verifier_env *env,
31633163 btf_verifier_log (env , "size=%u vlen=%u" , t -> size , btf_type_vlen (t ));
31643164}
31653165
3166+ enum btf_field_type {
3167+ BTF_FIELD_SPIN_LOCK ,
3168+ BTF_FIELD_TIMER ,
3169+ };
3170+
3171+ struct btf_field_info {
3172+ u32 off ;
3173+ };
3174+
3175+ static int btf_find_struct (const struct btf * btf , const struct btf_type * t ,
3176+ u32 off , int sz , struct btf_field_info * info )
3177+ {
3178+ if (!__btf_type_is_struct (t ))
3179+ return 0 ;
3180+ if (t -> size != sz )
3181+ return 0 ;
3182+ if (info -> off != - ENOENT )
3183+ /* only one such field is allowed */
3184+ return - E2BIG ;
3185+ info -> off = off ;
3186+ return 0 ;
3187+ }
3188+
31663189static int btf_find_struct_field (const struct btf * btf , const struct btf_type * t ,
3167- const char * name , int sz , int align )
3190+ const char * name , int sz , int align ,
3191+ enum btf_field_type field_type ,
3192+ struct btf_field_info * info )
31683193{
31693194 const struct btf_member * member ;
3170- u32 i , off = - ENOENT ;
3195+ u32 i , off ;
31713196
31723197 for_each_member (i , t , member ) {
31733198 const struct btf_type * member_type = btf_type_by_id (btf ,
31743199 member -> type );
3175- if (!__btf_type_is_struct (member_type ))
3176- continue ;
3177- if (member_type -> size != sz )
3178- continue ;
3200+
31793201 if (strcmp (__btf_name_by_offset (btf , member_type -> name_off ), name ))
31803202 continue ;
3181- if (off != - ENOENT )
3182- /* only one such field is allowed */
3183- return - E2BIG ;
3203+
31843204 off = __btf_member_bit_offset (t , member );
31853205 if (off % 8 )
31863206 /* valid C code cannot generate such BTF */
31873207 return - EINVAL ;
31883208 off /= 8 ;
31893209 if (off % align )
31903210 return - EINVAL ;
3211+
3212+ switch (field_type ) {
3213+ case BTF_FIELD_SPIN_LOCK :
3214+ case BTF_FIELD_TIMER :
3215+ return btf_find_struct (btf , member_type , off , sz , info );
3216+ default :
3217+ return - EFAULT ;
3218+ }
31913219 }
3192- return off ;
3220+ return 0 ;
31933221}
31943222
31953223static int btf_find_datasec_var (const struct btf * btf , const struct btf_type * t ,
3196- const char * name , int sz , int align )
3224+ const char * name , int sz , int align ,
3225+ enum btf_field_type field_type ,
3226+ struct btf_field_info * info )
31973227{
31983228 const struct btf_var_secinfo * vsi ;
3199- u32 i , off = - ENOENT ;
3229+ u32 i , off ;
32003230
32013231 for_each_vsi (i , t , vsi ) {
32023232 const struct btf_type * var = btf_type_by_id (btf , vsi -> type );
32033233 const struct btf_type * var_type = btf_type_by_id (btf , var -> type );
32043234
3205- if (! __btf_type_is_struct ( var_type ))
3206- continue ;
3207- if (var_type -> size != sz )
3235+ off = vsi -> offset ;
3236+
3237+ if (strcmp ( __btf_name_by_offset ( btf , var_type -> name_off ), name ) )
32083238 continue ;
32093239 if (vsi -> size != sz )
32103240 continue ;
3211- if (strcmp (__btf_name_by_offset (btf , var_type -> name_off ), name ))
3212- continue ;
3213- if (off != - ENOENT )
3214- /* only one such field is allowed */
3215- return - E2BIG ;
3216- off = vsi -> offset ;
32173241 if (off % align )
32183242 return - EINVAL ;
3243+
3244+ switch (field_type ) {
3245+ case BTF_FIELD_SPIN_LOCK :
3246+ case BTF_FIELD_TIMER :
3247+ return btf_find_struct (btf , var_type , off , sz , info );
3248+ default :
3249+ return - EFAULT ;
3250+ }
32193251 }
3220- return off ;
3252+ return 0 ;
32213253}
32223254
32233255static int btf_find_field (const struct btf * btf , const struct btf_type * t ,
3224- const char * name , int sz , int align )
3256+ enum btf_field_type field_type ,
3257+ struct btf_field_info * info )
32253258{
3259+ const char * name ;
3260+ int sz , align ;
3261+
3262+ switch (field_type ) {
3263+ case BTF_FIELD_SPIN_LOCK :
3264+ name = "bpf_spin_lock" ;
3265+ sz = sizeof (struct bpf_spin_lock );
3266+ align = __alignof__(struct bpf_spin_lock );
3267+ break ;
3268+ case BTF_FIELD_TIMER :
3269+ name = "bpf_timer" ;
3270+ sz = sizeof (struct bpf_timer );
3271+ align = __alignof__(struct bpf_timer );
3272+ break ;
3273+ default :
3274+ return - EFAULT ;
3275+ }
32263276
32273277 if (__btf_type_is_struct (t ))
3228- return btf_find_struct_field (btf , t , name , sz , align );
3278+ return btf_find_struct_field (btf , t , name , sz , align , field_type , info );
32293279 else if (btf_type_is_datasec (t ))
3230- return btf_find_datasec_var (btf , t , name , sz , align );
3280+ return btf_find_datasec_var (btf , t , name , sz , align , field_type , info );
32313281 return - EINVAL ;
32323282}
32333283
@@ -3237,16 +3287,24 @@ static int btf_find_field(const struct btf *btf, const struct btf_type *t,
32373287 */
32383288int btf_find_spin_lock (const struct btf * btf , const struct btf_type * t )
32393289{
3240- return btf_find_field (btf , t , "bpf_spin_lock" ,
3241- sizeof (struct bpf_spin_lock ),
3242- __alignof__(struct bpf_spin_lock ));
3290+ struct btf_field_info info = { .off = - ENOENT };
3291+ int ret ;
3292+
3293+ ret = btf_find_field (btf , t , BTF_FIELD_SPIN_LOCK , & info );
3294+ if (ret < 0 )
3295+ return ret ;
3296+ return info .off ;
32433297}
32443298
32453299int btf_find_timer (const struct btf * btf , const struct btf_type * t )
32463300{
3247- return btf_find_field (btf , t , "bpf_timer" ,
3248- sizeof (struct bpf_timer ),
3249- __alignof__(struct bpf_timer ));
3301+ struct btf_field_info info = { .off = - ENOENT };
3302+ int ret ;
3303+
3304+ ret = btf_find_field (btf , t , BTF_FIELD_TIMER , & info );
3305+ if (ret < 0 )
3306+ return ret ;
3307+ return info .off ;
32503308}
32513309
32523310static void __btf_struct_show (const struct btf * btf , const struct btf_type * t ,
0 commit comments