mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 12:50:54 +00:00
fix(xenplatform): e820 sanitize should now produce valid mappings
This commit is contained in:
parent
b1e7a05440
commit
7f5a8c7a6e
@ -22,6 +22,10 @@ name = "xencall"
|
||||
[dev-dependencies]
|
||||
env_logger = { workspace = true }
|
||||
|
||||
[[example]]
|
||||
name = "xencall-cpu-topology"
|
||||
path = "examples/cpu_topology.rs"
|
||||
|
||||
[[example]]
|
||||
name = "xencall-domain-info"
|
||||
path = "examples/domain_info.rs"
|
||||
|
@ -1,5 +1,4 @@
|
||||
use xencall::error::Result;
|
||||
use xencall::sys::CpuId;
|
||||
use xencall::XenCall;
|
||||
|
||||
#[tokio::main]
|
||||
@ -11,9 +10,5 @@ async fn main() -> Result<()> {
|
||||
println!("{:?}", physinfo);
|
||||
let topology = call.cpu_topology().await?;
|
||||
println!("{:?}", topology);
|
||||
call.set_cpufreq_gov(CpuId::All, "performance").await?;
|
||||
call.set_cpufreq_gov(CpuId::Single(0), "performance")
|
||||
.await?;
|
||||
call.set_turbo_mode(CpuId::All, true).await?;
|
||||
Ok(())
|
||||
}
|
@ -7,8 +7,6 @@ async fn main() -> Result<()> {
|
||||
env_logger::init();
|
||||
|
||||
let call = XenCall::open(0)?;
|
||||
let physinfo = call.phys_info().await?;
|
||||
println!("{:?}", physinfo);
|
||||
let topology = call.cpu_topology().await?;
|
||||
println!("{:?}", topology);
|
||||
call.set_cpufreq_gov(CpuId::All, "performance").await?;
|
||||
|
@ -10,10 +10,11 @@ use crate::sys::{
|
||||
PciAssignDevice, XenCapabilitiesInfo, DOMCTL_DEV_PCI, HYPERVISOR_DOMCTL,
|
||||
HYPERVISOR_EVENT_CHANNEL_OP, HYPERVISOR_HVM_OP, HYPERVISOR_MEMORY_OP, HYPERVISOR_MMUEXT_OP,
|
||||
HYPERVISOR_MULTICALL, HYPERVISOR_XEN_VERSION, XENVER_CAPABILITIES, XEN_DOMCTL_ASSIGN_DEVICE,
|
||||
XEN_DOMCTL_CREATEDOMAIN, XEN_DOMCTL_DESTROYDOMAIN, XEN_DOMCTL_GETDOMAININFO,
|
||||
XEN_DOMCTL_GETHVMCONTEXT, XEN_DOMCTL_GETPAGEFRAMEINFO3, XEN_DOMCTL_HYPERCALL_INIT,
|
||||
XEN_DOMCTL_IOMEM_PERMISSION, XEN_DOMCTL_IOPORT_PERMISSION, XEN_DOMCTL_IRQ_PERMISSION,
|
||||
XEN_DOMCTL_MAX_MEM, XEN_DOMCTL_MAX_VCPUS, XEN_DOMCTL_PAUSEDOMAIN, XEN_DOMCTL_SETHVMCONTEXT,
|
||||
XEN_DOMCTL_CREATEDOMAIN, XEN_DOMCTL_CREATE_DOMAIN2_INTERFACE_THRESHOLD,
|
||||
XEN_DOMCTL_DESTROYDOMAIN, XEN_DOMCTL_GETDOMAININFO, XEN_DOMCTL_GETHVMCONTEXT,
|
||||
XEN_DOMCTL_GETPAGEFRAMEINFO3, XEN_DOMCTL_HYPERCALL_INIT, XEN_DOMCTL_IOMEM_PERMISSION,
|
||||
XEN_DOMCTL_IOPORT_PERMISSION, XEN_DOMCTL_IRQ_PERMISSION, XEN_DOMCTL_MAX_MEM,
|
||||
XEN_DOMCTL_MAX_VCPUS, XEN_DOMCTL_PAUSEDOMAIN, XEN_DOMCTL_SETHVMCONTEXT,
|
||||
XEN_DOMCTL_SETVCPUCONTEXT, XEN_DOMCTL_SET_ADDRESS_SIZE, XEN_DOMCTL_SET_PAGING_MEMPOOL_SIZE,
|
||||
XEN_DOMCTL_UNPAUSEDOMAIN, XEN_MEM_ADD_TO_PHYSMAP, XEN_MEM_CLAIM_PAGES, XEN_MEM_MEMORY_MAP,
|
||||
XEN_MEM_POPULATE_PHYSMAP,
|
||||
@ -25,10 +26,11 @@ use std::ffi::{c_long, c_uint, c_ulong, c_void};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use sys::{
|
||||
CpuId, E820Entry, ForeignMemoryMap, PhysdevMapPirq, Sysctl, SysctlCputopo, SysctlCputopoinfo,
|
||||
SysctlPhysinfo, SysctlPmOp, SysctlPmOpValue, SysctlReadconsole, SysctlSetCpuFreqGov,
|
||||
SysctlValue, VcpuGuestContextAny, HYPERVISOR_PHYSDEV_OP, HYPERVISOR_SYSCTL, PHYSDEVOP_MAP_PIRQ,
|
||||
XEN_DOMCTL_MAX_INTERFACE_VERSION, XEN_DOMCTL_MIN_INTERFACE_VERSION, XEN_MEM_SET_MEMORY_MAP,
|
||||
CpuId, E820Entry, ForeignMemoryMap, PhysdevMapPirq, SetDomainHandle, Sysctl, SysctlCputopo,
|
||||
SysctlCputopoinfo, SysctlPhysinfo, SysctlPmOp, SysctlPmOpValue, SysctlReadconsole,
|
||||
SysctlSetCpuFreqGov, SysctlValue, VcpuGuestContextAny, HYPERVISOR_PHYSDEV_OP,
|
||||
HYPERVISOR_SYSCTL, PHYSDEVOP_MAP_PIRQ, XEN_DOMCTL_MAX_INTERFACE_VERSION,
|
||||
XEN_DOMCTL_MIN_INTERFACE_VERSION, XEN_DOMCTL_SETDOMAINHANDLE, XEN_MEM_SET_MEMORY_MAP,
|
||||
XEN_SYSCTL_CPUTOPOINFO, XEN_SYSCTL_MAX_INTERFACE_VERSION, XEN_SYSCTL_MIN_INTERFACE_VERSION,
|
||||
XEN_SYSCTL_PHYSINFO, XEN_SYSCTL_PM_OP, XEN_SYSCTL_PM_OP_DISABLE_TURBO,
|
||||
XEN_SYSCTL_PM_OP_ENABLE_TURBO, XEN_SYSCTL_PM_OP_SET_CPUFREQ_GOV, XEN_SYSCTL_READCONSOLE,
|
||||
@ -366,6 +368,28 @@ impl XenCall {
|
||||
Ok(alloc_unbound.port)
|
||||
}
|
||||
|
||||
pub async fn set_domain_handle(&self, domid: u32, domain_handle: [u8; 16]) -> Result<()> {
|
||||
trace!(
|
||||
"domctl fd={} set_domain_handle domid={} handle={:?}",
|
||||
self.handle.as_raw_fd(),
|
||||
domid,
|
||||
domain_handle,
|
||||
);
|
||||
let mut domctl = DomCtl {
|
||||
cmd: XEN_DOMCTL_SETDOMAINHANDLE,
|
||||
interface_version: self.domctl_interface_version,
|
||||
domid,
|
||||
value: DomCtlValue {
|
||||
set_domain_handle: SetDomainHandle {
|
||||
handle: domain_handle,
|
||||
},
|
||||
},
|
||||
};
|
||||
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_domain_info(&self, domid: u32) -> Result<GetDomainInfo> {
|
||||
trace!(
|
||||
"domctl fd={} get_domain_info domid={}",
|
||||
@ -395,7 +419,14 @@ impl XenCall {
|
||||
cmd: XEN_DOMCTL_CREATEDOMAIN,
|
||||
interface_version: self.domctl_interface_version,
|
||||
domid: 0,
|
||||
value: DomCtlValue { create_domain },
|
||||
value: if self.domctl_interface_version >= XEN_DOMCTL_CREATE_DOMAIN2_INTERFACE_THRESHOLD
|
||||
{
|
||||
DomCtlValue {
|
||||
create_domain2: create_domain.to_cd_2(),
|
||||
}
|
||||
} else {
|
||||
DomCtlValue { create_domain }
|
||||
},
|
||||
};
|
||||
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong)
|
||||
.await?;
|
||||
|
@ -231,6 +231,7 @@ pub struct AddressSize {
|
||||
#[derive(Copy, Clone)]
|
||||
pub union DomCtlValue {
|
||||
pub create_domain: CreateDomain,
|
||||
pub create_domain2: CreateDomain2,
|
||||
pub get_domain_info: GetDomainInfo,
|
||||
pub max_mem: MaxMem,
|
||||
pub max_cpus: MaxVcpus,
|
||||
@ -244,6 +245,7 @@ pub union DomCtlValue {
|
||||
pub assign_device: AssignDevice,
|
||||
pub hvm_context: HvmContext,
|
||||
pub paging_mempool: PagingMempool,
|
||||
pub set_domain_handle: SetDomainHandle,
|
||||
pub pad: [u8; 128],
|
||||
}
|
||||
|
||||
@ -264,6 +266,24 @@ pub struct CreateDomain {
|
||||
pub arch_domain_config: ArchDomainConfig,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct CreateDomain2 {
|
||||
pub ssidref: u32,
|
||||
pub handle: [u8; 16],
|
||||
pub flags: u32,
|
||||
pub iommu_opts: u32,
|
||||
pub max_vcpus: u32,
|
||||
pub max_evtchn_port: u32,
|
||||
pub max_grant_frames: i32,
|
||||
pub max_maptrack_frames: i32,
|
||||
pub grant_opts: u32,
|
||||
pub altp2m_opts: u32,
|
||||
pub vmtrace_size: u32,
|
||||
pub cpupool_id: u32,
|
||||
pub arch_domain_config: ArchDomainConfig,
|
||||
}
|
||||
|
||||
impl Default for CreateDomain {
|
||||
fn default() -> Self {
|
||||
CreateDomain {
|
||||
@ -283,6 +303,32 @@ impl Default for CreateDomain {
|
||||
}
|
||||
}
|
||||
|
||||
impl CreateDomain {
|
||||
pub fn to_cd_2(self) -> CreateDomain2 {
|
||||
CreateDomain2 {
|
||||
ssidref: self.ssidref,
|
||||
handle: self.handle,
|
||||
flags: self.flags,
|
||||
iommu_opts: self.iommu_opts,
|
||||
max_vcpus: self.max_vcpus,
|
||||
max_evtchn_port: self.max_evtchn_port,
|
||||
max_grant_frames: self.max_grant_frames,
|
||||
max_maptrack_frames: self.max_maptrack_frames,
|
||||
grant_opts: self.grant_opts,
|
||||
altp2m_opts: 0,
|
||||
vmtrace_size: self.vmtrace_size,
|
||||
cpupool_id: self.cpupool_id,
|
||||
arch_domain_config: self.arch_domain_config,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct SetDomainHandle {
|
||||
pub handle: [u8; 16],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct GetDomainInfo {
|
||||
@ -377,7 +423,8 @@ pub struct HypercallInit {
|
||||
}
|
||||
|
||||
pub const XEN_DOMCTL_MIN_INTERFACE_VERSION: u32 = 0x00000015;
|
||||
pub const XEN_DOMCTL_MAX_INTERFACE_VERSION: u32 = 0x00000016;
|
||||
pub const XEN_DOMCTL_MAX_INTERFACE_VERSION: u32 = 0x00000017;
|
||||
pub const XEN_DOMCTL_CREATE_DOMAIN2_INTERFACE_THRESHOLD: u32 = 0x00000017;
|
||||
|
||||
pub const SECINITSID_DOMU: u32 = 12;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "krata-xenevtchn"
|
||||
description = "An implementation of Xen evtchn for krata"
|
||||
description = "An implementation of Xen evtchn for krata."
|
||||
license.workspace = true
|
||||
version.workspace = true
|
||||
homepage.workspace = true
|
||||
|
@ -287,7 +287,6 @@ impl X86PvPlatform {
|
||||
&self,
|
||||
mut source: Vec<E820Entry>,
|
||||
map_limit_kb: u64,
|
||||
balloon_kb: u64,
|
||||
) -> Result<Vec<E820Entry>> {
|
||||
let mut e820 = vec![E820Entry::default(); E820_MAX as usize];
|
||||
|
||||
@ -323,111 +322,10 @@ impl X86PvPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
let start_kb = if lowest > 1024 { lowest >> 10 } else { 0 };
|
||||
e820[0].addr = 0;
|
||||
e820[0].size = map_limit_kb << 10;
|
||||
e820[0].typ = E820_RAM;
|
||||
|
||||
let mut idx: usize = 0;
|
||||
|
||||
e820[idx].addr = 0;
|
||||
e820[idx].size = map_limit_kb << 10;
|
||||
e820[idx].typ = E820_RAM;
|
||||
|
||||
let mut delta_kb = 0u64;
|
||||
|
||||
if start_kb > 0 && map_limit_kb > start_kb {
|
||||
delta_kb = map_limit_kb - start_kb;
|
||||
if delta_kb > 0 {
|
||||
e820[idx].size -= delta_kb << 10;
|
||||
}
|
||||
}
|
||||
|
||||
let ram_end = source[0].addr + source[0].size;
|
||||
idx += 1;
|
||||
|
||||
for src in &mut source {
|
||||
let end = src.addr + src.size;
|
||||
if src.typ == E820_UNUSABLE || end < ram_end {
|
||||
src.typ = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if src.typ != E820_RAM {
|
||||
continue;
|
||||
}
|
||||
|
||||
if src.addr >= (1 << 32) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if src.addr < ram_end {
|
||||
let delta = ram_end - src.addr;
|
||||
src.typ = E820_UNUSABLE;
|
||||
|
||||
if src.size < delta {
|
||||
src.typ = 0;
|
||||
} else {
|
||||
src.size -= delta;
|
||||
src.addr = ram_end;
|
||||
}
|
||||
|
||||
if src.addr + src.size != end {
|
||||
src.typ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if end > ram_end {
|
||||
src.typ = E820_UNUSABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if lowest > ram_end {
|
||||
let mut add_unusable = true;
|
||||
|
||||
for src in &mut source {
|
||||
if !add_unusable {
|
||||
break;
|
||||
}
|
||||
|
||||
if src.typ != E820_UNUSABLE {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ram_end != src.addr {
|
||||
continue;
|
||||
}
|
||||
|
||||
if lowest != src.addr + src.size {
|
||||
src.size = lowest - src.addr;
|
||||
}
|
||||
add_unusable = false;
|
||||
}
|
||||
|
||||
if add_unusable {
|
||||
e820[1].typ = E820_UNUSABLE;
|
||||
e820[1].addr = ram_end;
|
||||
e820[1].size = lowest - ram_end;
|
||||
}
|
||||
}
|
||||
|
||||
for src in &source {
|
||||
if src.typ == E820_RAM || src.typ == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
e820[idx].typ = src.typ;
|
||||
e820[idx].addr = src.addr;
|
||||
e820[idx].size = src.size;
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
if balloon_kb > 0 || delta_kb > 0 {
|
||||
e820[idx].typ = E820_RAM;
|
||||
e820[idx].addr = if (1u64 << 32u64) > highest {
|
||||
1u64 << 32u64
|
||||
} else {
|
||||
highest
|
||||
};
|
||||
e820[idx].size = (delta_kb << 10) + (balloon_kb << 10);
|
||||
}
|
||||
Ok(e820)
|
||||
}
|
||||
}
|
||||
@ -831,7 +729,7 @@ impl BootSetupPlatform for X86PvPlatform {
|
||||
let map = domain.call.get_memory_map(E820_MAX).await?;
|
||||
let mem_mb = domain.total_pages >> (20 - self.page_shift());
|
||||
let mem_kb = mem_mb * 1024;
|
||||
let e820 = self.e820_sanitize(map, mem_kb, 0)?;
|
||||
let e820 = self.e820_sanitize(map, mem_kb)?;
|
||||
domain.call.set_memory_map(domain.domid, e820).await?;
|
||||
|
||||
domain
|
||||
|
Loading…
Reference in New Issue
Block a user