Add the first attempt at detectecting prefetch
This commit is contained in:
parent
f5312321c8
commit
2ce9de1482
@ -10,32 +10,37 @@ use core::cmp::min;
|
|||||||
// this will require getting a nice page to do some amusing stuff on it.
|
// this will require getting a nice page to do some amusing stuff on it.
|
||||||
// it will have to return some results later.
|
// it will have to return some results later.
|
||||||
|
|
||||||
unsafe fn only_reload(p: *const u8) -> u64 {
|
pub unsafe fn only_reload(p: *const u8) -> u64 {
|
||||||
let t = rdtsc_fence();
|
let t = rdtsc_fence();
|
||||||
maccess(p);
|
maccess(p);
|
||||||
rdtsc_fence() - t
|
rdtsc_fence() - t
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn flush_and_reload(p: *const u8) -> u64 {
|
pub unsafe fn flush_and_reload(p: *const u8) -> u64 {
|
||||||
flush(p);
|
flush(p);
|
||||||
let t = rdtsc_fence();
|
let t = rdtsc_fence();
|
||||||
maccess(p);
|
maccess(p);
|
||||||
rdtsc_fence() - t
|
rdtsc_fence() - t
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn load_and_flush(p: *const u8) -> u64 {
|
pub unsafe fn load_and_flush(p: *const u8) -> u64 {
|
||||||
maccess(p);
|
maccess(p);
|
||||||
let t = rdtsc_fence();
|
let t = rdtsc_fence();
|
||||||
flush(p);
|
flush(p);
|
||||||
rdtsc_fence() - t
|
rdtsc_fence() - t
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn flush_and_flush(p: *const u8) -> u64 {
|
pub unsafe fn flush_and_flush(p: *const u8) -> u64 {
|
||||||
flush(p);
|
flush(p);
|
||||||
let t = rdtsc_fence();
|
let t = rdtsc_fence();
|
||||||
flush(p);
|
flush(p);
|
||||||
rdtsc_fence() - t
|
rdtsc_fence() - t
|
||||||
}
|
}
|
||||||
|
pub unsafe fn only_flush(p: *const u8) -> u64 {
|
||||||
|
let t = rdtsc_fence();
|
||||||
|
flush(p);
|
||||||
|
rdtsc_fence() - t
|
||||||
|
}
|
||||||
|
|
||||||
const BUCKET_SIZE: usize = 5;
|
const BUCKET_SIZE: usize = 5;
|
||||||
const BUCKET_NUMBER: usize = 250;
|
const BUCKET_NUMBER: usize = 250;
|
||||||
|
@ -1,7 +1,17 @@
|
|||||||
use x86_64::registers::model_specific::Msr;
|
use x86_64::registers::model_specific::Msr;
|
||||||
|
|
||||||
|
use crate::calibration::only_flush;
|
||||||
|
use crate::flush;
|
||||||
|
use crate::maccess;
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
use alloc::vec;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
const MSR_MISC_FEATURE8CONTROL: u32 = 0x1a4;
|
const MSR_MISC_FEATURE8CONTROL: u32 = 0x1a4;
|
||||||
|
|
||||||
|
const N: i32 = 10;
|
||||||
|
|
||||||
pub fn prefetcher_status() -> bool {
|
pub fn prefetcher_status() -> bool {
|
||||||
let msr = Msr::new(MSR_MISC_FEATURE8CONTROL);
|
let msr = Msr::new(MSR_MISC_FEATURE8CONTROL);
|
||||||
let value = unsafe { msr.read() };
|
let value = unsafe { msr.read() };
|
||||||
@ -17,3 +27,21 @@ pub fn enable_prefetchers(status: bool) {
|
|||||||
}
|
}
|
||||||
unsafe { msr.write(value) };
|
unsafe { msr.write(value) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prefetcher_fun(victim4kaddr: *mut u8, victim2Maddr: *mut u8, threshold_ff: u64) -> Vec<i32> {
|
||||||
|
let mut results = vec![0; 4096 / 64];
|
||||||
|
|
||||||
|
for _ in 0..N {
|
||||||
|
//unsafe { maccess(victim4kaddr) };
|
||||||
|
for j in (0..4096).step_by(64).rev() {
|
||||||
|
let t = unsafe { only_flush(victim4kaddr.offset(j)) };
|
||||||
|
if threshold_ff < t {
|
||||||
|
// hit
|
||||||
|
results[(j / 64) as usize] += 1;
|
||||||
|
} else if threshold_ff > t {
|
||||||
|
results[(j / 64) as usize] -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
results
|
||||||
|
}
|
||||||
|
39
src/main.rs
39
src/main.rs
@ -22,12 +22,14 @@ use dendrobates_tinctoreus_azureus::hlt_loop;
|
|||||||
|
|
||||||
use bootloader::bootinfo::MemoryRegionType::{InUse, Usable};
|
use bootloader::bootinfo::MemoryRegionType::{InUse, Usable};
|
||||||
use bootloader::bootinfo::{FrameRange, MemoryMap, MemoryRegion};
|
use bootloader::bootinfo::{FrameRange, MemoryMap, MemoryRegion};
|
||||||
|
use cache_utils::maccess;
|
||||||
|
use cache_utils::prefetcher::{enable_prefetchers, prefetcher_fun};
|
||||||
use dendrobates_tinctoreus_azureus::memory;
|
use dendrobates_tinctoreus_azureus::memory;
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use vga_buffer::{set_colors, Color, ForegroundColor};
|
use vga_buffer::{set_colors, Color, ForegroundColor};
|
||||||
use x86_64::structures::paging::frame::PhysFrameRange;
|
use x86_64::structures::paging::frame::PhysFrameRange;
|
||||||
use x86_64::structures::paging::{
|
use x86_64::structures::paging::{
|
||||||
Mapper, Page, PageSize, PageTableFlags, PhysFrame, Size4KiB, UnusedPhysFrame,
|
Mapper, MapperAllSizes, Page, PageSize, PageTableFlags, PhysFrame, Size4KiB, UnusedPhysFrame,
|
||||||
};
|
};
|
||||||
use x86_64::PhysAddr;
|
use x86_64::PhysAddr;
|
||||||
use x86_64::VirtAddr;
|
use x86_64::VirtAddr;
|
||||||
@ -51,6 +53,8 @@ fn distance<T: Sub<Output = T> + Ord>(a: T, b: T) -> T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const victim4k_start: u64 = 0x0ccc_0000_0000_u64;
|
||||||
|
const victim4k_end: u64 = victim4k_start + (1 << 21);
|
||||||
entry_point!(kernel_main);
|
entry_point!(kernel_main);
|
||||||
|
|
||||||
// Kernel entry point
|
// Kernel entry point
|
||||||
@ -75,6 +79,9 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
|||||||
let mut victim = None;
|
let mut victim = None;
|
||||||
|
|
||||||
for region in boot_info.memory_map.iter() {
|
for region in boot_info.memory_map.iter() {
|
||||||
|
if region.region_type == Usable {
|
||||||
|
serial_println!("Usable Region: {:?}", region);
|
||||||
|
}
|
||||||
let new_region = {
|
let new_region = {
|
||||||
if victim.is_none()
|
if victim.is_none()
|
||||||
&& region.region_type == Usable
|
&& region.region_type == Usable
|
||||||
@ -157,13 +164,14 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
|||||||
serial_println!("{:?} -> {:?}", virt, phys);
|
serial_println!("{:?} -> {:?}", virt, phys);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
for (page, frame) in (0xcccc_0000_0000_u64..0xcccc_0020_0000)
|
for (page, frame) in (victim4k_start..victim4k_end)
|
||||||
.step_by(Size4KiB::SIZE as usize)
|
.step_by(Size4KiB::SIZE as usize)
|
||||||
.zip(PhysFrameRange {
|
.zip(PhysFrameRange {
|
||||||
start: PhysFrame::containing_address(PhysAddr::new(victim.range.start_addr())),
|
start: PhysFrame::containing_address(PhysAddr::new(victim.range.start_addr())),
|
||||||
end: PhysFrame::containing_address(PhysAddr::new(victim.range.end_addr())),
|
end: PhysFrame::containing_address(PhysAddr::new(victim.range.end_addr())),
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
serial_println!("Mapping page {:x} on frame {:?}", page, frame);
|
||||||
mapper
|
mapper
|
||||||
.map_to(
|
.map_to(
|
||||||
Page::<Size4KiB>::containing_address(VirtAddr::new(page)),
|
Page::<Size4KiB>::containing_address(VirtAddr::new(page)),
|
||||||
@ -173,6 +181,15 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
|||||||
)
|
)
|
||||||
.expect("Failed to map the experiment buffer")
|
.expect("Failed to map the experiment buffer")
|
||||||
.flush();
|
.flush();
|
||||||
|
let phys = mapper.translate_addr(VirtAddr::new(page));
|
||||||
|
serial_println!(
|
||||||
|
"Mapped page {:p}({:?}) on frame {:?}",
|
||||||
|
page as *mut u8,
|
||||||
|
VirtAddr::new(page),
|
||||||
|
phys
|
||||||
|
);
|
||||||
|
|
||||||
|
unsafe { maccess(page as *mut u8) };
|
||||||
}
|
}
|
||||||
|
|
||||||
allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed");
|
allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed");
|
||||||
@ -202,6 +219,24 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
|||||||
panic!("Inconsistent thresholds");
|
panic!("Inconsistent thresholds");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serial_println!("0");
|
||||||
|
let r_no_prefetch = prefetcher_fun(
|
||||||
|
victim4k_start as *mut u8,
|
||||||
|
unsafe { (victim.range.start_addr() as *mut u8).offset(phys_mem_offset.as_u64() as isize) },
|
||||||
|
threshold_flush,
|
||||||
|
);
|
||||||
|
serial_println!("1");
|
||||||
|
enable_prefetchers(true);
|
||||||
|
let r_prefetch = prefetcher_fun(
|
||||||
|
victim4k_start as *mut u8,
|
||||||
|
unsafe { (victim.range.start_addr() as *mut u8).offset(phys_mem_offset.as_u64() as isize) },
|
||||||
|
threshold_flush,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (i, (&npf, pf)) in r_no_prefetch.iter().zip(r_prefetch).enumerate() {
|
||||||
|
serial_println!("{} {} {}", i, npf, pf);
|
||||||
|
}
|
||||||
|
|
||||||
// Calibration
|
// Calibration
|
||||||
// disable pretechers
|
// disable pretechers
|
||||||
// Calibrate hit / miss rdtsc threshold
|
// Calibrate hit / miss rdtsc threshold
|
||||||
|
Loading…
Reference in New Issue
Block a user