krata: rework cross-compilation

This commit is contained in:
Alex Zenla
2024-03-21 21:31:10 +00:00
parent 332a1bba26
commit 0191e5b2c1
27 changed files with 321 additions and 131 deletions

View File

@ -137,7 +137,7 @@ impl Arm64BootSetup {
&mut extents,
)?;
if allocsz == 0 {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("allocsz is zero"));
}
}
@ -154,6 +154,10 @@ impl ArchBootSetup for Arm64BootSetup {
ARM_PAGE_SHIFT
}
fn needs_early_kernel(&mut self) -> bool {
true
}
fn setup_shared_info(&mut self, _: &mut BootSetup, _: u64) -> Result<()> {
Ok(())
}
@ -166,9 +170,12 @@ impl ArchBootSetup for Arm64BootSetup {
&mut self,
setup: &mut BootSetup,
total_pages: u64,
kernel_segment: &DomainSegment,
kernel_segment: &Option<DomainSegment>,
initrd_segment: &Option<DomainSegment>,
) -> Result<()> {
let kernel_segment = kernel_segment
.as_ref()
.ok_or(Error::MemorySetupFailed("kernel_segment missing"))?;
setup.call.claim_pages(setup.domid, total_pages)?;
let mut ramsize = total_pages << XEN_PAGE_SHIFT;
@ -218,7 +225,7 @@ impl ArchBootSetup for Arm64BootSetup {
} else if kernbase - bankbase[0] > modsize {
kernbase - modsize
} else {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("unable to determine modbase"));
};
setup.call.claim_pages(setup.domid, 0)?;
Ok(())

View File

