projects/linux·blob master · refs

107 lines · 3.4 KiB

1// SPDX-License-Identifier: GPL-2.0
2
3// Copyright (C) 2025 Google LLC.
4
5use crate::transaction::Transaction;
6
7use core::ptr;
8
9use kernel::bindings::{rust_binder_transaction, task_struct};
10use kernel::error::Result;
11use kernel::ffi::{c_int, c_uint, c_ulong};
12use kernel::task::Task;
13use kernel::tracepoint::declare_trace;
14
15declare_trace! {
16 unsafe fn binder_ioctl(cmd: c_uint, arg: c_ulong);
17 unsafe fn binder_ioctl_done(ret: c_int);
18 unsafe fn binder_read_done(ret: c_int);
19 unsafe fn binder_write_done(ret: c_int);
20 unsafe fn binder_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool);
21 unsafe fn binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct);
22 unsafe fn binder_transaction_received(t: rust_binder_transaction);
23 unsafe fn binder_transaction_fd_send(t_debug_id: c_int, fd: c_int, offset: usize);
24 unsafe fn binder_transaction_fd_recv(t_debug_id: c_int, fd: c_int, offset: usize);
25 unsafe fn binder_command(cmd: u32);
26 unsafe fn binder_return(ret: u32);
27}
28
29#[inline]
30fn raw_transaction(t: &Transaction) -> rust_binder_transaction {
31 ptr::from_ref(t).cast_mut().cast()
32}
33
34#[inline]
35fn to_errno(ret: Result) -> i32 {
36 match ret {
37 Ok(()) => 0,
38 Err(err) => err.to_errno(),
39 }
40}
41
42#[inline]
43pub(crate) fn trace_ioctl(cmd: u32, arg: usize) {
44 // SAFETY: Always safe to call.
45 unsafe { binder_ioctl(cmd, arg as c_ulong) }
46}
47
48#[inline]
49pub(crate) fn trace_ioctl_done(ret: Result) {
50 // SAFETY: Always safe to call.
51 unsafe { binder_ioctl_done(to_errno(ret)) }
52}
53#[inline]
54pub(crate) fn trace_read_done(ret: Result) {
55 // SAFETY: Always safe to call.
56 unsafe { binder_read_done(to_errno(ret)) }
57}
58#[inline]
59pub(crate) fn trace_write_done(ret: Result) {
60 // SAFETY: Always safe to call.
61 unsafe { binder_write_done(to_errno(ret)) }
62}
63
64#[inline]
65pub(crate) fn trace_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool) {
66 // SAFETY: Always safe to call.
67 unsafe { binder_wait_for_work(proc_work, transaction_stack, thread_todo) }
68}
69
70#[inline]
71pub(crate) fn trace_transaction(reply: bool, t: &Transaction, thread: Option<&Task>) {
72 let thread = match thread {
73 Some(thread) => thread.as_ptr(),
74 None => core::ptr::null_mut(),
75 };
76 // SAFETY: The raw transaction is valid for the duration of this call. The thread pointer is
77 // valid or null.
78 unsafe { binder_transaction(reply, raw_transaction(t), thread) }
79}
80
81#[inline]
82pub(crate) fn trace_transaction_received(t: &Transaction) {
83 // SAFETY: The raw transaction is valid for the duration of this call.
84 unsafe { binder_transaction_received(raw_transaction(t)) }
85}
86
87#[inline]
88pub(crate) fn trace_transaction_fd_send(t_debug_id: usize, fd: u32, offset: usize) {
89 // SAFETY: This function is always safe to call.
90 unsafe { binder_transaction_fd_send(t_debug_id as c_int, fd as c_int, offset) }
91}
92#[inline]
93pub(crate) fn trace_transaction_fd_recv(t_debug_id: usize, fd: u32, offset: usize) {
94 // SAFETY: This function is always safe to call.
95 unsafe { binder_transaction_fd_recv(t_debug_id as c_int, fd as c_int, offset) }
96}
97
98#[inline]
99pub(crate) fn trace_command(cmd: u32) {
100 // SAFETY: This function is always safe to call.
101 unsafe { binder_command(cmd) }
102}
103#[inline]
104pub(crate) fn trace_return(ret: u32) {
105 // SAFETY: This function is always safe to call.
106 unsafe { binder_return(ret) }
107}