vmi_utils/bpm/controller/
memory.rs

1use vmi_core::{
2    Gfn, MemoryAccess, Pa, View, VmiCore, VmiDriver, VmiError, VmiEvent,
3    arch::{Architecture as _, EventMemoryAccess as _, EventReason as _},
4};
5
6use super::TapController;
7
8#[doc = include_str!("memory.md")]
9pub struct MemoryController<Driver>
10where
11    Driver: VmiDriver,
12{
13    _marker: std::marker::PhantomData<Driver>,
14}
15
16impl<Driver> TapController for MemoryController<Driver>
17where
18    Driver: VmiDriver,
19{
20    type Driver = Driver;
21
22    fn new() -> Self {
23        Self {
24            _marker: std::marker::PhantomData,
25        }
26    }
27
28    fn check_event(&self, event: &VmiEvent<Driver::Architecture>) -> Option<(View, Gfn)> {
29        let memory_access = event.reason().as_memory_access()?;
30
31        if !memory_access.access().contains(MemoryAccess::X) {
32            return None;
33        }
34
35        let view = event.view()?;
36
37        let gfn = Driver::Architecture::gfn_from_pa(memory_access.pa());
38        Some((view, gfn))
39    }
40
41    fn insert_breakpoint(
42        &mut self,
43        _vmi: &VmiCore<Driver>,
44        _pa: Pa,
45        _view: View,
46    ) -> Result<(), VmiError> {
47        Ok(())
48    }
49
50    fn remove_breakpoint(
51        &mut self,
52        _vmi: &VmiCore<Driver>,
53        _pa: Pa,
54        _view: View,
55    ) -> Result<(), VmiError> {
56        Ok(())
57    }
58
59    fn monitor(&mut self, vmi: &VmiCore<Driver>, gfn: Gfn, view: View) -> Result<(), VmiError> {
60        vmi.set_memory_access(gfn, view, MemoryAccess::RW)
61    }
62
63    fn unmonitor(&mut self, vmi: &VmiCore<Driver>, gfn: Gfn, view: View) -> Result<(), VmiError> {
64        vmi.set_memory_access(gfn, view, MemoryAccess::RWX)
65    }
66}