@ -88,7 +88,7 @@ impl BootSetup<'_> {
&mut self,
arch: &mut dyn ArchBootSetup,
total_pages: u64,
kernel_segment: &DomainSegment,
kernel_segment: &Option<DomainSegment>,
initrd_segment: &Option<DomainSegment>,
) -> Result<()> {
self.call.set_address_size(self.domid, 64)?;
@ -119,15 +119,24 @@ impl BootSetup<'_> {
let image_info = image_loader.parse()?;
debug!("initialize image_info={:?}", image_info);
let kernel_segment = self.load_kernel_segment(arch, image_loader, &image_info)?;
let mut kernel_segment: Option<DomainSegment> = None;
let mut initrd_segment: Option<DomainSegment> = None;
if !image_info.unmapped_initrd {
initrd_segment = Some(self.alloc_module(arch, initrd)?);
}
if arch.needs_early_kernel() {
kernel_segment = Some(self.load_kernel_segment(arch, image_loader, &image_info)?);
}
let total_pages = mem_mb << (20 - arch.page_shift());
self.initialize_memory(arch, total_pages, &kernel_segment, &initrd_segment)?;
self.virt_alloc_end = image_info.virt_base;
if kernel_segment.is_none() {
kernel_segment = Some(self.load_kernel_segment(arch, image_loader, &image_info)?);
}
let mut p2m_segment: Option<DomainSegment> = None;
if image_info.virt_p2m_base >= image_info.virt_base
|| (image_info.virt_p2m_base & ((1 << arch.page_shift()) - 1)) != 0
@ -158,6 +167,10 @@ impl BootSetup<'_> {
let initrd_segment = initrd_segment.unwrap();
let store_evtchn = self.call.evtchn_alloc_unbound(self.domid, 0)?;
let console_evtchn = self.call.evtchn_alloc_unbound(self.domid, 0)?;
let kernel_segment =
kernel_segment.ok_or(Error::MemorySetupFailed("kernel_segment missing"))?;
let state = BootState {
kernel_segment,
start_info_segment,
@ -317,11 +330,11 @@ impl BootSetup<'_> {
fn alloc_padding_pages(&mut self, arch: &mut dyn ArchBootSetup, boundary: u64) -> Result<()> {
if (boundary & (arch.page_size() - 1)) != 0 {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("boundary is incorrect"));
}
if boundary < self.virt_alloc_end {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("boundary is below allocation end"));
}
let pages = (boundary - self.virt_alloc_end) / arch.page_size();
self.chk_alloc_pages(arch, pages)?;
@ -333,7 +346,7 @@ impl BootSetup<'_> {
|| self.pfn_alloc_end > self.total_pages
|| pages > self.total_pages - self.pfn_alloc_end
{
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("no more pages left"));
}
self.pfn_alloc_end += pages;
@ -346,6 +359,8 @@ pub trait ArchBootSetup {
fn page_size(&mut self) -> u64;
fn page_shift(&mut self) -> u64;
fn needs_early_kernel(&mut self) -> bool;
fn alloc_p2m_segment(
&mut self,
setup: &mut BootSetup,
@ -373,7 +388,7 @@ pub trait ArchBootSetup {
&mut self,
setup: &mut BootSetup,
total_pages: u64,
kernel_segment: &DomainSegment,
kernel_segment: &Option<DomainSegment>,
initrd_segment: &Option<DomainSegment>,
) -> Result<()>;
fn bootlate(&mut self, setup: &mut BootSetup, state: &mut BootState) -> Result<()>;

View File

@ -24,8 +24,8 @@ pub enum Error {
MmapFailed,
#[error("munmap failed")]
UnmapFailed,
#[error("memory setup failed")]
MemorySetupFailed,
#[error("memory setup failed: {0}")]
MemorySetupFailed(&'static str),
#[error("populate physmap failed: wanted={0}, received={1}, input_extents={2}")]
PopulatePhysmapFailed(usize, usize, usize),
#[error("unknown elf compression method")]

View File

@ -57,7 +57,7 @@ impl PhysicalPages<'_> {
}
if pfn < page.pfn || (pfn + count) > page.pfn + page.count {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("pfn is out of range"));
}
} else {
if pfn < page.pfn {
@ -73,7 +73,7 @@ impl PhysicalPages<'_> {
}
if count == 0 {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("page count is zero"));
}
self.pfn_alloc(pfn, count)
@ -166,7 +166,7 @@ impl PhysicalPages<'_> {
pub fn unmap(&mut self, pfn: u64) -> Result<()> {
let page = self.pages.iter().enumerate().find(|(_, x)| x.pfn == pfn);
if page.is_none() {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("cannot unmap missing page"));
}
let (i, page) = page.unwrap();

View File

@ -116,7 +116,6 @@ pub struct SharedInfo {
pub wc_sec: u32,
pub wc_nsec: u32,
pub wc_sec_hi: u32,
// arch shared info
pub max_pfn: u64,
pub pfn_to_mfn_frame_list_list: u64,
@ -201,19 +200,19 @@ impl X86BootSetup {
) -> Result<usize> {
debug!("counting pgtables from={} to={} pfn={}", from, to, pfn);
if self.table.mappings_count == X86_PAGE_TABLE_MAX_MAPPINGS {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("max page table count reached"));
}
let m = self.table.mappings_count;
let pfn_end = pfn + ((to - from) >> X86_PAGE_SHIFT);
if pfn_end >= setup.phys.p2m_size() {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("pfn_end greater than p2m size"));
}
for idx in 0..self.table.mappings_count {
if from < self.table.mappings[idx].area.to && to > self.table.mappings[idx].area.from {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("page table calculation failed"));
}
}
let mut map = PageTableMapping::default();
@ -285,6 +284,10 @@ impl ArchBootSetup for X86BootSetup {
X86_PAGE_SHIFT
}
fn needs_early_kernel(&mut self) -> bool {
false
}
fn alloc_p2m_segment(
&mut self,
setup: &mut BootSetup,
@ -347,7 +350,10 @@ impl ArchBootSetup for X86BootSetup {
}
fn setup_page_tables(&mut self, setup: &mut BootSetup, state: &mut BootState) -> Result<()> {
let p2m_segment = state.p2m_segment.as_ref().ok_or(Error::MemorySetupFailed)?;
let p2m_segment = state
.p2m_segment
.as_ref()
.ok_or(Error::MemorySetupFailed("p2m_segment missing"))?;
let p2m_guest = unsafe {
slice::from_raw_parts_mut(p2m_segment.addr as *mut u64, setup.phys.p2m_size() as usize)
};
@ -416,8 +422,11 @@ impl ArchBootSetup for X86BootSetup {
let page_table_segment = state
.page_table_segment
.as_ref()
.ok_or(Error::MemorySetupFailed)?;
let p2m_segment = state.p2m_segment.as_ref().ok_or(Error::MemorySetupFailed)?;
.ok_or(Error::MemorySetupFailed("page_table_segment missing"))?;
let p2m_segment = state
.p2m_segment
.as_ref()
.ok_or(Error::MemorySetupFailed("p2m_segment missing"))?;
unsafe {
for (i, c) in X86_GUEST_MAGIC.chars().enumerate() {
(*info).magic[i] = c as c_char;
@ -467,7 +476,7 @@ impl ArchBootSetup for X86BootSetup {
&mut self,
setup: &mut BootSetup,
total_pages: u64,
_: &DomainSegment,
_: &Option<DomainSegment>,
_: &Option<DomainSegment>,
) -> Result<()> {
setup.call.claim_pages(setup.domid, total_pages)?;
@ -487,7 +496,7 @@ impl ArchBootSetup for X86BootSetup {
}
if total != total_pages {
return Err(Error::MemorySetupFailed);
return Err(Error::MemorySetupFailed("total pages mismatch"));
}
setup.total_pages = total;
@ -576,11 +585,14 @@ impl ArchBootSetup for X86BootSetup {
}
fn bootlate(&mut self, setup: &mut BootSetup, state: &mut BootState) -> Result<()> {
let p2m_segment = state.p2m_segment.as_ref().ok_or(Error::MemorySetupFailed)?;
let p2m_segment = state
.p2m_segment
.as_ref()
.ok_or(Error::MemorySetupFailed("p2m_segment missing"))?;
let page_table_segment = state
.page_table_segment
.as_ref()
.ok_or(Error::MemorySetupFailed)?;
.ok_or(Error::MemorySetupFailed("page_table_segment missing"))?;
let pg_pfn = page_table_segment.pfn;
let pg_mfn = setup.phys.p2m[pg_pfn as usize];
setup.phys.unmap(pg_pfn)?;
@ -595,7 +607,7 @@ impl ArchBootSetup for X86BootSetup {
let page_table_segment = state
.page_table_segment
.as_ref()
.ok_or(Error::MemorySetupFailed)?;
.ok_or(Error::MemorySetupFailed("page_table_segment missing"))?;
let pg_pfn = page_table_segment.pfn;
let pg_mfn = setup.phys.p2m[pg_pfn as usize];
let mut vcpu = VcpuGuestContext::default();