浏览代码

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.
Kenjiro Nakayama 1 年之前
父节点
当前提交
7dfabd07a7
共有 4 个文件被更改,包括 78 次插入6 次删除
  1. 1 2
      .github/workflows/build-aya-bpf.yml
  2. 3 0
      bpf/aya-bpf-cty/src/lib.rs
  3. 69 2
      bpf/aya-bpf/src/args.rs
  4. 5 2
      bpf/aya-bpf/src/programs/probe.rs

+ 1 - 2
.github/workflows/build-aya-bpf.yml

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

+ 3 - 0
bpf/aya-bpf-cty/src/lib.rs

@@ -26,6 +26,9 @@ mod ad {
     #[cfg(bpf_target_arch = "aarch64")]
     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"))]
     pub type c_char = super::c_schar;
 

+ 69 - 2
bpf/aya-bpf/src/args.rs

@@ -1,11 +1,15 @@
 use crate::{cty::c_void, helpers::bpf_probe_read};
 
 // 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;
+
 #[cfg(bpf_target_arch = "aarch64")]
 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
 /// context.
 ///
@@ -60,7 +64,7 @@ pub struct PtRegs {
     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 {
     pub fn new(regs: *mut pt_regs) -> Self {
         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")]
 impl<T> FromPtRegs for *mut T {
     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.
 macro_rules! impl_from_pt_regs {
     ($type:ident) => {
@@ -246,6 +292,27 @@ macro_rules! impl_from_pt_regs {
                 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 _)
+            }
+        }
     };
 }
 

+ 5 - 2
bpf/aya-bpf/src/programs/probe.rs

@@ -2,12 +2,15 @@ use core::ffi::c_void;
 
 use crate::{args::FromPtRegs, BpfContext};
 
-// 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;
+
 #[cfg(bpf_target_arch = "aarch64")]
 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 regs: *mut pt_regs,
 }