mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-03 13:11:31 +00:00
actually allocate max memory
This commit is contained in:
@ -6,7 +6,7 @@ use crate::sys::{
|
|||||||
};
|
};
|
||||||
use crate::{XenCall, XenCallError};
|
use crate::{XenCall, XenCallError};
|
||||||
use std::ffi::c_ulong;
|
use std::ffi::c_ulong;
|
||||||
use std::ptr::addr_of;
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
pub struct DomainControl<'a> {
|
pub struct DomainControl<'a> {
|
||||||
call: &'a XenCall,
|
call: &'a XenCall,
|
||||||
@ -18,7 +18,7 @@ impl DomainControl<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_domain_info(&self, domid: u32) -> Result<GetDomainInfo, XenCallError> {
|
pub fn get_domain_info(&self, domid: u32) -> Result<GetDomainInfo, XenCallError> {
|
||||||
let domctl = DomCtl {
|
let mut domctl = DomCtl {
|
||||||
cmd: XEN_DOMCTL_GETDOMAININFO,
|
cmd: XEN_DOMCTL_GETDOMAININFO,
|
||||||
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
||||||
domid,
|
domid,
|
||||||
@ -48,24 +48,24 @@ impl DomainControl<'_> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
self.call
|
self.call
|
||||||
.hypercall1(HYPERVISOR_DOMCTL, addr_of!(domctl) as c_ulong)?;
|
.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong)?;
|
||||||
Ok(unsafe { domctl.value.get_domain_info })
|
Ok(unsafe { domctl.value.get_domain_info })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_domain(&self, create_domain: CreateDomain) -> Result<u32, XenCallError> {
|
pub fn create_domain(&self, create_domain: CreateDomain) -> Result<u32, XenCallError> {
|
||||||
let domctl = DomCtl {
|
let mut domctl = DomCtl {
|
||||||
cmd: XEN_DOMCTL_CREATEDOMAIN,
|
cmd: XEN_DOMCTL_CREATEDOMAIN,
|
||||||
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
||||||
domid: 0,
|
domid: 0,
|
||||||
value: DomCtlValue { create_domain },
|
value: DomCtlValue { create_domain },
|
||||||
};
|
};
|
||||||
self.call
|
self.call
|
||||||
.hypercall1(HYPERVISOR_DOMCTL, addr_of!(domctl) as c_ulong)?;
|
.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong)?;
|
||||||
Ok(domctl.domid)
|
Ok(domctl.domid)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_max_mem(&mut self, domid: u32, memkb: u64) -> Result<(), XenCallError> {
|
pub fn set_max_mem(&self, domid: u32, memkb: u64) -> Result<(), XenCallError> {
|
||||||
let domctl = DomCtl {
|
let mut domctl = DomCtl {
|
||||||
cmd: XEN_DOMCTL_MAX_MEM,
|
cmd: XEN_DOMCTL_MAX_MEM,
|
||||||
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
||||||
domid,
|
domid,
|
||||||
@ -74,12 +74,12 @@ impl DomainControl<'_> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
self.call
|
self.call
|
||||||
.hypercall1(HYPERVISOR_DOMCTL, addr_of!(domctl) as c_ulong)?;
|
.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_max_vcpus(&mut self, domid: u32, max_vcpus: u32) -> Result<(), XenCallError> {
|
pub fn set_max_vcpus(&self, domid: u32, max_vcpus: u32) -> Result<(), XenCallError> {
|
||||||
let domctl = DomCtl {
|
let mut domctl = DomCtl {
|
||||||
cmd: XEN_DOMCTL_MAX_VCPUS,
|
cmd: XEN_DOMCTL_MAX_VCPUS,
|
||||||
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
||||||
domid,
|
domid,
|
||||||
@ -88,12 +88,12 @@ impl DomainControl<'_> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
self.call
|
self.call
|
||||||
.hypercall1(HYPERVISOR_DOMCTL, addr_of!(domctl) as c_ulong)?;
|
.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hypercall_init(&self, domid: u32, gmfn: u64) -> Result<(), XenCallError> {
|
pub fn hypercall_init(&self, domid: u32, gmfn: u64) -> Result<(), XenCallError> {
|
||||||
let domctl = DomCtl {
|
let mut domctl = DomCtl {
|
||||||
cmd: XEN_DOMCTL_HYPERCALL_INIT,
|
cmd: XEN_DOMCTL_HYPERCALL_INIT,
|
||||||
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
||||||
domid,
|
domid,
|
||||||
@ -102,19 +102,19 @@ impl DomainControl<'_> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
self.call
|
self.call
|
||||||
.hypercall1(HYPERVISOR_DOMCTL, addr_of!(domctl) as c_ulong)?;
|
.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy_domain(&self, domid: u32) -> Result<(), XenCallError> {
|
pub fn destroy_domain(&self, domid: u32) -> Result<(), XenCallError> {
|
||||||
let domctl = DomCtl {
|
let mut domctl = DomCtl {
|
||||||
cmd: XEN_DOMCTL_DESTROYDOMAIN,
|
cmd: XEN_DOMCTL_DESTROYDOMAIN,
|
||||||
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
|
||||||
domid,
|
domid,
|
||||||
value: DomCtlValue { pad: [0; 128] },
|
value: DomCtlValue { pad: [0; 128] },
|
||||||
};
|
};
|
||||||
self.call
|
self.call
|
||||||
.hypercall1(HYPERVISOR_DOMCTL, addr_of!(domctl) as c_ulong)?;
|
.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use std::ffi::{c_long, c_ulong, c_void};
|
|||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::os::fd::AsRawFd;
|
use std::os::fd::AsRawFd;
|
||||||
use std::ptr::addr_of;
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
pub struct XenCall {
|
pub struct XenCall {
|
||||||
pub handle: File,
|
pub handle: File,
|
||||||
@ -143,7 +143,7 @@ impl XenCall {
|
|||||||
pub fn mmap_batch(
|
pub fn mmap_batch(
|
||||||
&self,
|
&self,
|
||||||
domid: u32,
|
domid: u32,
|
||||||
count: u64,
|
num: u64,
|
||||||
addr: u64,
|
addr: u64,
|
||||||
mfns: Vec<u64>,
|
mfns: Vec<u64>,
|
||||||
) -> Result<c_long, XenCallError> {
|
) -> Result<c_long, XenCallError> {
|
||||||
@ -151,7 +151,7 @@ impl XenCall {
|
|||||||
let mut mfns = mfns.clone();
|
let mut mfns = mfns.clone();
|
||||||
let mut errors = vec![0i32; mfns.len()];
|
let mut errors = vec![0i32; mfns.len()];
|
||||||
let mut batch = MmapBatch {
|
let mut batch = MmapBatch {
|
||||||
num: count as u32,
|
num: num as u32,
|
||||||
domid: domid as u16,
|
domid: domid as u16,
|
||||||
addr,
|
addr,
|
||||||
mfns: mfns.as_mut_ptr(),
|
mfns: mfns.as_mut_ptr(),
|
||||||
@ -163,13 +163,13 @@ impl XenCall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_version_capabilities(&self) -> Result<XenCapabilitiesInfo, XenCallError> {
|
pub fn get_version_capabilities(&self) -> Result<XenCapabilitiesInfo, XenCallError> {
|
||||||
let info = XenCapabilitiesInfo {
|
let mut info = XenCapabilitiesInfo {
|
||||||
capabilities: [0; 1024],
|
capabilities: [0; 1024],
|
||||||
};
|
};
|
||||||
self.hypercall2(
|
self.hypercall2(
|
||||||
HYPERVISOR_XEN_VERSION,
|
HYPERVISOR_XEN_VERSION,
|
||||||
XENVER_CAPABILITIES,
|
XENVER_CAPABILITIES,
|
||||||
addr_of!(info) as c_ulong,
|
addr_of_mut!(info) as c_ulong,
|
||||||
)?;
|
)?;
|
||||||
Ok(info)
|
Ok(info)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use crate::{XenCall, XenCallError};
|
|||||||
|
|
||||||
use std::ffi::c_ulong;
|
use std::ffi::c_ulong;
|
||||||
|
|
||||||
use std::ptr::addr_of;
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
pub struct MemoryControl<'a> {
|
pub struct MemoryControl<'a> {
|
||||||
call: &'a XenCall,
|
call: &'a XenCall,
|
||||||
@ -22,19 +22,28 @@ impl MemoryControl<'_> {
|
|||||||
mem_flags: u32,
|
mem_flags: u32,
|
||||||
extent_starts: &[u64],
|
extent_starts: &[u64],
|
||||||
) -> Result<Vec<u64>, XenCallError> {
|
) -> Result<Vec<u64>, XenCallError> {
|
||||||
let extent_starts = extent_starts.to_vec();
|
let mut extent_starts = extent_starts.to_vec();
|
||||||
let reservation = MemoryReservation {
|
let mut reservation = MemoryReservation {
|
||||||
extent_start: addr_of!(extent_starts) as c_ulong,
|
extent_start: extent_starts.as_mut_ptr() as c_ulong,
|
||||||
nr_extents,
|
nr_extents,
|
||||||
extent_order,
|
extent_order,
|
||||||
mem_flags,
|
mem_flags,
|
||||||
domid: domid as u16,
|
domid: domid as u16,
|
||||||
};
|
};
|
||||||
self.call.hypercall2(
|
let code = self.call.hypercall2(
|
||||||
HYPERVISOR_MEMORY_OP,
|
HYPERVISOR_MEMORY_OP,
|
||||||
XEN_MEM_POPULATE_PHYSMAP as c_ulong,
|
XEN_MEM_POPULATE_PHYSMAP as c_ulong,
|
||||||
addr_of!(reservation) as c_ulong,
|
addr_of_mut!(reservation) as c_ulong,
|
||||||
)?;
|
)?;
|
||||||
Ok(extent_starts)
|
|
||||||
|
if code < 0 {
|
||||||
|
return Err(XenCallError::new("failed to populate physmap"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if code as usize > extent_starts.len() {
|
||||||
|
return Err(XenCallError::new("failed to populate physmap"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(extent_starts[0..code as usize].to_vec())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ fn main() -> Result<(), XenClientError> {
|
|||||||
let image_info = image_loader.parse()?;
|
let image_info = image_loader.parse()?;
|
||||||
println!("loaded kernel image into memory: {:?}", image_info);
|
println!("loaded kernel image into memory: {:?}", image_info);
|
||||||
let memctl = MemoryControl::new(&call);
|
let memctl = MemoryControl::new(&call);
|
||||||
let mut boot = BootSetup::new(&call, &domctl, &memctl, domid, 512 * 1024);
|
let mut boot = BootSetup::new(&call, &domctl, &memctl, domid);
|
||||||
boot.initialize(image_info)?;
|
boot.initialize(image_info, 512 * 1024)?;
|
||||||
domctl.destroy_domain(domid)?;
|
domctl.destroy_domain(domid)?;
|
||||||
println!("domain destroyed: {}", domid);
|
println!("domain destroyed: {}", domid);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -30,7 +30,6 @@ pub struct BootSetup<'a> {
|
|||||||
memctl: &'a MemoryControl<'a>,
|
memctl: &'a MemoryControl<'a>,
|
||||||
phys: PhysicalPages<'a>,
|
phys: PhysicalPages<'a>,
|
||||||
domid: u32,
|
domid: u32,
|
||||||
memkb: u64,
|
|
||||||
virt_alloc_end: u64,
|
virt_alloc_end: u64,
|
||||||
pfn_alloc_end: u64,
|
pfn_alloc_end: u64,
|
||||||
}
|
}
|
||||||
@ -55,23 +54,20 @@ impl BootSetup<'_> {
|
|||||||
domctl: &'a DomainControl<'a>,
|
domctl: &'a DomainControl<'a>,
|
||||||
memctl: &'a MemoryControl<'a>,
|
memctl: &'a MemoryControl<'a>,
|
||||||
domid: u32,
|
domid: u32,
|
||||||
memkb: u64,
|
|
||||||
) -> BootSetup<'a> {
|
) -> BootSetup<'a> {
|
||||||
BootSetup {
|
BootSetup {
|
||||||
domctl,
|
domctl,
|
||||||
memctl,
|
memctl,
|
||||||
phys: PhysicalPages::new(call, domid),
|
phys: PhysicalPages::new(call, domid),
|
||||||
domid,
|
domid,
|
||||||
memkb,
|
|
||||||
virt_alloc_end: 0,
|
virt_alloc_end: 0,
|
||||||
pfn_alloc_end: 0,
|
pfn_alloc_end: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_memory(&mut self) -> Result<(), XenClientError> {
|
fn initialize_memory(&mut self, memkb: u64) -> Result<(), XenClientError> {
|
||||||
let mem_mb: u64 = self.memkb / 1024;
|
let mem_mb: u64 = memkb / 1024;
|
||||||
let page_count: u64 = mem_mb << (20 - XEN_PAGE_SHIFT);
|
let page_count: u64 = mem_mb << (20 - XEN_PAGE_SHIFT);
|
||||||
let mut pfn_base_idx: u64 = 0;
|
|
||||||
let mut vmemranges: Vec<VmemRange> = Vec::new();
|
let mut vmemranges: Vec<VmemRange> = Vec::new();
|
||||||
let stub = VmemRange {
|
let stub = VmemRange {
|
||||||
start: 0,
|
start: 0,
|
||||||
@ -105,15 +101,20 @@ impl BootSetup<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut super_pages = pages >> SUPERPAGE_2MB_SHIFT;
|
let mut super_pages = pages >> SUPERPAGE_2MB_SHIFT;
|
||||||
|
let mut pfn_base_idx: u64 = pfn_base;
|
||||||
while super_pages > 0 {
|
while super_pages > 0 {
|
||||||
let count = super_pages.min(SUPERPAGE_BATCH_SIZE);
|
let count = super_pages.min(SUPERPAGE_BATCH_SIZE);
|
||||||
super_pages -= count;
|
super_pages -= count;
|
||||||
|
|
||||||
for (i, pfn) in (pfn_base_idx..(count << SUPERPAGE_2MB_SHIFT))
|
let mut j: usize = 0;
|
||||||
.step_by(SUPERPAGE_2MB_NR_PFNS as usize)
|
let mut pfn: u64 = pfn_base_idx;
|
||||||
.enumerate()
|
loop {
|
||||||
{
|
if pfn >= pfn_base_idx + (count << SUPERPAGE_2MB_SHIFT) {
|
||||||
extents[i] = p2m[pfn as usize];
|
break;
|
||||||
|
}
|
||||||
|
extents[j] = p2m[pfn as usize];
|
||||||
|
pfn += SUPERPAGE_2MB_NR_PFNS;
|
||||||
|
j += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let starts = self.memctl.populate_physmap(
|
let starts = self.memctl.populate_physmap(
|
||||||
@ -124,31 +125,36 @@ impl BootSetup<'_> {
|
|||||||
extents.as_slice(),
|
extents.as_slice(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let pfn = pfn_base;
|
pfn = pfn_base_idx;
|
||||||
for mfn in starts {
|
for mfn in starts {
|
||||||
for k in 0..SUPERPAGE_2MB_NR_PFNS {
|
for k in 0..SUPERPAGE_2MB_NR_PFNS {
|
||||||
p2m[pfn as usize] = mfn + k;
|
p2m[pfn as usize] = mfn + k;
|
||||||
|
pfn += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pfn_base_idx = pfn;
|
pfn_base_idx = pfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut j = pfn_base_idx - pfn_base;
|
let mut j = pfn_base_idx - pfn_base;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if j >= pages {
|
if j >= pages {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let allocsz = (pages - j).min(1024 * 1024);
|
let allocsz = (1024 * 1024).min(pages - j);
|
||||||
let result = self.memctl.populate_physmap(
|
let p2m_idx = (pfn_base + j) as usize;
|
||||||
self.domid,
|
let extent_start = p2m[p2m_idx];
|
||||||
allocsz,
|
let result =
|
||||||
0,
|
self.memctl
|
||||||
0,
|
.populate_physmap(self.domid, allocsz, 0, 0, &[extent_start])?;
|
||||||
&[p2m[(pfn_base + j) as usize]],
|
|
||||||
)?;
|
if result.len() != allocsz as usize {
|
||||||
p2m[(pfn_base + j) as usize] = result[0];
|
return Err(XenClientError::new(
|
||||||
|
format!("failed to populate physmap: {:?}", result).as_str(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
p2m[p2m_idx] = result[0];
|
||||||
j += allocsz;
|
j += allocsz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,8 +171,13 @@ impl BootSetup<'_> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initialize(&mut self, image_info: BootImageInfo) -> Result<(), XenClientError> {
|
pub fn initialize(
|
||||||
self.initialize_memory()?;
|
&mut self,
|
||||||
|
image_info: BootImageInfo,
|
||||||
|
memkb: u64,
|
||||||
|
) -> Result<(), XenClientError> {
|
||||||
|
self.domctl.set_max_mem(self.domid, memkb)?;
|
||||||
|
self.initialize_memory(memkb)?;
|
||||||
let _kernel_segment = self.alloc_segment(image_info.virt_kend - image_info.virt_kstart)?;
|
let _kernel_segment = self.alloc_segment(image_info.virt_kend - image_info.virt_kstart)?;
|
||||||
self.initialize_hypercall(image_info)?;
|
self.initialize_hypercall(image_info)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -41,11 +41,7 @@ impl DomainConfig {
|
|||||||
self.put_domain("memory/videoram", videokb.to_string());
|
self.put_domain("memory/videoram", videokb.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn configure_cpus(&mut self, maxvcpus: u32) {
|
pub fn configure_cpus(&mut self, _maxvcpus: u32) {}
|
||||||
for i in 0..maxvcpus {
|
|
||||||
println!("{}", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn configure_pv(&mut self, pv: PvDomainConfig) {
|
pub fn configure_pv(&mut self, pv: PvDomainConfig) {
|
||||||
self.put_vm_str("image/ostype", "linux");
|
self.put_vm_str("image/ostype", "linux");
|
||||||
|
@ -7,7 +7,7 @@ use xencall::XenCall;
|
|||||||
pub struct PhysicalPage {
|
pub struct PhysicalPage {
|
||||||
pfn: u64,
|
pfn: u64,
|
||||||
ptr: u64,
|
ptr: u64,
|
||||||
size: u64,
|
count: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PhysicalPages<'a> {
|
pub struct PhysicalPages<'a> {
|
||||||
@ -33,7 +33,7 @@ impl PhysicalPages<'_> {
|
|||||||
|
|
||||||
pub fn pfn_to_ptr(&mut self, pfn: u64, count: u64) -> Result<u64, XenClientError> {
|
pub fn pfn_to_ptr(&mut self, pfn: u64, count: u64) -> Result<u64, XenClientError> {
|
||||||
for page in &self.pages {
|
for page in &self.pages {
|
||||||
if pfn >= page.pfn + page.size {
|
if pfn >= page.pfn + page.count {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ impl PhysicalPages<'_> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if pfn < page.pfn || (pfn + count) > page.pfn + page.size {
|
if pfn < page.pfn || (pfn + count) > page.pfn + page.count {
|
||||||
return Err(XenClientError::new("request overlaps allocated block"));
|
return Err(XenClientError::new("request overlaps allocated block"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -50,7 +50,7 @@ impl PhysicalPages<'_> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if pfn >= page.pfn + page.size {
|
if pfn >= page.pfn + page.count {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ impl PhysicalPages<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let size = (num as u64) << XEN_PAGE_SHIFT;
|
let size = count << XEN_PAGE_SHIFT;
|
||||||
let addr = self
|
let addr = self
|
||||||
.call
|
.call
|
||||||
.mmap(0, size)
|
.mmap(0, size)
|
||||||
@ -91,7 +91,7 @@ impl PhysicalPages<'_> {
|
|||||||
let page = PhysicalPage {
|
let page = PhysicalPage {
|
||||||
pfn,
|
pfn,
|
||||||
ptr: addr,
|
ptr: addr,
|
||||||
size,
|
count,
|
||||||
};
|
};
|
||||||
self.pages.push(page);
|
self.pages.push(page);
|
||||||
Ok(addr)
|
Ok(addr)
|
||||||
|
Reference in New Issue
Block a user