mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-03 13:11:31 +00:00
krata: rework cross-compilation
This commit is contained in:
@ -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(())
|
||||
|
@ -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<()>;
|
||||
|
@ -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")]
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
Reference in New Issue
Block a user