Skip to main content

starnix_core/bpf/
context.rs

1// Copyright 2025 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::bpf::attachments::BpfSock;
6use crate::power::EbpfSuspendGuard;
7use crate::task::CurrentTask;
8use ebpf_api::{BpfSockContext, CurrentTaskContext, Map, MapValueRef, MapsContext};
9
10use starnix_uapi::{gid_t, pid_t, uid_t};
11
12enum SuspendLockState<'a> {
13    NotLocked(),
14
15    #[allow(dead_code)]
16    Locked(EbpfSuspendGuard<'a>),
17}
18
19pub struct EbpfRunContextImpl<'a> {
20    current_task: &'a CurrentTask,
21
22    // Must precede `map_refs` to ensure it's dropped after `base`.
23    suspend_lock_state: SuspendLockState<'a>,
24
25    map_refs: Vec<MapValueRef<'a>>,
26}
27
28impl<'a> EbpfRunContextImpl<'a> {
29    pub fn new(current_task: &'a CurrentTask) -> Self {
30        Self { current_task, suspend_lock_state: SuspendLockState::NotLocked(), map_refs: vec![] }
31    }
32}
33
34impl<'a> MapsContext<'a> for EbpfRunContextImpl<'a> {
35    fn on_map_access(&mut self, map: &Map) {
36        if map.uses_locks() && matches!(self.suspend_lock_state, SuspendLockState::NotLocked()) {
37            replace_with::replace_with(&mut self.suspend_lock_state, |state| {
38                let SuspendLockState::NotLocked() = state else { unreachable!() };
39                SuspendLockState::Locked(
40                    self.current_task.kernel().suspend_resume_manager.acquire_ebpf_suspend_lock(),
41                )
42            });
43        }
44    }
45
46    fn add_value_ref(&mut self, map_ref: MapValueRef<'a>) {
47        self.map_refs.push(map_ref)
48    }
49}
50
51impl<'a> CurrentTaskContext for EbpfRunContextImpl<'a> {
52    fn get_uid_gid(&self) -> (uid_t, gid_t) {
53        let creds = self.current_task.current_creds();
54        (creds.uid, creds.gid)
55    }
56
57    fn get_tid_tgid(&self) -> (pid_t, pid_t) {
58        let task = &self.current_task.task;
59        (task.get_tid(), task.get_pid())
60    }
61}
62
63impl<'a> BpfSockContext for EbpfRunContextImpl<'a> {
64    type BpfSockRef = &'a BpfSock<'a>;
65}