mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 12:50:54 +00:00
multiple fixes and cleanup
This commit is contained in:
parent
a9275c4bdf
commit
c9f39699dc
@ -188,7 +188,7 @@ impl DomainControl<'_> {
|
|||||||
&self,
|
&self,
|
||||||
domid: u32,
|
domid: u32,
|
||||||
vcpu: u32,
|
vcpu: u32,
|
||||||
context: Option<&VcpuGuestContext>,
|
context: &VcpuGuestContext,
|
||||||
) -> Result<(), XenCallError> {
|
) -> Result<(), XenCallError> {
|
||||||
trace!(
|
trace!(
|
||||||
"domctl fd={} set_vcpu_context domid={} context={:?}",
|
"domctl fd={} set_vcpu_context domid={} context={:?}",
|
||||||
@ -196,7 +196,10 @@ impl DomainControl<'_> {
|
|||||||
domid,
|
domid,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
let mut wrapper = context.map(|ctx| VcpuGuestContextAny { value: *ctx });
|
|
||||||
|
let mut value = VcpuGuestContextAny {
|
||||||
|
value: *context,
|
||||||
|
};
|
||||||
let mut domctl = DomCtl {
|
let mut domctl = DomCtl {
|
||||||
cmd: XEN_DOMCTL_SETVCPUCONTEXT,
|
cmd: XEN_DOMCTL_SETVCPUCONTEXT,
|
||||||
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
||||||
@ -204,11 +207,7 @@ impl DomainControl<'_> {
|
|||||||
value: DomCtlValue {
|
value: DomCtlValue {
|
||||||
vcpu_context: DomCtlVcpuContext {
|
vcpu_context: DomCtlVcpuContext {
|
||||||
vcpu,
|
vcpu,
|
||||||
ctx: if wrapper.is_some() {
|
ctx: addr_of_mut!(value) as c_ulong,
|
||||||
addr_of_mut!(wrapper) as c_ulong
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@ use crate::sys::{
|
|||||||
};
|
};
|
||||||
use crate::{XenCall, XenCallError};
|
use crate::{XenCall, XenCallError};
|
||||||
|
|
||||||
use log::{trace};
|
use log::trace;
|
||||||
use std::ffi::c_ulong;
|
use std::ffi::c_ulong;
|
||||||
use std::os::fd::AsRawFd;
|
use std::os::fd::AsRawFd;
|
||||||
use std::ptr::addr_of_mut;
|
use std::ptr::addr_of_mut;
|
||||||
@ -52,11 +52,14 @@ impl MemoryControl<'_> {
|
|||||||
self.call.multicall(calls)?;
|
self.call.multicall(calls)?;
|
||||||
let code = calls[0].result;
|
let code = calls[0].result;
|
||||||
if code > !0xfff {
|
if code > !0xfff {
|
||||||
return Err(XenCallError::new("failed to populate physmap"));
|
return Err(XenCallError::new(
|
||||||
|
format!("failed to populate physmap: {:#x}", code).as_str(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
if code as usize > extent_starts.len() {
|
if code as usize > extent_starts.len() {
|
||||||
return Err(XenCallError::new("failed to populate physmap"));
|
return Err(XenCallError::new("failed to populate physmap"));
|
||||||
}
|
}
|
||||||
Ok(extent_starts[0..code as usize].to_vec())
|
let extents = extent_starts[0..code as usize].to_vec();
|
||||||
|
Ok(extents)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ fn boot(
|
|||||||
let image_loader = ElfImageLoader::load_file_kernel(kernel_image_path)?;
|
let image_loader = ElfImageLoader::load_file_kernel(kernel_image_path)?;
|
||||||
let memctl = MemoryControl::new(call);
|
let memctl = MemoryControl::new(call);
|
||||||
let mut boot = BootSetup::new(call, domctl, &memctl, domid);
|
let mut boot = BootSetup::new(call, domctl, &memctl, domid);
|
||||||
let mut state = boot.initialize(&image_loader, 512 * 1024)?;
|
let mut state = boot.initialize(&image_loader, 128 * 1024)?;
|
||||||
boot.boot(&mut state, "debug")?;
|
boot.boot(&mut state, "debug")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,10 @@ use crate::x86::{
|
|||||||
X86_VIRT_MASK,
|
X86_VIRT_MASK,
|
||||||
};
|
};
|
||||||
use crate::XenClientError;
|
use crate::XenClientError;
|
||||||
use libc::{c_char, memset};
|
use libc::c_char;
|
||||||
use log::{debug, trace};
|
use log::{debug, trace};
|
||||||
use slice_copy::copy;
|
use slice_copy::copy;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::ffi::c_void;
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use xencall::domctl::DomainControl;
|
use xencall::domctl::DomainControl;
|
||||||
use xencall::memory::MemoryControl;
|
use xencall::memory::MemoryControl;
|
||||||
@ -59,6 +58,7 @@ pub struct DomainSegment {
|
|||||||
_pages: u64,
|
_pages: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct VmemRange {
|
struct VmemRange {
|
||||||
start: u64,
|
start: u64,
|
||||||
end: u64,
|
end: u64,
|
||||||
@ -154,12 +154,13 @@ impl BootSetup<'_> {
|
|||||||
j += 1;
|
j += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let extents_init_slice = extents_init.as_slice();
|
||||||
let extents = self.memctl.populate_physmap(
|
let extents = self.memctl.populate_physmap(
|
||||||
self.domid,
|
self.domid,
|
||||||
count,
|
count,
|
||||||
SUPERPAGE_2MB_SHIFT as u32,
|
SUPERPAGE_2MB_SHIFT as u32,
|
||||||
0,
|
0,
|
||||||
extents_init.as_slice(),
|
&extents_init_slice[0usize..count as usize],
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
pfn = pfn_base_idx;
|
pfn = pfn_base_idx;
|
||||||
@ -181,17 +182,20 @@ impl BootSetup<'_> {
|
|||||||
let allocsz = (1024 * 1024).min(pages - j);
|
let allocsz = (1024 * 1024).min(pages - j);
|
||||||
let p2m_idx = (pfn_base + j) as usize;
|
let p2m_idx = (pfn_base + j) as usize;
|
||||||
let p2m_end_idx = p2m_idx + allocsz as usize;
|
let p2m_end_idx = p2m_idx + allocsz as usize;
|
||||||
let result = self.memctl.populate_physmap(
|
let input_extent_starts = &p2m[p2m_idx..p2m_end_idx];
|
||||||
self.domid,
|
let result =
|
||||||
allocsz,
|
self.memctl
|
||||||
0,
|
.populate_physmap(self.domid, allocsz, 0, 0, input_extent_starts)?;
|
||||||
0,
|
|
||||||
&p2m[p2m_idx..p2m_end_idx],
|
|
||||||
)?;
|
|
||||||
|
|
||||||
if result.len() != allocsz as usize {
|
if result.len() != allocsz as usize {
|
||||||
return Err(XenClientError::new(
|
return Err(XenClientError::new(
|
||||||
format!("failed to populate physmap: {:?}", result).as_str(),
|
format!(
|
||||||
|
"failed to populate physmap: wanted={} received={} input_extents={}",
|
||||||
|
allocsz,
|
||||||
|
result.len(),
|
||||||
|
input_extent_starts.len()
|
||||||
|
)
|
||||||
|
.as_str(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
copy(p2m.as_mut_slice(), result.as_slice());
|
copy(p2m.as_mut_slice(), result.as_slice());
|
||||||
@ -268,6 +272,10 @@ impl BootSetup<'_> {
|
|||||||
vcpu.debugreg[7] = 0x00000400;
|
vcpu.debugreg[7] = 0x00000400;
|
||||||
vcpu.flags = VGCF_IN_KERNEL | VGCF_ONLINE;
|
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];
|
||||||
|
debug!(
|
||||||
|
"cr3: pfn {:#x} mfn {:#x}",
|
||||||
|
state.page_table_segment.pfn, cr3_pfn
|
||||||
|
);
|
||||||
vcpu.ctrlreg[3] = cr3_pfn << 12;
|
vcpu.ctrlreg[3] = cr3_pfn << 12;
|
||||||
vcpu.user_regs.ds = 0x0;
|
vcpu.user_regs.ds = 0x0;
|
||||||
vcpu.user_regs.es = 0x0;
|
vcpu.user_regs.es = 0x0;
|
||||||
@ -277,7 +285,7 @@ impl BootSetup<'_> {
|
|||||||
vcpu.user_regs.cs = 0xe033;
|
vcpu.user_regs.cs = 0xe033;
|
||||||
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;
|
||||||
self.domctl.set_vcpu_context(self.domid, 0, Some(&vcpu))?;
|
self.domctl.set_vcpu_context(self.domid, 0, &vcpu)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,9 +331,12 @@ impl BootSetup<'_> {
|
|||||||
)
|
)
|
||||||
.unwrap_or(0u64);
|
.unwrap_or(0u64);
|
||||||
|
|
||||||
for p in p_s..p_e + 1 {
|
for p in p_s..p_e {
|
||||||
|
let prot = self.get_pg_prot(lvl_idx, pfn, &state.page_table);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
*pg.add(p as usize) = self.phys.p2m[pfn as usize] << X86_PAGE_SHIFT;
|
*pg.add(p as usize) =
|
||||||
|
(self.phys.p2m[pfn as usize] << X86_PAGE_SHIFT) | prot;
|
||||||
}
|
}
|
||||||
pfn += 1;
|
pfn += 1;
|
||||||
}
|
}
|
||||||
@ -335,6 +346,46 @@ impl BootSetup<'_> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PAGE_PRESENT: u64 = 0x001;
|
||||||
|
const PAGE_RW: u64 = 0x002;
|
||||||
|
const PAGE_ACCESSED: u64 = 0x020;
|
||||||
|
const PAGE_DIRTY: u64 = 0x040;
|
||||||
|
const PAGE_USER: u64 = 0x004;
|
||||||
|
fn get_pg_prot(&mut self, l: usize, pfn: u64, table: &PageTable) -> u64 {
|
||||||
|
let prot = [
|
||||||
|
BootSetup::PAGE_PRESENT | BootSetup::PAGE_RW | BootSetup::PAGE_ACCESSED,
|
||||||
|
BootSetup::PAGE_PRESENT
|
||||||
|
| BootSetup::PAGE_RW
|
||||||
|
| BootSetup::PAGE_ACCESSED
|
||||||
|
| BootSetup::PAGE_DIRTY
|
||||||
|
| BootSetup::PAGE_USER,
|
||||||
|
BootSetup::PAGE_PRESENT
|
||||||
|
| BootSetup::PAGE_RW
|
||||||
|
| BootSetup::PAGE_ACCESSED
|
||||||
|
| BootSetup::PAGE_DIRTY
|
||||||
|
| BootSetup::PAGE_USER,
|
||||||
|
BootSetup::PAGE_PRESENT
|
||||||
|
| BootSetup::PAGE_RW
|
||||||
|
| BootSetup::PAGE_ACCESSED
|
||||||
|
| BootSetup::PAGE_DIRTY
|
||||||
|
| BootSetup::PAGE_USER,
|
||||||
|
];
|
||||||
|
|
||||||
|
let prot = prot[l];
|
||||||
|
if l > 0 {
|
||||||
|
return prot;
|
||||||
|
}
|
||||||
|
|
||||||
|
for map in &table.mappings {
|
||||||
|
let pfn_s = map.levels[(X86_PGTABLE_LEVELS - 1) as usize].pfn;
|
||||||
|
let pfn_e = map.area.pgtables as u64 + pfn_s;
|
||||||
|
if pfn > pfn_s && pfn < pfn_e {
|
||||||
|
return prot & !BootSetup::PAGE_RW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prot
|
||||||
|
}
|
||||||
|
|
||||||
fn setup_start_info(&mut self, state: &BootState, cmdline: &str) -> Result<(), XenClientError> {
|
fn setup_start_info(&mut self, state: &BootState, cmdline: &str) -> Result<(), XenClientError> {
|
||||||
let info = self.phys.pfn_to_ptr(state.start_info_segment.pfn, 1)? as *mut StartInfo;
|
let info = self.phys.pfn_to_ptr(state.start_info_segment.pfn, 1)? as *mut StartInfo;
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -543,9 +594,9 @@ impl BootSetup<'_> {
|
|||||||
|
|
||||||
let ptr = self.phys.pfn_to_ptr(segment.pfn, pages)?;
|
let ptr = self.phys.pfn_to_ptr(segment.pfn, pages)?;
|
||||||
segment.addr = ptr;
|
segment.addr = ptr;
|
||||||
unsafe {
|
let slice =
|
||||||
memset(ptr as *mut c_void, 0, (pages * page_size) as usize);
|
unsafe { slice::from_raw_parts_mut(ptr as *mut u8, (pages * page_size) as usize) };
|
||||||
}
|
slice.fill(0);
|
||||||
segment._vend = self.virt_alloc_end;
|
segment._vend = self.virt_alloc_end;
|
||||||
debug!(
|
debug!(
|
||||||
"BootSetup alloc_segment {:#x} -> {:#x} (pfn {:#x} + {:#x} pages)",
|
"BootSetup alloc_segment {:#x} -> {:#x} (pfn {:#x} + {:#x} pages)",
|
||||||
|
Loading…
Reference in New Issue
Block a user