@@ -6798,10 +6798,113 @@ int register_btf_kfunc_id_set(enum bpf_prog_type prog_type,
6798
6798
}
6799
6799
EXPORT_SYMBOL_GPL (register_btf_kfunc_id_set );
6800
6800
6801
+ #define MAX_TYPES_ARE_COMPAT_DEPTH 2
6802
+
6803
+ static
6804
+ int __bpf_core_types_are_compat (const struct btf * local_btf , __u32 local_id ,
6805
+ const struct btf * targ_btf , __u32 targ_id ,
6806
+ int level )
6807
+ {
6808
+ const struct btf_type * local_type , * targ_type ;
6809
+ int depth = 32 ; /* max recursion depth */
6810
+
6811
+ /* caller made sure that names match (ignoring flavor suffix) */
6812
+ local_type = btf_type_by_id (local_btf , local_id );
6813
+ targ_type = btf_type_by_id (targ_btf , targ_id );
6814
+ if (btf_kind (local_type ) != btf_kind (targ_type ))
6815
+ return 0 ;
6816
+
6817
+ recur :
6818
+ depth -- ;
6819
+ if (depth < 0 )
6820
+ return - EINVAL ;
6821
+
6822
+ local_type = btf_type_skip_modifiers (local_btf , local_id , & local_id );
6823
+ targ_type = btf_type_skip_modifiers (targ_btf , targ_id , & targ_id );
6824
+ if (!local_type || !targ_type )
6825
+ return - EINVAL ;
6826
+
6827
+ if (btf_kind (local_type ) != btf_kind (targ_type ))
6828
+ return 0 ;
6829
+
6830
+ switch (btf_kind (local_type )) {
6831
+ case BTF_KIND_UNKN :
6832
+ case BTF_KIND_STRUCT :
6833
+ case BTF_KIND_UNION :
6834
+ case BTF_KIND_ENUM :
6835
+ case BTF_KIND_FWD :
6836
+ return 1 ;
6837
+ case BTF_KIND_INT :
6838
+ /* just reject deprecated bitfield-like integers; all other
6839
+ * integers are by default compatible between each other
6840
+ */
6841
+ return btf_int_offset (local_type ) == 0 && btf_int_offset (targ_type ) == 0 ;
6842
+ case BTF_KIND_PTR :
6843
+ local_id = local_type -> type ;
6844
+ targ_id = targ_type -> type ;
6845
+ goto recur ;
6846
+ case BTF_KIND_ARRAY :
6847
+ local_id = btf_array (local_type )-> type ;
6848
+ targ_id = btf_array (targ_type )-> type ;
6849
+ goto recur ;
6850
+ case BTF_KIND_FUNC_PROTO : {
6851
+ struct btf_param * local_p = btf_params (local_type );
6852
+ struct btf_param * targ_p = btf_params (targ_type );
6853
+ __u16 local_vlen = btf_vlen (local_type );
6854
+ __u16 targ_vlen = btf_vlen (targ_type );
6855
+ int i , err ;
6856
+
6857
+ if (local_vlen != targ_vlen )
6858
+ return 0 ;
6859
+
6860
+ for (i = 0 ; i < local_vlen ; i ++ , local_p ++ , targ_p ++ ) {
6861
+ if (level <= 1 )
6862
+ return - EINVAL ;
6863
+
6864
+ btf_type_skip_modifiers (local_btf , local_p -> type , & local_id );
6865
+ btf_type_skip_modifiers (targ_btf , targ_p -> type , & targ_id );
6866
+ err = __bpf_core_types_are_compat (local_btf , local_id ,
6867
+ targ_btf , targ_id ,
6868
+ level - 1 );
6869
+ if (err <= 0 )
6870
+ return err ;
6871
+ }
6872
+
6873
+ /* tail recurse for return type check */
6874
+ btf_type_skip_modifiers (local_btf , local_type -> type , & local_id );
6875
+ btf_type_skip_modifiers (targ_btf , targ_type -> type , & targ_id );
6876
+ goto recur ;
6877
+ }
6878
+ default :
6879
+ return 0 ;
6880
+ }
6881
+ }
6882
+
6883
+ /* Check local and target types for compatibility. This check is used for
6884
+ * type-based CO-RE relocations and follow slightly different rules than
6885
+ * field-based relocations. This function assumes that root types were already
6886
+ * checked for name match. Beyond that initial root-level name check, names
6887
+ * are completely ignored. Compatibility rules are as follows:
6888
+ * - any two STRUCTs/UNIONs/FWDs/ENUMs/INTs are considered compatible, but
6889
+ * kind should match for local and target types (i.e., STRUCT is not
6890
+ * compatible with UNION);
6891
+ * - for ENUMs, the size is ignored;
6892
+ * - for INT, size and signedness are ignored;
6893
+ * - for ARRAY, dimensionality is ignored, element types are checked for
6894
+ * compatibility recursively;
6895
+ * - CONST/VOLATILE/RESTRICT modifiers are ignored;
6896
+ * - TYPEDEFs/PTRs are compatible if types they pointing to are compatible;
6897
+ * - FUNC_PROTOs are compatible if they have compatible signature: same
6898
+ * number of input args and compatible return and argument types.
6899
+ * These rules are not set in stone and probably will be adjusted as we get
6900
+ * more experience with using BPF CO-RE relocations.
6901
+ */
6801
6902
int bpf_core_types_are_compat (const struct btf * local_btf , __u32 local_id ,
6802
6903
const struct btf * targ_btf , __u32 targ_id )
6803
6904
{
6804
- return - EOPNOTSUPP ;
6905
+ return __bpf_core_types_are_compat (local_btf , local_id ,
6906
+ targ_btf , targ_id ,
6907
+ MAX_TYPES_ARE_COMPAT_DEPTH );
6805
6908
}
6806
6909
6807
6910
static bool bpf_core_is_flavor_sep (const char * s )
0 commit comments