use core::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use crate::structures::paging::page_table::PHYSICAL_ADDRESS_MASK;
use crate::structures::paging::PageTableFlags;
pub(crate) static ENC_BIT_MASK: AtomicU64 = AtomicU64::new(0);
static ENC_BIT_REVERSED: AtomicBool = AtomicBool::new(false);
#[derive(Debug)]
pub enum MemoryEncryptionConfiguration {
EncryptedBit(u8),
SharedBit(u8),
}
pub unsafe fn enable_memory_encryption(configuration: MemoryEncryptionConfiguration) {
let (bit_position, reversed) = match configuration {
MemoryEncryptionConfiguration::EncryptedBit(pos) => (pos, false),
MemoryEncryptionConfiguration::SharedBit(pos) => (pos, true),
};
let c_bit_mask = 1u64 << bit_position;
PHYSICAL_ADDRESS_MASK.fetch_and(!c_bit_mask, Ordering::Relaxed);
ENC_BIT_MASK.store(c_bit_mask, Ordering::Relaxed);
ENC_BIT_REVERSED.store(reversed, Ordering::Release);
}
impl PageTableFlags {
#[inline]
fn enc_bit_flag() -> Option<PageTableFlags> {
let bit_mask = ENC_BIT_MASK.load(Ordering::Relaxed);
if bit_mask > 0 {
Some(PageTableFlags::from_bits_retain(bit_mask))
} else {
None
}
}
pub fn set_encrypted(&mut self, encrypted: bool) {
let flag = Self::enc_bit_flag().expect("memory encryption is not enabled");
self.set(flag, encrypted ^ ENC_BIT_REVERSED.load(Ordering::Relaxed));
}
pub fn is_encrypted(&self) -> bool {
if let Some(c_bit_flag) = Self::enc_bit_flag() {
self.contains(c_bit_flag) ^ ENC_BIT_REVERSED.load(Ordering::Relaxed)
} else {
false
}
}
}