Skip to content
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

Merged
merged 3 commits into from
Dec 9, 2024
Merged

[WIP] Memory channels #2

merged 3 commits into from
Dec 9, 2024

Conversation

Sabanic-P
Copy link

No description provided.

// 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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

page_table_ref.add_function() (more precicely, add_region_vaddr() expects page-aligned size, therefore

Suggested change
trustlet.base.page_table_ref.add_function(function_code, size);
let size = (4096 - (size & 0xFFF)) + size;
trustlet.base.page_table_ref.add_function(function_code, size);

(I think add_region_vaddr should be able to take non-page aligend size though)

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);
Copy link
Member

Choose a reason for hiding this comment

The 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

[libos]
entrypoint = "/lib/python"

[loader]
argv = ["python3", "-c", "print('import ctypes'); import ctypes; print('string_at'); a=ctypes.string_at(0x14000000000); print(a)"]
...

this manifest works.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.add_region_vaddr(VirtAddr::from(0x7F80_0000_0000u64), data);

is ok but

self.add_region_vaddr(VirtAddr::from(0x8000_0000_0000u64), data);

is not (PGD idx=256)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok this is because

Address sizes: 43 bits physical, 48 bits virtual

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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to use

Suggested change
self.add_region_vaddr(VirtAddr::from(0xFE8000000000u64), data);
self.add_region_vaddr(VirtAddr::from(0x140_0000_0000u64), data);

Comment on lines 5 to 6
pub const INPUT_VADDR: u64 = 0xFF0000000000u64;
pub const OUTPUT_VADDR: u64 = 0xFF8000000000u64;
Copy link
Member

@mmisono mmisono Dec 8, 2024

Choose a reason for hiding this comment

The 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
pub const INPUT_VADDR: u64 = 0xFF0000000000u64;
pub const OUTPUT_VADDR: u64 = 0xFF8000000000u64;
pub const INPUT_VADDR: u64 = 0x200_0000_0000u64;
pub const OUTPUT_VADDR: u64 = 0x200_0000_8000u64;

However, even with this change, I still cannot access input/output channels (it seems #PF)


let start_address = VirtAddr::from(0x30000000000u64);
let start_address = VirtAddr::from(start_addr);

for i in 0..(pages as usize) {
let current_page = allocate_page();
Copy link
Member

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

            if !mount {
                let (mapping, _page_mapped) = paddr_as_slice!(current_page);
                rmp_adjust(mapping.virt_addr(), RMPFlags::VMPL1 | RMPFlags::RWX , PageSize::Regular).unwra
p();
            }

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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

INPUT_VADDR istead of ALLOCATION_RANGE_VIRT_STRAT?


self.input.mount();

page_table_ref.copy_address_range(VirtAddr::from(source_addr), copy_size as u64, target);
Copy link
Member

Choose a reason for hiding this comment

The 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


impl MemoryChannel {

pub fn allocate_input(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

     pub fn allocate_input(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize) {
-        self.input = self.allocate_range(page_table_ref, size, INPUT_VADDR);
+        let flags = ProcessPageFlags::PRESENT | ProcessPageFlags::WRITABLE |
+        ProcessPageFlags::USER_ACCESSIBLE | ProcessPageFlags::ACCESSED;
+        page_table_ref.add_pages(VirtAddr::from(INPUT_VADDR), 1, flags);
+        //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);
+        let flags = ProcessPageFlags::PRESENT | ProcessPageFlags::WRITABLE |
+        ProcessPageFlags::USER_ACCESSIBLE | ProcessPageFlags::ACCESSED;
+        page_table_ref.add_pages(VirtAddr::from(OUTPUT_VADDR), 1, flags);
+        //self.output = self.allocate_range(page_table_ref, size, OUTPUT_VADDR);
     }

this works. allocate_range for the trustlets has some issuses

Set new ranges for input and output
Add rmp_adjust for new memory
Fix input copy
@Sabanic-P Sabanic-P merged commit b68ce76 into dev Dec 9, 2024
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants