mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-08-12 18:35:45 +00:00
sel4bundle: fix handling of segment gaps
Need to account for gaps between application segments when calculating the index of the page frame object. This was being handled only for a gap before the first page/segment. Bug: 243556006 Change-Id: I0e723a58dc5e2b9c49b29aebe030a546bbe024ac GitOrigin-RevId: 83e6cad536ffa148c434341fbefdce2dd43667ee
This commit is contained in:
parent
173e7211c7
commit
201876492b
@ -178,9 +178,6 @@ pub struct seL4BundleImpl {
|
|||||||
// CNode so long as the application is active.
|
// CNode so long as the application is active.
|
||||||
cspace_root: ObjDescBundle,
|
cspace_root: ObjDescBundle,
|
||||||
|
|
||||||
// Page index for first virtual address in BundleImage.
|
|
||||||
first_page: usize,
|
|
||||||
|
|
||||||
// Application thread for start/suspend/resume. This starts out
|
// Application thread for start/suspend/resume. This starts out
|
||||||
// in the cspace_root until after the CSpace is constructed when
|
// in the cspace_root until after the CSpace is constructed when
|
||||||
// we dup the capability into our top-level CNode for suspend/resume.
|
// we dup the capability into our top-level CNode for suspend/resume.
|
||||||
@ -226,6 +223,8 @@ impl seL4BundleImpl {
|
|||||||
"Bundle {} has no entry point, using 0x{:x}",
|
"Bundle {} has no entry point, using 0x{:x}",
|
||||||
&bundle.app_id, first_vaddr
|
&bundle.app_id, first_vaddr
|
||||||
);
|
);
|
||||||
|
// XXX should probably just return but need to verify
|
||||||
|
// bundle_frames is reclaimed
|
||||||
}
|
}
|
||||||
// TODO(sleffler): reject empty image or no entry point?
|
// TODO(sleffler): reject empty image or no entry point?
|
||||||
// TODO(sleffler): could sanity check memory requirements but
|
// TODO(sleffler): could sanity check memory requirements but
|
||||||
@ -296,7 +295,6 @@ impl seL4BundleImpl {
|
|||||||
dynamic_objs,
|
dynamic_objs,
|
||||||
cspace_root,
|
cspace_root,
|
||||||
cap_tcb: CSpaceSlot::new(), // Top-level dup for suspend/resume
|
cap_tcb: CSpaceSlot::new(), // Top-level dup for suspend/resume
|
||||||
first_page: first_vaddr / PAGE_SIZE,
|
|
||||||
|
|
||||||
affinity: 0, // CPU 0
|
affinity: 0, // CPU 0
|
||||||
domain: Domain::System, // TODO(jtgans,sleffler): Figure out how to use this correctly. b/238811077
|
domain: Domain::System, // TODO(jtgans,sleffler): Figure out how to use this correctly. b/238811077
|
||||||
@ -322,26 +320,32 @@ impl seL4BundleImpl {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate how many pages are needed and (while we're here)
|
// Calculate how many pages are needed and and identify the entry point.
|
||||||
// identify an entry point.
|
// While we're here also verify segments are ordered by vaddr; this
|
||||||
|
// is required by load_application to handle gaps between segments.
|
||||||
fn preprocess_bundle_image(bundle_frames: &ObjDescBundle) -> (usize, usize, Option<usize>) {
|
fn preprocess_bundle_image(bundle_frames: &ObjDescBundle) -> (usize, usize, Option<usize>) {
|
||||||
let mut nframes = 0;
|
let mut nframes = 0;
|
||||||
let mut entry_point = None;
|
let mut entry_point = None;
|
||||||
let mut first_vaddr = usize::MAX;
|
let mut first_vaddr = usize::MAX;
|
||||||
|
let mut prev_vaddr = 0;
|
||||||
let mut image = BundleImage::new(bundle_frames);
|
let mut image = BundleImage::new(bundle_frames);
|
||||||
while let Some(section) = image.next_section() {
|
while let Some(section) = image.next_section() {
|
||||||
let vaddr = section.vaddr;
|
let vaddr = section.vaddr;
|
||||||
if vaddr < first_vaddr {
|
if vaddr < first_vaddr {
|
||||||
first_vaddr = vaddr;
|
first_vaddr = vaddr;
|
||||||
}
|
}
|
||||||
|
assert!(vaddr >= prev_vaddr); // XXX return error instead
|
||||||
if let Some(pc) = section.entry {
|
if let Some(pc) = section.entry {
|
||||||
trace!("entry point 0x{:x}", pc);
|
trace!("entry point 0x{:x}", pc);
|
||||||
|
// XXX reject multiple entry's
|
||||||
entry_point = Some(pc);
|
entry_point = Some(pc);
|
||||||
}
|
}
|
||||||
let first_frame = vaddr / PAGE_SIZE;
|
let first_frame = vaddr / PAGE_SIZE;
|
||||||
let last_frame = roundup(vaddr + section.msize, PAGE_SIZE) / PAGE_SIZE;
|
let last_frame = roundup(vaddr + section.msize, PAGE_SIZE) / PAGE_SIZE;
|
||||||
nframes += last_frame - first_frame
|
nframes += last_frame - first_frame;
|
||||||
|
prev_vaddr = vaddr;
|
||||||
}
|
}
|
||||||
|
trace!("nframes {} first_vaddr 0x{:x}", nframes, first_vaddr);
|
||||||
(nframes, first_vaddr, entry_point)
|
(nframes, first_vaddr, entry_point)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,6 +372,10 @@ impl seL4BundleImpl {
|
|||||||
CopyRegion::new(unsafe { ptr::addr_of_mut!(LOAD_APPLICATION[0]) }, PAGE_SIZE);
|
CopyRegion::new(unsafe { ptr::addr_of_mut!(LOAD_APPLICATION[0]) }, PAGE_SIZE);
|
||||||
|
|
||||||
let mut vaddr_top = 0;
|
let mut vaddr_top = 0;
|
||||||
|
// Track last allocated page that was mapped to handle gaps between
|
||||||
|
// segments. Note page_offset is accumulated to handle multiple gaps.
|
||||||
|
let mut page_adjust = 0;
|
||||||
|
let mut prev_last_page = 0;
|
||||||
while let Some(section) = image.next_section() {
|
while let Some(section) = image.next_section() {
|
||||||
trace!("load {:?}", §ion);
|
trace!("load {:?}", §ion);
|
||||||
let rights = §ion.get_rights();
|
let rights = §ion.get_rights();
|
||||||
@ -388,7 +396,9 @@ impl seL4BundleImpl {
|
|||||||
// do page-by-page copying or zero-filling.
|
// do page-by-page copying or zero-filling.
|
||||||
let first_page = vaddr / PAGE_SIZE;
|
let first_page = vaddr / PAGE_SIZE;
|
||||||
let last_page = roundup(vaddr + section.msize, PAGE_SIZE) / PAGE_SIZE;
|
let last_page = roundup(vaddr + section.msize, PAGE_SIZE) / PAGE_SIZE;
|
||||||
let page_range = (first_page - self.first_page)..(last_page - self.first_page);
|
// NB: this assumes segments are ordered by vaddr.
|
||||||
|
page_adjust += first_page - prev_last_page;
|
||||||
|
let page_range = (first_page - page_adjust)..(last_page - page_adjust);
|
||||||
for index in page_range {
|
for index in page_range {
|
||||||
let frame = &page_frames.new_at(index);
|
let frame = &page_frames.new_at(index);
|
||||||
let frame_vaddr = (vaddr / PAGE_SIZE) * PAGE_SIZE;
|
let frame_vaddr = (vaddr / PAGE_SIZE) * PAGE_SIZE;
|
||||||
@ -418,6 +428,7 @@ impl seL4BundleImpl {
|
|||||||
arch::map_page(frame, pd, frame_vaddr, *rights, vm_attribs)?;
|
arch::map_page(frame, pd, frame_vaddr, *rights, vm_attribs)?;
|
||||||
vaddr += frame.size_bytes().unwrap();
|
vaddr += frame.size_bytes().unwrap();
|
||||||
}
|
}
|
||||||
|
prev_last_page = last_page;
|
||||||
if vaddr > vaddr_top {
|
if vaddr > vaddr_top {
|
||||||
// NB: leaves an unused frame in the gap but should not matter
|
// NB: leaves an unused frame in the gap but should not matter
|
||||||
vaddr_top = vaddr;
|
vaddr_top = vaddr;
|
||||||
|
Loading…
Reference in New Issue
Block a user