Selaa lähdekoodia

aya: add archs powerpc64 and s390x to aya

bpfman, a project using aya, has a requirement to support powerpc64 and
s390x architectures. Adding these two architectures to aya.

Signed-off-by: Billy McFall <[email protected]>
Billy McFall 8 kuukautta sitten
vanhempi
commit
b513af12e8

+ 6 - 0
.cargo/config.toml

@@ -9,3 +9,9 @@ linker = "arm-linux-gnueabihf-gcc"
 
 [target.aarch64-unknown-linux-musl]
 linker = "aarch64-linux-musl-gcc"
+
+[target.powerpc64le-unknown-linux-gnu]
+linker = "powerpc64le-linux-gnu-gcc"
+
+[target.s390x-unknown-linux-gnu]
+linker = "s390x-linux-gnu-gcc"

+ 4 - 0
.github/workflows/ci.yml

@@ -72,6 +72,8 @@ jobs:
           - aarch64-unknown-linux-gnu
           - armv7-unknown-linux-gnueabi
           - riscv64gc-unknown-linux-gnu
+          - powerpc64le-unknown-linux-gnu
+          - s390x-unknown-linux-gnu
     runs-on: ubuntu-22.04
     steps:
       - uses: actions/checkout@v4
@@ -135,6 +137,8 @@ jobs:
           - aarch64
           - arm
           - riscv64
+          - powerpc64
+          - s390x
         target:
           - bpfel-unknown-none
           - bpfeb-unknown-none

+ 1 - 1
Cargo.toml

@@ -40,7 +40,7 @@ default-members = [
 
     # ebpf crates are omitted; they must be built with:
     # --target bpfe{b,l}-unknown-none
-    # CARGO_CFG_BPF_TARGET_ARCH={x86_64,aarch64,arm,riscv64}
+    # CARGO_CFG_BPF_TARGET_ARCH={x86_64,aarch64,arm,riscv64,powerpc64,s390x}
 ]
 
 [workspace.package]

+ 1 - 1
aya-obj/src/btf/relocation.rs

@@ -1215,7 +1215,7 @@ impl ComputedRelocation {
             }
             #[cfg(target_endian = "big")]
             FieldLShift64 => {
-                value.value = (8 - byte_size) * 8 + (bit_off - byte_off * 8);
+                value.value = ((8 - byte_size) * 8 + (bit_off - byte_off * 8)) as u64;
             }
             FieldRShift64 => {
                 value.value = 64 - bit_size as u64;

+ 8 - 0
aya-obj/src/generated/mod.rs

@@ -13,8 +13,12 @@ mod btf_internal_bindings;
 mod linux_bindings_aarch64;
 #[cfg(target_arch = "arm")]
 mod linux_bindings_armv7;
+#[cfg(target_arch = "powerpc64")]
+mod linux_bindings_powerpc64;
 #[cfg(target_arch = "riscv64")]
 mod linux_bindings_riscv64;
+#[cfg(target_arch = "s390x")]
+mod linux_bindings_s390x;
 #[cfg(target_arch = "x86_64")]
 mod linux_bindings_x86_64;
 
@@ -25,7 +29,11 @@ pub use btf_internal_bindings::{bpf_core_relo, bpf_core_relo_kind, btf_ext_heade
 pub use linux_bindings_aarch64::*;
 #[cfg(target_arch = "arm")]
 pub use linux_bindings_armv7::*;
+#[cfg(target_arch = "powerpc64")]
+pub use linux_bindings_powerpc64::*;
 #[cfg(target_arch = "riscv64")]
 pub use linux_bindings_riscv64::*;
+#[cfg(target_arch = "s390x")]
+pub use linux_bindings_s390x::*;
 #[cfg(target_arch = "x86_64")]
 pub use linux_bindings_x86_64::*;

+ 1 - 1
ebpf/aya-ebpf-bindings/build.rs

@@ -9,5 +9,5 @@ fn main() {
         let arch = arch.split_once('-').map_or(&*arch, |x| x.0);
         println!("cargo:rustc-cfg=bpf_target_arch=\"{arch}\"");
     }
-    println!("cargo::rustc-check-cfg=cfg(bpf_target_arch, values(\"x86_64\",\"arm\",\"aarch64\",\"riscv64\"))");
+    println!("cargo::rustc-check-cfg=cfg(bpf_target_arch, values(\"x86_64\",\"arm\",\"aarch64\",\"riscv64\",\"powerpc64\",\"s390x\"))");
 }

+ 10 - 0
ebpf/aya-ebpf-bindings/src/lib.rs

@@ -14,13 +14,23 @@ mod aarch64;
 #[cfg(bpf_target_arch = "riscv64")]
 mod riscv64;
 
+#[cfg(bpf_target_arch = "powerpc64")]
+mod powerpc64;
+
+#[cfg(bpf_target_arch = "s390x")]
+mod s390x;
+
 mod gen {
     #[cfg(bpf_target_arch = "aarch64")]
     pub use super::aarch64::*;
     #[cfg(bpf_target_arch = "arm")]
     pub use super::armv7::*;
+    #[cfg(bpf_target_arch = "powerpc64")]
+    pub use super::powerpc64::*;
     #[cfg(bpf_target_arch = "riscv64")]
     pub use super::riscv64::*;
+    #[cfg(bpf_target_arch = "s390x")]
+    pub use super::s390x::*;
     #[cfg(bpf_target_arch = "x86_64")]
     pub use super::x86_64::*;
 }

+ 3 - 0
ebpf/aya-ebpf-bindings/src/powerpc64/mod.rs

@@ -0,0 +1,3 @@
+#![allow(clippy::all, dead_code)]
+pub mod bindings;
+pub mod helpers;

+ 3 - 0
ebpf/aya-ebpf-bindings/src/s390x/mod.rs

@@ -0,0 +1,3 @@
+#![allow(clippy::all, dead_code)]
+pub mod bindings;
+pub mod helpers;

+ 1 - 1
ebpf/aya-ebpf-cty/build.rs

@@ -9,6 +9,6 @@ fn main() {
         let arch = arch.split_once('-').map_or(&*arch, |x| x.0);
         println!("cargo:rustc-cfg=bpf_target_arch=\"{arch}\"");
     }
-    println!("cargo::rustc-check-cfg=cfg(bpf_target_arch, values(\"x86_64\",\"arm\",\"aarch64\",\"riscv64\"))");
+    println!("cargo::rustc-check-cfg=cfg(bpf_target_arch, values(\"x86_64\",\"arm\",\"aarch64\",\"riscv64\",\"powerpc64\",\"s390x\"))");
     println!("cargo::rustc-check-cfg=cfg(target_arch, values(\"asmjs\",\"nvptx\",\"xtensa\"))");
 }

