mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 21:00:55 +00:00
fix multiple oversights that make values not align with original library
This commit is contained in:
parent
b79c31e613
commit
1f30f8315a
@ -1,6 +1,7 @@
|
|||||||
use crate::mem::PhysicalPages;
|
use crate::mem::PhysicalPages;
|
||||||
use crate::sys::{
|
use crate::sys::{
|
||||||
SUPERPAGE_2MB_NR_PFNS, SUPERPAGE_2MB_SHIFT, SUPERPAGE_BATCH_SIZE, XEN_PAGE_SHIFT,
|
SUPERPAGE_2MB_NR_PFNS, SUPERPAGE_2MB_SHIFT, SUPERPAGE_BATCH_SIZE, VGCF_IN_KERNEL, VGCF_ONLINE,
|
||||||
|
XEN_PAGE_SHIFT,
|
||||||
};
|
};
|
||||||
use crate::x86::{
|
use crate::x86::{
|
||||||
PageTable, PageTableMapping, StartInfo, MAX_GUEST_CMDLINE, X86_GUEST_MAGIC, X86_PAGE_SHIFT,
|
PageTable, PageTableMapping, StartInfo, MAX_GUEST_CMDLINE, X86_GUEST_MAGIC, X86_PAGE_SHIFT,
|
||||||
@ -64,6 +65,7 @@ struct VmemRange {
|
|||||||
_nid: u32,
|
_nid: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct BootState {
|
pub struct BootState {
|
||||||
pub kernel_segment: DomainSegment,
|
pub kernel_segment: DomainSegment,
|
||||||
pub start_info_segment: DomainSegment,
|
pub start_info_segment: DomainSegment,
|
||||||
@ -231,7 +233,7 @@ impl BootSetup<'_> {
|
|||||||
if self.virt_pgtab_end > 0 {
|
if self.virt_pgtab_end > 0 {
|
||||||
self.alloc_padding_pages(self.virt_pgtab_end)?;
|
self.alloc_padding_pages(self.virt_pgtab_end)?;
|
||||||
}
|
}
|
||||||
Ok(BootState {
|
let state = BootState {
|
||||||
kernel_segment,
|
kernel_segment,
|
||||||
start_info_segment,
|
start_info_segment,
|
||||||
xenstore_segment,
|
xenstore_segment,
|
||||||
@ -240,12 +242,14 @@ impl BootSetup<'_> {
|
|||||||
page_table_segment,
|
page_table_segment,
|
||||||
page_table,
|
page_table,
|
||||||
image_info,
|
image_info,
|
||||||
})
|
};
|
||||||
|
debug!("initialize state={:?}", state);
|
||||||
|
Ok(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn boot(&mut self, state: &mut BootState, cmdline: &str) -> Result<(), XenClientError> {
|
pub fn boot(&mut self, state: &mut BootState, cmdline: &str) -> Result<(), XenClientError> {
|
||||||
self.setup_page_tables(state)?;
|
self.setup_page_tables(state)?;
|
||||||
self.setup_start_info(state, cmdline);
|
self.setup_start_info(state, cmdline)?;
|
||||||
self.setup_hypercall_page(&state.image_info)?;
|
self.setup_hypercall_page(&state.image_info)?;
|
||||||
|
|
||||||
let mut vcpu = VcpuGuestContext::default();
|
let mut vcpu = VcpuGuestContext::default();
|
||||||
@ -257,7 +261,7 @@ impl BootSetup<'_> {
|
|||||||
vcpu.user_regs.rflags = 1 << 9;
|
vcpu.user_regs.rflags = 1 << 9;
|
||||||
vcpu.debugreg[6] = 0xffff0ff0;
|
vcpu.debugreg[6] = 0xffff0ff0;
|
||||||
vcpu.debugreg[7] = 0x00000400;
|
vcpu.debugreg[7] = 0x00000400;
|
||||||
vcpu.flags = (1 << 2) | (1 << 5);
|
vcpu.flags = VGCF_IN_KERNEL | VGCF_ONLINE;
|
||||||
let cr3_pfn = self.phys.p2m[state.page_table_segment.pfn as usize];
|
let cr3_pfn = self.phys.p2m[state.page_table_segment.pfn as usize];
|
||||||
vcpu.ctrlreg[3] = cr3_pfn << 12;
|
vcpu.ctrlreg[3] = cr3_pfn << 12;
|
||||||
vcpu.user_regs.ds = 0xe021;
|
vcpu.user_regs.ds = 0xe021;
|
||||||
@ -268,7 +272,6 @@ impl BootSetup<'_> {
|
|||||||
vcpu.user_regs.cs = 0xe019;
|
vcpu.user_regs.cs = 0xe019;
|
||||||
vcpu.kernel_ss = vcpu.user_regs.ss as u64;
|
vcpu.kernel_ss = vcpu.user_regs.ss as u64;
|
||||||
vcpu.kernel_sp = vcpu.user_regs.rsp;
|
vcpu.kernel_sp = vcpu.user_regs.rsp;
|
||||||
let _vcpu = vcpu;
|
|
||||||
self.domctl.set_vcpu_context(self.domid, 0, Some(&vcpu))?;
|
self.domctl.set_vcpu_context(self.domid, 0, Some(&vcpu))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -319,8 +322,8 @@ impl BootSetup<'_> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_start_info(&mut self, state: &BootState, cmdline: &str) {
|
fn setup_start_info(&mut self, state: &BootState, cmdline: &str) -> Result<(), XenClientError> {
|
||||||
let info = state.start_info_segment.addr as *mut StartInfo;
|
let info = self.phys.pfn_to_ptr(state.start_info_segment.pfn, 1)? as *mut StartInfo;
|
||||||
unsafe {
|
unsafe {
|
||||||
for (i, c) in X86_GUEST_MAGIC.chars().enumerate() {
|
for (i, c) in X86_GUEST_MAGIC.chars().enumerate() {
|
||||||
(*info).magic[i] = c as c_char;
|
(*info).magic[i] = c as c_char;
|
||||||
@ -345,6 +348,7 @@ impl BootSetup<'_> {
|
|||||||
}
|
}
|
||||||
debug!("BootSetup setup_start_info={:?}", *info);
|
debug!("BootSetup setup_start_info={:?}", *info);
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_kernel_segment(
|
fn load_kernel_segment(
|
||||||
@ -422,6 +426,7 @@ impl BootSetup<'_> {
|
|||||||
if lvl.from >= cmp_lvl.from && lvl.to <= cmp_lvl.to {
|
if lvl.from >= cmp_lvl.from && lvl.to <= cmp_lvl.to {
|
||||||
lvl.from = 0;
|
lvl.from = 0;
|
||||||
lvl.to = 0;
|
lvl.to = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if lvl.from >= cmp_lvl.from && lvl.from <= cmp_lvl.to {
|
if lvl.from >= cmp_lvl.from && lvl.from <= cmp_lvl.to {
|
||||||
@ -437,6 +442,10 @@ impl BootSetup<'_> {
|
|||||||
lvl.pgtables = (((lvl.to - lvl.from) >> bits) + 1) as usize;
|
lvl.pgtables = (((lvl.to - lvl.from) >> bits) + 1) as usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"count_pgtables {:#x}/{}: {:#x} -> {:#x}, {} tables",
|
||||||
|
mask, bits, lvl.from, lvl.to, lvl.pgtables
|
||||||
|
);
|
||||||
map.area.pgtables += lvl.pgtables;
|
map.area.pgtables += lvl.pgtables;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -447,7 +456,8 @@ impl BootSetup<'_> {
|
|||||||
image_info: &BootImageInfo,
|
image_info: &BootImageInfo,
|
||||||
) -> Result<(DomainSegment, PageTable), XenClientError> {
|
) -> Result<(DomainSegment, PageTable), XenClientError> {
|
||||||
let mut table = PageTable::default();
|
let mut table = PageTable::default();
|
||||||
let extra_pages = ((512 * 1024) / X86_PAGE_SIZE) + 1;
|
let mut extra_pages = 1;
|
||||||
|
extra_pages += (512 * 1024) / X86_PAGE_SIZE;
|
||||||
let mut pages = extra_pages;
|
let mut pages = extra_pages;
|
||||||
|
|
||||||
let mut try_virt_end: u64;
|
let mut try_virt_end: u64;
|
||||||
@ -466,7 +476,8 @@ impl BootSetup<'_> {
|
|||||||
map.area.pfn = 0;
|
map.area.pfn = 0;
|
||||||
table.mappings_count += 1;
|
table.mappings_count += 1;
|
||||||
self.virt_pgtab_end = try_virt_end + 1;
|
self.virt_pgtab_end = try_virt_end + 1;
|
||||||
segment = self.alloc_segment(0, map.area.pgtables as u64 * X86_PAGE_SIZE)?;
|
segment =
|
||||||
|
self.alloc_segment(0, (map.area.pgtables as u64 * X86_PAGE_SIZE) + extra_pages)?;
|
||||||
}
|
}
|
||||||
debug!(
|
debug!(
|
||||||
"BootSetup alloc_page_tables table={:?} segment={:?}",
|
"BootSetup alloc_page_tables table={:?} segment={:?}",
|
||||||
@ -502,15 +513,26 @@ impl BootSetup<'_> {
|
|||||||
}
|
}
|
||||||
segment._vend = self.virt_alloc_end;
|
segment._vend = self.virt_alloc_end;
|
||||||
debug!(
|
debug!(
|
||||||
"BootSetup alloc_segment start={:#x} size={} ptr={:#x}",
|
"alloc_segment {:#x} -> {:#x} (pfn {:#x} + {:#x} pages)",
|
||||||
start, size, ptr
|
start, segment._vend, segment.pfn, pages
|
||||||
);
|
);
|
||||||
Ok(segment)
|
Ok(segment)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_page(&mut self) -> Result<DomainSegment, XenClientError> {
|
fn alloc_page(&mut self) -> Result<DomainSegment, XenClientError> {
|
||||||
let page_size = 1u64 << XEN_PAGE_SHIFT;
|
let start = self.virt_alloc_end;
|
||||||
self.alloc_segment(0, page_size)
|
let pfn = self.pfn_alloc_end;
|
||||||
|
|
||||||
|
self.chk_alloc_pages(1)?;
|
||||||
|
debug!("alloc_page {:#x} (pfn {:#x})", start, pfn);
|
||||||
|
Ok(DomainSegment {
|
||||||
|
vstart: start,
|
||||||
|
_vend: (start + X86_PAGE_SIZE) - 1,
|
||||||
|
pfn,
|
||||||
|
addr: 0,
|
||||||
|
size: 0,
|
||||||
|
_pages: 1,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_padding_pages(&mut self, boundary: u64) -> Result<(), XenClientError> {
|
fn alloc_padding_pages(&mut self, boundary: u64) -> Result<(), XenClientError> {
|
||||||
|
@ -119,3 +119,5 @@ pub const XEN_PAGE_MASK: u64 = !(XEN_PAGE_SIZE - 1);
|
|||||||
pub const SUPERPAGE_BATCH_SIZE: u64 = 512;
|
pub const SUPERPAGE_BATCH_SIZE: u64 = 512;
|
||||||
pub const SUPERPAGE_2MB_SHIFT: u64 = 9;
|
pub const SUPERPAGE_2MB_SHIFT: u64 = 9;
|
||||||
pub const SUPERPAGE_2MB_NR_PFNS: u64 = 1u64 << SUPERPAGE_2MB_SHIFT;
|
pub const SUPERPAGE_2MB_NR_PFNS: u64 = 1u64 << SUPERPAGE_2MB_SHIFT;
|
||||||
|
pub const VGCF_IN_KERNEL: u64 = 1 << 2;
|
||||||
|
pub const VGCF_ONLINE: u64 = 1 << 5;
|
||||||
|
Loading…
Reference in New Issue
Block a user