Add pt_regs handling in aya-bpf/args.rs for riscv64

This patch introduces `pt_regs` handling in aya-bpf/args.rs
for the riscv64 architecture. The current CI is disabled
for riscv64 because this implementation is missing.
pull/627/head
Kenjiro Nakayama 1 year ago
parent 9cdae81265
commit 7dfabd07a7

@ -21,8 +21,7 @@ jobs:
- x86_64 - x86_64
- aarch64 - aarch64
- arm - arm
# Disable riscv64 due to missing pt_regs handling in aya-bpf/args.rs - riscv64
# - riscv64
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:

@ -26,6 +26,9 @@ mod ad {
#[cfg(bpf_target_arch = "aarch64")] #[cfg(bpf_target_arch = "aarch64")]
pub type c_char = super::c_uchar; pub type c_char = super::c_uchar;
#[cfg(bpf_target_arch = "riscv64")]
pub type c_char = super::c_uchar;
#[cfg(any(bpf_target_arch = "x86", bpf_target_arch = "x86_64"))] #[cfg(any(bpf_target_arch = "x86", bpf_target_arch = "x86_64"))]
pub type c_char = super::c_schar; pub type c_char = super::c_schar;

@ -1,11 +1,15 @@
use crate::{cty::c_void, helpers::bpf_probe_read}; use crate::{cty::c_void, helpers::bpf_probe_read};
// aarch64 uses user_pt_regs instead of pt_regs // aarch64 uses user_pt_regs instead of pt_regs
#[cfg(not(bpf_target_arch = "aarch64"))] #[cfg(not(any(bpf_target_arch = "aarch64", bpf_target_arch = "riscv64")))]
use crate::bindings::pt_regs; use crate::bindings::pt_regs;
#[cfg(bpf_target_arch = "aarch64")] #[cfg(bpf_target_arch = "aarch64")]
use crate::bindings::user_pt_regs as pt_regs; use crate::bindings::user_pt_regs as pt_regs;
#[cfg(bpf_target_arch = "riscv64")]
use crate::bindings::user_regs_struct as pt_regs;
/// A trait that indicates a valid type for an argument which can be coerced from a BTF /// A trait that indicates a valid type for an argument which can be coerced from a BTF
/// context. /// context.
/// ///
@ -60,7 +64,7 @@ pub struct PtRegs {
regs: *mut pt_regs, regs: *mut pt_regs,
} }
/// A portable wrapper around pt_regs and user_pt_regs. /// A portable wrapper around pt_regs, user_pt_regs and user_regs_struct.
impl PtRegs { impl PtRegs {
pub fn new(regs: *mut pt_regs) -> Self { pub fn new(regs: *mut pt_regs) -> Self {
PtRegs { regs } PtRegs { regs }
@ -146,6 +150,27 @@ impl<T> FromPtRegs for *const T {
} }
} }
#[cfg(bpf_target_arch = "riscv64")]
impl<T> FromPtRegs for *const T {
fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
match n {
0 => unsafe { bpf_probe_read(&ctx.a0).map(|v| v as *const _).ok() },
1 => unsafe { bpf_probe_read(&ctx.a1).map(|v| v as *const _).ok() },
2 => unsafe { bpf_probe_read(&ctx.a2).map(|v| v as *const _).ok() },
3 => unsafe { bpf_probe_read(&ctx.a3).map(|v| v as *const _).ok() },
4 => unsafe { bpf_probe_read(&ctx.a4).map(|v| v as *const _).ok() },
5 => unsafe { bpf_probe_read(&ctx.a5).map(|v| v as *const _).ok() },
6 => unsafe { bpf_probe_read(&ctx.a6).map(|v| v as *const _).ok() },
7 => unsafe { bpf_probe_read(&ctx.a7).map(|v| v as *const _).ok() },
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.ra).map(|v| v as *const _).ok() }
}
}
#[cfg(bpf_target_arch = "x86_64")] #[cfg(bpf_target_arch = "x86_64")]
impl<T> FromPtRegs for *mut T { impl<T> FromPtRegs for *mut T {
fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> { fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
@ -195,6 +220,27 @@ impl<T> FromPtRegs for *mut T {
} }
} }
#[cfg(bpf_target_arch = "riscv64")]
impl<T> FromPtRegs for *mut T {
fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
match n {
0 => unsafe { bpf_probe_read(&ctx.a0).map(|v| v as *mut _).ok() },
1 => unsafe { bpf_probe_read(&ctx.a1).map(|v| v as *mut _).ok() },
2 => unsafe { bpf_probe_read(&ctx.a2).map(|v| v as *mut _).ok() },
3 => unsafe { bpf_probe_read(&ctx.a3).map(|v| v as *mut _).ok() },
4 => unsafe { bpf_probe_read(&ctx.a4).map(|v| v as *mut _).ok() },
5 => unsafe { bpf_probe_read(&ctx.a5).map(|v| v as *mut _).ok() },
6 => unsafe { bpf_probe_read(&ctx.a6).map(|v| v as *mut _).ok() },
7 => unsafe { bpf_probe_read(&ctx.a7).map(|v| v as *mut _).ok() },
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.ra).map(|v| v as *mut _).ok() }
}
}
/// Helper macro to implement [`FromPtRegs`] for a primitive type. /// Helper macro to implement [`FromPtRegs`] for a primitive type.
macro_rules! impl_from_pt_regs { macro_rules! impl_from_pt_regs {
($type:ident) => { ($type:ident) => {
@ -246,6 +292,27 @@ macro_rules! impl_from_pt_regs {
Some(ctx.regs[0] as *const $type as _) Some(ctx.regs[0] as *const $type as _)
} }
} }
#[cfg(bpf_target_arch = "riscv64")]
impl FromPtRegs for $type {
fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
match n {
0 => Some(ctx.a0 as *const $type as _),
1 => Some(ctx.a1 as *const $type as _),
2 => Some(ctx.a2 as *const $type as _),
3 => Some(ctx.a3 as *const $type as _),
4 => Some(ctx.a4 as *const $type as _),
5 => Some(ctx.a5 as *const $type as _),
6 => Some(ctx.a6 as *const $type as _),
7 => Some(ctx.a7 as *const $type as _),
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
Some(ctx.ra as *const $type as _)
}
}
}; };
} }

@ -2,12 +2,15 @@ use core::ffi::c_void;
use crate::{args::FromPtRegs, BpfContext}; use crate::{args::FromPtRegs, BpfContext};
// aarch64 uses user_pt_regs instead of pt_regs #[cfg(not(any(bpf_target_arch = "aarch64", bpf_target_arch = "riscv64")))]
#[cfg(not(bpf_target_arch = "aarch64"))]
use crate::bindings::pt_regs; use crate::bindings::pt_regs;
#[cfg(bpf_target_arch = "aarch64")] #[cfg(bpf_target_arch = "aarch64")]
use crate::bindings::user_pt_regs as pt_regs; use crate::bindings::user_pt_regs as pt_regs;
#[cfg(bpf_target_arch = "riscv64")]
use crate::bindings::user_regs_struct as pt_regs;
pub struct ProbeContext { pub struct ProbeContext {
pub regs: *mut pt_regs, pub regs: *mut pt_regs,
} }

Loading…
Cancel
Save