linux-imx/drivers/android/binder/defs.rs
Alice Ryhl 6249f06992 ANDROID: rust_binder: add TF_UPDATE_TXN support
When a process is frozen, incoming oneway transactions are held in a
queue until the process is unfrozen. If many oneway transactions are
sent, then the process could run out of space for them. This patch adds
a flag that avoids this by replacing previous oneway transactions in the
queue to avoid having transactions of the same type build up. This can
be useful when only the most recent transaction is necessary.

Link: https://lore.kernel.org/rust-for-linux/20231101-rust-binder-v1-16-08ba9197f637@google.com/
Change-Id: I2f99cc54a065c0eef60324e860610b562e910a8d
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Bug: 278052745
2024-02-19 13:02:28 +00:00

176 lines
5.0 KiB
Rust

// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2024 Google LLC.
use core::mem::MaybeUninit;
use core::ops::{Deref, DerefMut};
use kernel::{
bindings::{self, *},
types::{AsBytes, FromBytes},
};
macro_rules! pub_no_prefix {
($prefix:ident, $($newname:ident),+) => {
$(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+
};
}
pub_no_prefix!(
binder_driver_return_protocol_,
BR_TRANSACTION,
BR_TRANSACTION_SEC_CTX,
BR_REPLY,
BR_DEAD_REPLY,
BR_FAILED_REPLY,
BR_FROZEN_REPLY,
BR_NOOP,
BR_SPAWN_LOOPER,
BR_TRANSACTION_COMPLETE,
BR_OK,
BR_ERROR,
BR_INCREFS,
BR_ACQUIRE,
BR_RELEASE,
BR_DECREFS,
BR_DEAD_BINDER,
BR_CLEAR_DEATH_NOTIFICATION_DONE
);
pub_no_prefix!(
binder_driver_command_protocol_,
BC_TRANSACTION,
BC_TRANSACTION_SG,
BC_REPLY,
BC_REPLY_SG,
BC_FREE_BUFFER,
BC_ENTER_LOOPER,
BC_EXIT_LOOPER,
BC_REGISTER_LOOPER,
BC_INCREFS,
BC_ACQUIRE,
BC_RELEASE,
BC_DECREFS,
BC_INCREFS_DONE,
BC_ACQUIRE_DONE,
BC_REQUEST_DEATH_NOTIFICATION,
BC_CLEAR_DEATH_NOTIFICATION,
BC_DEAD_BINDER_DONE
);
pub_no_prefix!(
flat_binder_object_flags_,
FLAT_BINDER_FLAG_ACCEPTS_FDS,
FLAT_BINDER_FLAG_TXN_SECURITY_CTX
);
pub_no_prefix!(
transaction_flags_,
TF_ONE_WAY,
TF_ACCEPT_FDS,
TF_CLEAR_BUF,
TF_UPDATE_TXN
);
pub(crate) use bindings::{
BINDER_TYPE_BINDER, BINDER_TYPE_FD, BINDER_TYPE_FDA, BINDER_TYPE_HANDLE, BINDER_TYPE_PTR,
BINDER_TYPE_WEAK_BINDER, BINDER_TYPE_WEAK_HANDLE,
};
macro_rules! decl_wrapper {
($newname:ident, $wrapped:ty) => {
// Define a wrapper around the C type. Use `MaybeUninit` to enforce that the value of
// padding bytes must be preserved.
#[derive(Copy, Clone)]
#[repr(transparent)]
pub(crate) struct $newname(MaybeUninit<$wrapped>);
// SAFETY: This macro is only used with types where this is ok.
unsafe impl FromBytes for $newname {}
unsafe impl AsBytes for $newname {}
impl Deref for $newname {
type Target = $wrapped;
fn deref(&self) -> &Self::Target {
// SAFETY: We use `MaybeUninit` only to preserve padding. The value must still
// always be valid.
unsafe { self.0.assume_init_ref() }
}
}
impl DerefMut for $newname {
fn deref_mut(&mut self) -> &mut Self::Target {
// SAFETY: We use `MaybeUninit` only to preserve padding. The value must still
// always be valid.
unsafe { self.0.assume_init_mut() }
}
}
impl Default for $newname {
fn default() -> Self {
// Create a new value of this type where all bytes (including padding) are zeroed.
Self(MaybeUninit::zeroed())
}
}
};
}
decl_wrapper!(BinderNodeDebugInfo, bindings::binder_node_debug_info);
decl_wrapper!(BinderNodeInfoForRef, bindings::binder_node_info_for_ref);
decl_wrapper!(FlatBinderObject, bindings::flat_binder_object);
decl_wrapper!(BinderFdObject, bindings::binder_fd_object);
decl_wrapper!(BinderFdArrayObject, bindings::binder_fd_array_object);
decl_wrapper!(BinderObjectHeader, bindings::binder_object_header);
decl_wrapper!(BinderBufferObject, bindings::binder_buffer_object);
decl_wrapper!(BinderTransactionData, bindings::binder_transaction_data);
decl_wrapper!(
BinderTransactionDataSecctx,
bindings::binder_transaction_data_secctx
);
decl_wrapper!(
BinderTransactionDataSg,
bindings::binder_transaction_data_sg
);
decl_wrapper!(BinderWriteRead, bindings::binder_write_read);
decl_wrapper!(BinderVersion, bindings::binder_version);
decl_wrapper!(BinderFrozenStatusInfo, bindings::binder_frozen_status_info);
decl_wrapper!(BinderFreezeInfo, bindings::binder_freeze_info);
decl_wrapper!(ExtendedError, bindings::binder_extended_error);
impl BinderVersion {
pub(crate) fn current() -> Self {
Self(MaybeUninit::new(bindings::binder_version {
protocol_version: bindings::BINDER_CURRENT_PROTOCOL_VERSION as _,
}))
}
}
impl BinderTransactionData {
pub(crate) fn with_buffers_size(self, buffers_size: u64) -> BinderTransactionDataSg {
BinderTransactionDataSg(MaybeUninit::new(bindings::binder_transaction_data_sg {
transaction_data: *self,
buffers_size,
}))
}
}
impl BinderTransactionDataSecctx {
/// View the inner data as wrapped in `BinderTransactionData`.
pub(crate) fn tr_data(&mut self) -> &mut BinderTransactionData {
// SAFETY: Transparent wrapper is safe to transmute.
unsafe {
&mut *(&mut self.transaction_data as *mut bindings::binder_transaction_data
as *mut BinderTransactionData)
}
}
}
impl ExtendedError {
pub(crate) fn new(id: u32, command: u32, param: i32) -> Self {
Self(MaybeUninit::new(bindings::binder_extended_error {
id,
command,
param,
}))
}
}