-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Memory channels #2
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,70 @@ | ||||||||||
use crate::{address::VirtAddr, mm::PAGE_SIZE, process_manager::process_memory::ALLOCATION_RANGE_VIRT_START}; | ||||||||||
|
||||||||||
use super::{allocation::AllocationRange, process::ProcessID, process_paging::ProcessPageTableRef}; | ||||||||||
|
||||||||||
pub const INPUT_VADDR: u64 = 0xFF0000000000u64; | ||||||||||
pub const OUTPUT_VADDR: u64 = 0xFF8000000000u64; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These exceed 48-bit virtual addresses. I suggest to use following instead
Suggested change
However, even with this change, I still cannot access input/output channels (it seems #PF) |
||||||||||
|
||||||||||
#[derive(Debug, Clone, Copy, Default)] | ||||||||||
pub struct MemoryChannel { | ||||||||||
pub input: AllocationRange, | ||||||||||
pub output: AllocationRange, | ||||||||||
pub owner: ProcessID, | ||||||||||
pub last_in_channel: bool, | ||||||||||
pub next: ProcessID, | ||||||||||
} | ||||||||||
|
||||||||||
impl MemoryChannel { | ||||||||||
|
||||||||||
pub fn allocate_input(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize) { | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
this works. allocate_range for the trustlets has some issuses |
||||||||||
self.input = self.allocate_range(page_table_ref, size, INPUT_VADDR); | ||||||||||
} | ||||||||||
|
||||||||||
pub fn allocate_output(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize) { | ||||||||||
self.output = self.allocate_range(page_table_ref, size, OUTPUT_VADDR); | ||||||||||
} | ||||||||||
|
||||||||||
pub fn inflate_input(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize) { | ||||||||||
let page_count = (size + PAGE_SIZE - (size % PAGE_SIZE)) / PAGE_SIZE; | ||||||||||
self.input.inflate(page_table_ref, page_count as u64, INPUT_VADDR); | ||||||||||
} | ||||||||||
|
||||||||||
pub fn inflate_output(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize) { | ||||||||||
let page_count = (size + PAGE_SIZE - (size % PAGE_SIZE)) / PAGE_SIZE; | ||||||||||
self.output.inflate(page_table_ref, page_count as u64, OUTPUT_VADDR); | ||||||||||
} | ||||||||||
|
||||||||||
pub fn copy_into(&mut self, source_addr: u64, page_table: u64, size: usize) { | ||||||||||
let copy_size = size + PAGE_SIZE - (size % PAGE_SIZE); | ||||||||||
let copy_page_count = copy_size / PAGE_SIZE; | ||||||||||
let target = VirtAddr::from(ALLOCATION_RANGE_VIRT_START); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||
|
||||||||||
let mut page_table_ref = ProcessPageTableRef::default(); | ||||||||||
page_table_ref.set_external_table(page_table); | ||||||||||
|
||||||||||
self.input.mount(); | ||||||||||
|
||||||||||
page_table_ref.copy_address_range(VirtAddr::from(source_addr), copy_size as u64, target); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In my understanding, this function is copying the guest input data to the input channel. For that I believe we need to copy the guest data first |
||||||||||
|
||||||||||
} | ||||||||||
|
||||||||||
pub fn copy_out(&mut self, target_addr: u64, page_table: u64, size: usize) { | ||||||||||
let copy_size = size + PAGE_SIZE - (size % PAGE_SIZE); | ||||||||||
let copy_page_count = copy_size / PAGE_SIZE; | ||||||||||
let target = VirtAddr::from(ALLOCATION_RANGE_VIRT_START); | ||||||||||
let mut page_table_ref = ProcessPageTableRef::default(); | ||||||||||
page_table_ref.set_external_table(page_table); | ||||||||||
|
||||||||||
self.output.mount(); | ||||||||||
|
||||||||||
page_table_ref.copy_address_range(VirtAddr::from(target), copy_size as u64, VirtAddr::from(target_addr)); | ||||||||||
} | ||||||||||
|
||||||||||
fn allocate_range(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize, start: u64) -> AllocationRange{ | ||||||||||
let mut r = AllocationRange::default(); | ||||||||||
let page_count = (size + PAGE_SIZE - (size % PAGE_SIZE)) / PAGE_SIZE; | ||||||||||
r.allocate_with_start_addr(page_table_ref, page_count as u64, start); | ||||||||||
return r; | ||||||||||
} | ||||||||||
|
||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -2,9 +2,11 @@ extern crate alloc; | |||||||
|
||||||||
use core::cell::UnsafeCell; | ||||||||
use alloc::vec::Vec; | ||||||||
use igvm_defs::PAGE_SIZE_4K; | ||||||||
use crate::address::PhysAddr; | ||||||||
use crate::cpu::percpu::this_cpu_shared; | ||||||||
use crate::cpu::percpu::this_cpu_unsafe; | ||||||||
use crate::mm::PAGE_SIZE; | ||||||||
use crate::mm::SVSM_PERCPU_VMSA_BASE; | ||||||||
use crate::process_manager::process_memory::allocate_page; | ||||||||
use crate::process_manager::allocation::AllocationRange; | ||||||||
|
@@ -25,6 +27,8 @@ use crate::vaddr_as_u64_slice; | |||||||
use cpuarch::vmsa::VMSA; | ||||||||
use core::mem::replace; | ||||||||
|
||||||||
use super::memory_channels::MemoryChannel; | ||||||||
|
||||||||
trait FromVAddr { | ||||||||
fn from_virt_addr(v: VirtAddr) -> &'static mut VMSA; | ||||||||
} | ||||||||
|
@@ -103,7 +107,7 @@ impl ProcessData { | |||||||
} | ||||||||
} | ||||||||
|
||||||||
#[derive(Clone,Copy,Debug)] | ||||||||
#[derive(Clone,Copy,Debug, Default)] | ||||||||
pub struct ProcessID(pub usize); | ||||||||
|
||||||||
#[derive(Clone,Copy,Debug)] | ||||||||
|
@@ -113,9 +117,7 @@ pub struct TrustedProcess { | |||||||
pub base: ProcessBaseContext, | ||||||||
#[allow(dead_code)] | ||||||||
pub context: ProcessContext, | ||||||||
/*input: VirtAddr, | ||||||||
output: VirtAddr, | ||||||||
pub hash: [u8; 32]i,*/ | ||||||||
//pub channel: MemoryChannel, | ||||||||
} | ||||||||
|
||||||||
impl TrustedProcess { | ||||||||
|
@@ -171,9 +173,14 @@ impl TrustedProcess { | |||||||
|
||||||||
} | ||||||||
|
||||||||
pub fn trustlet(parent: ProcessID, _data: u64, _size: u64, _pgt: u64) -> Self{ | ||||||||
pub fn trustlet(parent: ProcessID, data: u64, size: u64, pgt: u64) -> Self{ | ||||||||
// Inherit the data from the Zygote | ||||||||
let trustlet = TrustedProcess::dublicate(parent); | ||||||||
if data != 0 { | ||||||||
let (function_code, function_code_range) = ProcessPageTableRef::copy_data_from_guest(data, size, pgt); | ||||||||
trustlet.base.page_table_ref.add_function(function_code, size); | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
(I think |
||||||||
function_code_range.delete(); | ||||||||
} | ||||||||
trustlet | ||||||||
} | ||||||||
|
||||||||
|
@@ -346,6 +353,7 @@ impl ProcessBaseContext { | |||||||
pub struct ProcessContext { | ||||||||
pub base: ProcessBaseContext, | ||||||||
pub vmsa: PhysAddr, | ||||||||
pub channel: MemoryChannel, | ||||||||
pub sev_features: u64, | ||||||||
} | ||||||||
|
||||||||
|
@@ -354,6 +362,7 @@ impl Default for ProcessContext { | |||||||
return ProcessContext { | ||||||||
base: ProcessBaseContext::default(), | ||||||||
vmsa: PhysAddr::null(), | ||||||||
channel: MemoryChannel::default(), | ||||||||
sev_features: 0, | ||||||||
} | ||||||||
} | ||||||||
|
@@ -402,12 +411,26 @@ impl ProcessContext { | |||||||
panic!("Failed to create new VMSA"); | ||||||||
} | ||||||||
|
||||||||
|
||||||||
//Memory Channel setup -- No chain setup here | ||||||||
let page_table_addr = vmsa.cr3; | ||||||||
let mut pptr = ProcessPageTableRef::default(); | ||||||||
pptr.set_external_table(page_table_addr); | ||||||||
self.channel.allocate_input(&mut pptr, PAGE_SIZE); | ||||||||
self.channel.allocate_output(&mut pptr, PAGE_SIZE); | ||||||||
|
||||||||
|
||||||||
self.vmsa = new_vmsa_page; | ||||||||
self.sev_features = vmsa.sev_features; | ||||||||
self.base = base; | ||||||||
|
||||||||
} | ||||||||
|
||||||||
pub fn add_function(&mut self, function: VirtAddr, size: u64) { | ||||||||
let size = size + PAGE_SIZE_4K - (size % PAGE_SIZE_4K); | ||||||||
self.base.page_table_ref.add_function(function, size); | ||||||||
} | ||||||||
|
||||||||
pub fn test_run(&self) { | ||||||||
let apic_id = this_cpu().get_apic_id(); | ||||||||
log::info!("Trying to execute Context"); | ||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -286,6 +286,12 @@ impl ProcessPageTableRef { | |||||
self.add_region_vaddr(VirtAddr::from(0x18000000000u64), data); | ||||||
} | ||||||
|
||||||
pub fn add_function(&self, data:VirtAddr, size: u64) { | ||||||
let data: *mut u8 = data.as_mut_ptr::<u8>(); | ||||||
let data = unsafe { slice::from_raw_parts(data, size as usize) }; | ||||||
self.add_region_vaddr(VirtAddr::from(0xFE8000000000u64), data); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I changed the address to, say, self.add_region_vaddr(VirtAddr::from(0x140_0000_0000u64), data); then I confirmed that
this manifest works. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
is ok but
is not (PGD idx=256) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok this is because
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest to use
Suggested change
|
||||||
} | ||||||
|
||||||
pub fn add_pages(&self, start: VirtAddr, size: u64, flags: ProcessPageFlags) { | ||||||
for i in 0..(size as usize) { | ||||||
let new_page = allocate_page(); | ||||||
|
@@ -394,7 +400,7 @@ impl ProcessPageTableRef { | |||||
pub fn virt_to_phys(&self, vaddr: VirtAddr) -> PhysAddr { | ||||||
let (_pgd_mapping, pgd_table) = paddr_as_table!(self.process_page_table); | ||||||
let mut current_mapping = self.page_walk(&pgd_table, self.process_page_table, vaddr); | ||||||
log::info!("Current Mapping {:?}", current_mapping); | ||||||
//log::info!("Current Mapping {:?}", current_mapping); | ||||||
match current_mapping { | ||||||
ProcessTableLevelMapping::PTE(addr, index) => { | ||||||
let (_mapping, table) = paddr_as_u64_slice!(addr); | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for non-mount case (i.e., adding pages for trustlets), rmpadjust is needed