1use crate::memory::{BitFlip, Checkable, ConsecBlocks, DataPattern, Initializable};
2use crate::victim::VictimOrchestrator;
3use log::debug;
4use serde::Serialize;
5use std::arch::x86_64::_mm_clflush;
6
7use crate::victim::{HammerVictimError, VictimResult};
8
9#[derive(Clone)]
14pub struct ExcludeFromInit(Vec<*const u8>);
15
16#[derive(Serialize)]
21pub struct MemCheck {
22 #[serde(skip_serializing)]
23 memory: ConsecBlocks,
24 pub pattern: DataPattern,
26 #[serde(skip_serializing)]
27 excluding: ExcludeFromInit,
28}
29
30impl MemCheck {
31 pub fn new(memory: ConsecBlocks, pattern: DataPattern, excluding: ExcludeFromInit) -> Self {
39 Self {
40 memory,
41 pattern,
42 excluding,
43 }
44 }
45}
46
47impl VictimOrchestrator for MemCheck {
48 fn start(&mut self) -> Result<(), HammerVictimError> {
49 Ok(())
50 }
51
52 fn init(&mut self) {
53 debug!("initialize victim");
54 self.memory
55 .initialize_excluding(self.pattern.clone(), &self.excluding.0);
56 }
57
58 fn check(&mut self) -> Result<VictimResult, HammerVictimError> {
59 debug!("check victim");
60 let flips = self
61 .memory
62 .check_excluding(self.pattern.clone(), &self.excluding.0);
63 if !flips.is_empty() {
64 Ok(VictimResult::BitFlips(flips.clone()))
65 } else {
66 Err(HammerVictimError::NoFlips)
67 }
68 }
69
70 fn stop(&mut self) {}
71}
72
73#[derive(Serialize)]
78pub struct HammerVictimTargetCheck {
79 #[serde(skip_serializing)]
80 memory: ConsecBlocks,
81 pattern: DataPattern,
82 targets: Vec<BitFlip>,
83}
84
85impl HammerVictimTargetCheck {
86 pub fn new(memory: ConsecBlocks, pattern: DataPattern, targets: Vec<BitFlip>) -> Self {
94 HammerVictimTargetCheck {
95 memory,
96 pattern,
97 targets,
98 }
99 }
100}
101
102impl VictimOrchestrator for HammerVictimTargetCheck {
103 fn start(&mut self) -> Result<(), HammerVictimError> {
104 Ok(())
105 }
106
107 fn init(&mut self) {
108 debug!("initialize victim");
109 self.memory.initialize(self.pattern.clone());
110 }
111
112 fn check(&mut self) -> Result<VictimResult, HammerVictimError> {
113 debug!("check victim");
114 let mut flips = vec![];
115 for target in &self.targets {
116 let value = unsafe {
117 _mm_clflush(target.addr as *const u8);
118 std::ptr::read_volatile(target.addr as *const u8)
119 };
120 if value != target.data {
121 let bitmask = target.data ^ value;
122 flips.push(BitFlip::new(target.addr as *const u8, bitmask, target.data))
123 }
124 }
125 if !flips.is_empty() {
126 Ok(VictimResult::BitFlips(flips))
127 } else {
128 Err(HammerVictimError::NoFlips)
129 }
130 }
131
132 fn stop(&mut self) {}
133}
134
135impl From<Vec<*const u8>> for ExcludeFromInit {
136 fn from(value: Vec<*const u8>) -> Self {
137 ExcludeFromInit(value)
138 }
139}