aya: Add probe for bpf_link_create for perf programs

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
pull/522/head
Dave Tucker 2 years ago
parent ce22ca668f
commit 763b92a2e0

@ -35,8 +35,8 @@ use crate::{
sys::{ sys::{
bpf_load_btf, bpf_map_freeze, bpf_map_update_elem_ptr, is_btf_datasec_supported, bpf_load_btf, bpf_map_freeze, bpf_map_update_elem_ptr, is_btf_datasec_supported,
is_btf_decl_tag_supported, is_btf_float_supported, is_btf_func_global_supported, is_btf_decl_tag_supported, is_btf_float_supported, is_btf_func_global_supported,
is_btf_func_supported, is_btf_supported, is_btf_type_tag_supported, is_prog_name_supported, is_btf_func_supported, is_btf_supported, is_btf_type_tag_supported, is_perf_link_supported,
retry_with_verifier_logs, is_prog_name_supported, retry_with_verifier_logs,
}, },
util::{bytes_of, possible_cpus, VerifierLog, POSSIBLE_CPUS}, util::{bytes_of, possible_cpus, VerifierLog, POSSIBLE_CPUS},
}; };
@ -73,6 +73,7 @@ lazy_static! {
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub(crate) struct Features { pub(crate) struct Features {
pub bpf_name: bool, pub bpf_name: bool,
pub bpf_perf_link: bool,
pub btf: Option<BtfFeatures>, pub btf: Option<BtfFeatures>,
} }
@ -92,6 +93,7 @@ impl Features {
}; };
let f = Features { let f = Features {
bpf_name: is_prog_name_supported(), bpf_name: is_prog_name_supported(),
bpf_perf_link: is_perf_link_supported(),
btf, btf,
}; };
@ -107,8 +109,10 @@ impl std::fmt::Display for Features {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!( f.write_fmt(format_args!(
"[FEAT PROBE] BPF program name support: {}\n\ "[FEAT PROBE] BPF program name support: {}\n\
[FEAT PROBE] bpf_link support for kprobe/uprobe/tracepoint: {}\n\
[FEAT PROBE] BTF support: {}", [FEAT PROBE] BTF support: {}",
self.bpf_name, self.bpf_name,
self.bpf_perf_link,
self.btf.is_some() self.btf.is_some()
)) ))
} }
@ -358,7 +362,7 @@ impl<'a> BpfLoader<'a> {
let mut obj = Object::parse(data)?; let mut obj = Object::parse(data)?;
obj.patch_map_data(self.globals.clone())?; obj.patch_map_data(self.globals.clone())?;
let btf_fd = if let Some(ref features) = FEATURES.btf { let btf_fd = if let Some(features) = &FEATURES.btf {
if let Some(btf) = obj.fixup_and_sanitize_btf(features)? { if let Some(btf) = obj.fixup_and_sanitize_btf(features)? {
// load btf to the kernel // load btf to the kernel
Some(load_btf(btf.to_bytes())?) Some(load_btf(btf.to_bytes())?)

@ -599,6 +599,37 @@ pub(crate) fn is_prog_name_supported() -> bool {
} }
} }
pub(crate) fn is_perf_link_supported() -> bool {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_3 };
let prog: &[u8] = &[
0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r0 = 0
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exit
];
let gpl = b"GPL\0";
u.license = gpl.as_ptr() as u64;
let insns = copy_instructions(prog).unwrap();
u.insn_cnt = insns.len() as u32;
u.insns = insns.as_ptr() as u64;
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT as u32;
if let Ok(fd) = sys_bpf(bpf_cmd::BPF_PROG_LOAD, &attr) {
if let Err((code, _)) =
// Uses an invalid target FD so we get EBADF if supported.
bpf_link_create(fd as i32, -1, bpf_attach_type::BPF_PERF_EVENT, None, 0)
{
// Returns EINVAL if unsupported. EBADF if supported.
let res = code == (-libc::EBADF).into();
unsafe { libc::close(fd as i32) };
return res;
}
}
false
}
pub(crate) fn is_btf_supported() -> bool { pub(crate) fn is_btf_supported() -> bool {
let mut btf = Btf::new(); let mut btf = Btf::new();
let name_offset = btf.add_string("int".to_string()); let name_offset = btf.add_string("int".to_string());

Loading…
Cancel
Save