+ 6 - 0
ebpf/aya-ebpf-cty/src/lib.rs

@@ -24,9 +24,15 @@ mod ad {
     #[cfg(bpf_target_arch = "aarch64")]
     pub type c_char = super::c_uchar;
 
+    #[cfg(bpf_target_arch = "powerpc64")]
+    pub type c_char = super::c_uchar;
+
     #[cfg(bpf_target_arch = "riscv64")]
     pub type c_char = super::c_uchar;
 
+    #[cfg(bpf_target_arch = "s390x")]
+    pub type c_char = super::c_uchar;
+
     #[cfg(bpf_target_arch = "x86_64")]
     pub type c_char = super::c_schar;
 }

+ 1 - 1
ebpf/aya-ebpf/build.rs

@@ -10,7 +10,7 @@ fn main() {
         let arch = arch.split_once('-').map_or(&*arch, |x| x.0);
         println!("cargo:rustc-cfg=bpf_target_arch=\"{arch}\"");
     }
-    println!("cargo::rustc-check-cfg=cfg(bpf_target_arch, values(\"x86_64\",\"arm\",\"aarch64\",\"riscv64\"))");
+    println!("cargo::rustc-check-cfg=cfg(bpf_target_arch, values(\"x86_64\",\"arm\",\"aarch64\",\"riscv64\",\"powerpc64\",\"s390x\"))");
     println!("cargo::rustc-check-cfg=cfg(unstable)");
 }
 

+ 98 - 3
ebpf/aya-ebpf/src/args.rs

@@ -1,8 +1,13 @@
-// aarch64 uses user_pt_regs instead of pt_regs
-#[cfg(not(any(bpf_target_arch = "aarch64", bpf_target_arch = "riscv64")))]
+#[cfg(any(
+    bpf_target_arch = "x86_64",
+    bpf_target_arch = "arm",
+    bpf_target_arch = "powerpc64"
+))]
 use crate::bindings::pt_regs;
-#[cfg(bpf_target_arch = "aarch64")]
+// aarch64 uses user_pt_regs instead of pt_regs
+#[cfg(any(bpf_target_arch = "aarch64", bpf_target_arch = "s390x"))]
 use crate::bindings::user_pt_regs as pt_regs;
+// riscv64 uses user_regs_struct instead of pt_regs
 #[cfg(bpf_target_arch = "riscv64")]
 use crate::bindings::user_regs_struct as pt_regs;
 use crate::{cty::c_void, helpers::bpf_probe_read};
@@ -168,6 +173,36 @@ impl<T> FromPtRegs for *const T {
     }
 }
 
