@@ -11,130 +11,147 @@ import (
1111
1212// haveBTF attempts to load a BTF blob containing an Int. It should pass on any
1313// kernel that supports BPF_BTF_LOAD.
14- var haveBTF = internal .NewFeatureTest ("BTF" , func () error {
15- // 0-length anonymous integer
16- err := probeBTF (& Int {})
17- if errors .Is (err , unix .EINVAL ) || errors .Is (err , unix .EPERM ) {
18- return internal .ErrNotSupported
19- }
20- return err
21- }, "4.18" )
14+ var haveBTF = internal .NewFeatureTest ("BTF" ,
15+ func (opts ... internal.FeatureTestOption ) error {
16+ // 0-length anonymous integer
17+ o := internal .BuildOptions (opts ... )
18+
19+ err := probeBTF (& Int {}, o .BpffsTokenFd )
20+ if errors .Is (err , unix .EINVAL ) || errors .Is (err , unix .EPERM ) {
21+ return internal .ErrNotSupported
22+ }
23+ return err
24+ },
25+ "4.18" ,
26+ )
2227
2328// haveMapBTF attempts to load a minimal BTF blob containing a Var. It is
2429// used as a proxy for .bss, .data and .rodata map support, which generally
2530// come with a Var and Datasec. These were introduced in Linux 5.2.
26- var haveMapBTF = internal .NewFeatureTest ("Map BTF (Var/Datasec)" , func () error {
27- if err := haveBTF (); err != nil {
31+ var haveMapBTF = internal .NewFeatureTest ("Map BTF (Var/Datasec)" ,
32+ func (opts ... internal.FeatureTestOption ) error {
33+ if err := haveBTF (opts ... ); err != nil {
34+ return err
35+ }
36+
37+ v := & Var {
38+ Name : "a" ,
39+ Type : & Pointer {(* Void )(nil )},
40+ }
41+
42+ o := internal .BuildOptions (opts ... )
43+ err := probeBTF (v , o .BpffsTokenFd )
44+ if errors .Is (err , unix .EINVAL ) || errors .Is (err , unix .EPERM ) {
45+ // Treat both EINVAL and EPERM as not supported: creating the map may still
46+ // succeed without Btf* attrs.
47+ return internal .ErrNotSupported
48+ }
2849 return err
29- }
30-
31- v := & Var {
32- Name : "a" ,
33- Type : & Pointer {(* Void )(nil )},
34- }
35-
36- err := probeBTF (v )
37- if errors .Is (err , unix .EINVAL ) || errors .Is (err , unix .EPERM ) {
38- // Treat both EINVAL and EPERM as not supported: creating the map may still
39- // succeed without Btf* attrs.
40- return internal .ErrNotSupported
41- }
42- return err
43- }, "5.2" )
50+ }, "5.2" )
4451
4552// haveProgBTF attempts to load a BTF blob containing a Func and FuncProto. It
4653// is used as a proxy for ext_info (func_info) support, which depends on
4754// Func(Proto) by definition.
48- var haveProgBTF = internal .NewFeatureTest ("Program BTF (func/line_info)" , func () error {
49- if err := haveBTF (); err != nil {
55+ var haveProgBTF = internal .NewFeatureTest ("Program BTF (func/line_info)" ,
56+ func (opts ... internal.FeatureTestOption ) error {
57+ if err := haveBTF (opts ... ); err != nil {
58+ return err
59+ }
60+
61+ fn := & Func {
62+ Name : "a" ,
63+ Type : & FuncProto {Return : (* Void )(nil )},
64+ }
65+
66+ o := internal .BuildOptions (opts ... )
67+ err := probeBTF (fn , o .BpffsTokenFd )
68+ if errors .Is (err , unix .EINVAL ) || errors .Is (err , unix .EPERM ) {
69+ return internal .ErrNotSupported
70+ }
5071 return err
51- }
52-
53- fn := & Func {
54- Name : "a" ,
55- Type : & FuncProto {Return : (* Void )(nil )},
56- }
57-
58- err := probeBTF (fn )
59- if errors .Is (err , unix .EINVAL ) || errors .Is (err , unix .EPERM ) {
60- return internal .ErrNotSupported
61- }
62- return err
63- }, "5.0" )
64-
65- var haveFuncLinkage = internal .NewFeatureTest ("BTF func linkage" , func () error {
66- if err := haveProgBTF (); err != nil {
72+ }, "5.0" )
73+
74+ var haveFuncLinkage = internal .NewFeatureTest ("BTF func linkage" ,
75+ func (opts ... internal.FeatureTestOption ) error {
76+ if err := haveProgBTF (opts ... ); err != nil {
77+ return err
78+ }
79+
80+ fn := & Func {
81+ Name : "a" ,
82+ Type : & FuncProto {Return : (* Void )(nil )},
83+ Linkage : GlobalFunc ,
84+ }
85+
86+ o := internal .BuildOptions (opts ... )
87+ err := probeBTF (fn , o .BpffsTokenFd )
88+ if errors .Is (err , unix .EINVAL ) {
89+ return internal .ErrNotSupported
90+ }
6791 return err
68- }
69-
70- fn := & Func {
71- Name : "a" ,
72- Type : & FuncProto {Return : (* Void )(nil )},
73- Linkage : GlobalFunc ,
74- }
75-
76- err := probeBTF (fn )
77- if errors .Is (err , unix .EINVAL ) {
78- return internal .ErrNotSupported
79- }
80- return err
81- }, "5.6" )
82-
83- var haveDeclTags = internal .NewFeatureTest ("BTF decl tags" , func () error {
84- if err := haveBTF (); err != nil {
92+ }, "5.6" )
93+
94+ var haveDeclTags = internal .NewFeatureTest ("BTF decl tags" ,
95+ func (opts ... internal.FeatureTestOption ) error {
96+ if err := haveBTF (opts ... ); err != nil {
97+ return err
98+ }
99+
100+ t := & Typedef {
101+ Name : "a" ,
102+ Type : & Int {},
103+ Tags : []string {"a" },
104+ }
105+
106+ o := internal .BuildOptions (opts ... )
107+ err := probeBTF (t , o .BpffsTokenFd )
108+ if errors .Is (err , unix .EINVAL ) {
109+ return internal .ErrNotSupported
110+ }
85111 return err
86- }
87-
88- t := & Typedef {
89- Name : "a" ,
90- Type : & Int {},
91- Tags : []string {"a" },
92- }
93-
94- err := probeBTF (t )
95- if errors .Is (err , unix .EINVAL ) {
96- return internal .ErrNotSupported
97- }
98- return err
99- }, "5.16" )
100-
101- var haveTypeTags = internal .NewFeatureTest ("BTF type tags" , func () error {
102- if err := haveBTF (); err != nil {
112+ }, "5.16" )
113+
114+ var haveTypeTags = internal .NewFeatureTest ("BTF type tags" ,
115+ func (opts ... internal.FeatureTestOption ) error {
116+ if err := haveBTF (opts ... ); err != nil {
117+ return err
118+ }
119+
120+ t := & TypeTag {
121+ Type : & Int {},
122+ Value : "a" ,
123+ }
124+
125+ o := internal .BuildOptions (opts ... )
126+ err := probeBTF (t , o .BpffsTokenFd )
127+ if errors .Is (err , unix .EINVAL ) {
128+ return internal .ErrNotSupported
129+ }
103130 return err
104- }
105-
106- t := & TypeTag {
107- Type : & Int {},
108- Value : "a" ,
109- }
110-
111- err := probeBTF (t )
112- if errors .Is (err , unix .EINVAL ) {
113- return internal .ErrNotSupported
114- }
115- return err
116- }, "5.17" )
117-
118- var haveEnum64 = internal .NewFeatureTest ("ENUM64" , func () error {
119- if err := haveBTF (); err != nil {
131+ }, "5.17" )
132+
133+ var haveEnum64 = internal .NewFeatureTest ("ENUM64" ,
134+ func (opts ... internal.FeatureTestOption ) error {
135+ if err := haveBTF (opts ... ); err != nil {
136+ return err
137+ }
138+
139+ enum := & Enum {
140+ Size : 8 ,
141+ Values : []EnumValue {
142+ {"TEST" , math .MaxUint32 + 1 },
143+ },
144+ }
145+
146+ o := internal .BuildOptions (opts ... )
147+ err := probeBTF (enum , o .BpffsTokenFd )
148+ if errors .Is (err , unix .EINVAL ) {
149+ return internal .ErrNotSupported
150+ }
120151 return err
121- }
152+ }, "6.0" )
122153
123- enum := & Enum {
124- Size : 8 ,
125- Values : []EnumValue {
126- {"TEST" , math .MaxUint32 + 1 },
127- },
128- }
129-
130- err := probeBTF (enum )
131- if errors .Is (err , unix .EINVAL ) {
132- return internal .ErrNotSupported
133- }
134- return err
135- }, "6.0" )
136-
137- func probeBTF (typ Type ) error {
154+ func probeBTF (typ Type , tokenFd int32 ) error {
138155 b , err := NewBuilder ([]Type {typ })
139156 if err != nil {
140157 return err
@@ -145,11 +162,17 @@ func probeBTF(typ Type) error {
145162 return err
146163 }
147164
148- fd , err := sys . BtfLoad ( & sys.BtfLoadAttr {
165+ attr := & sys.BtfLoadAttr {
149166 Btf : sys .SlicePointer (buf ),
150167 BtfSize : uint32 (len (buf )),
151- })
168+ }
169+
170+ if tokenFd > 0 {
171+ attr .BtfTokenFd = tokenFd
172+ attr .BtfFlags |= sys .BPF_F_TOKEN_FD
173+ }
152174
175+ fd , err := sys .BtfLoad (attr )
153176 if err == nil {
154177 fd .Close ()
155178 }
0 commit comments