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};
9use starnix_sync::{EbpfStateLock, Locked};
10use starnix_uapi::{gid_t, pid_t, uid_t};
11
12enum SuspendLockState<'a> {
13    NotLocked(&'a mut Locked<EbpfStateLock>),
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(locked: &'a mut Locked<EbpfStateLock>, current_task: &'a CurrentTask) -> Self {
30        Self {
31            current_task,
32            suspend_lock_state: SuspendLockState::NotLocked(locked),
33            map_refs: vec![],
34        }
35    }
36}
37
38impl<'a> MapsContext<'a> for EbpfRunContextImpl<'a> {
39    fn on_map_access(&mut self, map: &Map) {
40        if map.uses_locks() && matches!(self.suspend_lock_state, SuspendLockState::NotLocked(_)) {
41            replace_with::replace_with(&mut self.suspend_lock_state, |state| {
42                let SuspendLockState::NotLocked(locked) = state else { unreachable!() };
43                SuspendLockState::Locked(
44                    self.current_task
45                        .kernel()
46                        .suspend_resume_manager
47                        .acquire_ebpf_suspend_lock(locked),
48                )
49            });
50        }
51    }
52
53    fn add_value_ref(&mut self, map_ref: MapValueRef<'a>) {
54        self.map_refs.push(map_ref)
55    }
56}
57
58impl<'a> CurrentTaskContext for EbpfRunContextImpl<'a> {
59    fn get_uid_gid(&self) -> (uid_t, gid_t) {
60        let creds = self.current_task.current_creds();
61        (creds.uid, creds.gid)
62    }
63
64    fn get_tid_tgid(&self) -> (pid_t, pid_t) {
65        let task = &self.current_task.task;
66        (task.get_tid(), task.get_pid())
67    }
68}
69
70impl<'a> BpfSockContext for EbpfRunContextImpl<'a> {
71    type BpfSockRef = &'a BpfSock<'a>;
72}