+#[cfg(bpf_target_arch = "powerpc64")]
+impl<T> FromPtRegs for *const T {
+    fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
+        if n <= 7 {
+            unsafe { bpf_probe_read(&ctx.gpr[3 + n]).map(|v| v as *const _).ok() }
+        } else {
+            None
+        }
+    }
+
+    fn from_retval(ctx: &pt_regs) -> Option<Self> {
+        unsafe { bpf_probe_read(&ctx.gpr[3]).map(|v| v as *const _).ok() }
+    }
+}
+
+#[cfg(bpf_target_arch = "s390x")]
+impl<T> FromPtRegs for *const T {
+    fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
+        if n <= 4 {
+            unsafe { bpf_probe_read(&ctx.gprs[2 + n]).map(|v| v as *const _).ok() }
+        } else {
+            None
+        }
+    }
+
+    fn from_retval(ctx: &pt_regs) -> Option<Self> {
+        unsafe { bpf_probe_read(&ctx.gprs[2]).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> {
@@ -238,6 +273,36 @@ impl<T> FromPtRegs for *mut T {
     }
 }
 
+#[cfg(bpf_target_arch = "powerpc64")]
+impl<T> FromPtRegs for *mut T {
+    fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
+        if n <= 7 {
+            unsafe { bpf_probe_read(&ctx.gpr[3 + n]).map(|v| v as *mut _).ok() }
+        } else {
+            None
+        }
+    }
+
+    fn from_retval(ctx: &pt_regs) -> Option<Self> {
+        unsafe { bpf_probe_read(&ctx.gpr[3]).map(|v| v as *mut _).ok() }
+    }
+}
+
+#[cfg(bpf_target_arch = "s390x")]
+impl<T> FromPtRegs for *mut T {
+    fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
+        if n <= 4 {
+            unsafe { bpf_probe_read(&ctx.gprs[2 + n]).map(|v| v as *mut _).ok() }
+        } else {
+            None
+        }
+    }
+
+    fn from_retval(ctx: &pt_regs) -> Option<Self> {
+        unsafe { bpf_probe_read(&ctx.gprs[2]).map(|v| v as *mut _).ok() }
+    }
+}
+
 /// Helper macro to implement [`FromPtRegs`] for a primitive type.
 macro_rules! impl_from_pt_regs {
     ($type:ident) => {
@@ -310,6 +375,36 @@ macro_rules! impl_from_pt_regs {
                 Some(ctx.ra as *const $type as _)
             }
         }
+
+        #[cfg(bpf_target_arch = "powerpc64")]
+        impl FromPtRegs for $type {
+            fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
+                if n <= 7 {
+                    Some(ctx.gpr[3 + n] as *const $type as _)
+                } else {
+                    None
+                }
+            }
+
+            fn from_retval(ctx: &pt_regs) -> Option<Self> {
+                Some(ctx.gpr[3] as *const $type as _)
+            }
+        }
+
+        #[cfg(bpf_target_arch = "s390x")]
+        impl FromPtRegs for $type {
+            fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
+                if n <= 4 {
+                    Some(ctx.gprs[2 + n] as *const $type as _)
+                } else {
+                    None
+                }
+            }
+
+            fn from_retval(ctx: &pt_regs) -> Option<Self> {
+                Some(ctx.gprs[2] as *const $type as _)
+            }
+        }
     };
 }
 

+ 8 - 2
ebpf/aya-ebpf/src/programs/probe.rs

@@ -1,9 +1,15 @@
 use core::ffi::c_void;
 
-#[cfg(not(any(bpf_target_arch = "aarch64", bpf_target_arch = "riscv64")))]
+#[cfg(any(
+    bpf_target_arch = "x86_64",
+    bpf_target_arch = "arm",
+    bpf_target_arch = "powerpc64"
+))]
 use crate::bindings::pt_regs;
-#[cfg(bpf_target_arch = "aarch64")]
+// aarch64 uses user_pt_regs instead of pt_regs
+#[cfg(any(bpf_target_arch = "aarch64", bpf_target_arch = "s390x"))]
 use crate::bindings::user_pt_regs as pt_regs;
+// riscv64 uses user_regs_struct instead of pt_regs
 #[cfg(bpf_target_arch = "riscv64")]
 use crate::bindings::user_regs_struct as pt_regs;
 use crate::{args::FromPtRegs, EbpfContext};

+ 8 - 2
ebpf/aya-ebpf/src/programs/retprobe.rs

@@ -1,9 +1,15 @@
 use core::ffi::c_void;
 
-#[cfg(not(any(bpf_target_arch = "aarch64", bpf_target_arch = "riscv64")))]
+#[cfg(any(
+    bpf_target_arch = "x86_64",
+    bpf_target_arch = "arm",
+    bpf_target_arch = "powerpc64"
+))]
 use crate::bindings::pt_regs;
-#[cfg(bpf_target_arch = "aarch64")]
+// aarch64 uses user_pt_regs instead of pt_regs
+#[cfg(any(bpf_target_arch = "aarch64", bpf_target_arch = "s390x"))]
 use crate::bindings::user_pt_regs as pt_regs;
+// riscv64 uses user_regs_struct instead of pt_regs
 #[cfg(bpf_target_arch = "riscv64")]
 use crate::bindings::user_regs_struct as pt_regs;
 use crate::{args::FromPtRegs, EbpfContext};