mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 21:00:55 +00:00
xenclient: convert to using thiserror
This commit is contained in:
parent
890a8ee63f
commit
2eb287bf07
@ -182,7 +182,7 @@ impl BootSetup<'_> {
|
|||||||
let addr = self
|
let addr = self
|
||||||
.call
|
.call
|
||||||
.mmap(0, 1 << XEN_PAGE_SHIFT)
|
.mmap(0, 1 << XEN_PAGE_SHIFT)
|
||||||
.ok_or(Error::new("failed to mmap for resource"))?;
|
.ok_or(Error::MmapFailed)?;
|
||||||
self.call.map_resource(self.domid, 1, 0, 0, 1, addr)?;
|
self.call.map_resource(self.domid, 1, 0, 0, 1, addr)?;
|
||||||
let entries = unsafe { slice::from_raw_parts_mut(addr as *mut GrantEntry, 2) };
|
let entries = unsafe { slice::from_raw_parts_mut(addr as *mut GrantEntry, 2) };
|
||||||
entries[0].flags = 1 << 0;
|
entries[0].flags = 1 << 0;
|
||||||
@ -194,7 +194,7 @@ impl BootSetup<'_> {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let result = munmap(addr as *mut c_void, 1 << XEN_PAGE_SHIFT);
|
let result = munmap(addr as *mut c_void, 1 << XEN_PAGE_SHIFT);
|
||||||
if result != 0 {
|
if result != 0 {
|
||||||
return Err(Error::new("failed to unmap resource"));
|
return Err(Error::UnmapFailed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -294,15 +294,11 @@ impl BootSetup<'_> {
|
|||||||
|
|
||||||
fn alloc_padding_pages(&mut self, arch: &mut dyn ArchBootSetup, boundary: u64) -> Result<()> {
|
fn alloc_padding_pages(&mut self, arch: &mut dyn ArchBootSetup, boundary: u64) -> Result<()> {
|
||||||
if (boundary & (arch.page_size() - 1)) != 0 {
|
if (boundary & (arch.page_size() - 1)) != 0 {
|
||||||
return Err(Error::new(
|
return Err(Error::MemorySetupFailed);
|
||||||
format!("segment boundary isn't page aligned: {:#x}", boundary).as_str(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if boundary < self.virt_alloc_end {
|
if boundary < self.virt_alloc_end {
|
||||||
return Err(Error::new(
|
return Err(Error::MemorySetupFailed);
|
||||||
format!("segment boundary too low: {:#x})", boundary).as_str(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
let pages = (boundary - self.virt_alloc_end) / arch.page_size();
|
let pages = (boundary - self.virt_alloc_end) / arch.page_size();
|
||||||
self.chk_alloc_pages(arch, pages)?;
|
self.chk_alloc_pages(arch, pages)?;
|
||||||
@ -314,13 +310,7 @@ impl BootSetup<'_> {
|
|||||||
|| self.pfn_alloc_end > self.total_pages
|
|| self.pfn_alloc_end > self.total_pages
|
||||||
|| pages > self.total_pages - self.pfn_alloc_end
|
|| pages > self.total_pages - self.pfn_alloc_end
|
||||||
{
|
{
|
||||||
return Err(Error::new(
|
return Err(Error::MemorySetupFailed);
|
||||||
format!(
|
|
||||||
"segment too large: pages={} total_pages={} pfn_alloc_end={}",
|
|
||||||
pages, self.total_pages, self.pfn_alloc_end
|
|
||||||
)
|
|
||||||
.as_str(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pfn_alloc_end += pages;
|
self.pfn_alloc_end += pages;
|
||||||
|
@ -8,35 +8,16 @@ use crate::Error;
|
|||||||
use elf::abi::{PF_R, PF_W, PF_X, PT_LOAD, SHT_NOTE};
|
use elf::abi::{PF_R, PF_W, PF_X, PT_LOAD, SHT_NOTE};
|
||||||
use elf::endian::AnyEndian;
|
use elf::endian::AnyEndian;
|
||||||
use elf::note::Note;
|
use elf::note::Note;
|
||||||
use elf::{ElfBytes, ParseError};
|
use elf::ElfBytes;
|
||||||
use flate2::bufread::GzDecoder;
|
use flate2::bufread::GzDecoder;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use memchr::memmem::find_iter;
|
use memchr::memmem::find_iter;
|
||||||
use slice_copy::copy;
|
use slice_copy::copy;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::{FromVecWithNulError, IntoStringError};
|
|
||||||
use std::io::{BufReader, Read};
|
use std::io::{BufReader, Read};
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use xz2::bufread::XzDecoder;
|
use xz2::bufread::XzDecoder;
|
||||||
|
|
||||||
impl From<ParseError> for Error {
|
|
||||||
fn from(value: ParseError) -> Self {
|
|
||||||
Error::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<FromVecWithNulError> for Error {
|
|
||||||
fn from(value: FromVecWithNulError) -> Self {
|
|
||||||
Error::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<IntoStringError> for Error {
|
|
||||||
fn from(value: IntoStringError) -> Self {
|
|
||||||
Error::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ElfImageLoader {
|
pub struct ElfImageLoader {
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
}
|
}
|
||||||
@ -146,9 +127,7 @@ impl ElfImageLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(Error::new(
|
Err(Error::ElfCompressionUnknown)
|
||||||
"Unable to parse kernel image: unknown compression type",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,9 +138,7 @@ struct ElfNoteValue {
|
|||||||
impl BootImageLoader for ElfImageLoader {
|
impl BootImageLoader for ElfImageLoader {
|
||||||
fn parse(&self) -> Result<BootImageInfo> {
|
fn parse(&self) -> Result<BootImageInfo> {
|
||||||
let elf = ElfBytes::<AnyEndian>::minimal_parse(self.data.as_slice())?;
|
let elf = ElfBytes::<AnyEndian>::minimal_parse(self.data.as_slice())?;
|
||||||
let headers = elf.section_headers().ok_or(Error::new(
|
let headers = elf.section_headers().ok_or(Error::ElfInvalidImage)?;
|
||||||
"Unable to parse kernel image: section headers not found.",
|
|
||||||
))?;
|
|
||||||
let mut linux_notes: HashMap<u64, Vec<u8>> = HashMap::new();
|
let mut linux_notes: HashMap<u64, Vec<u8>> = HashMap::new();
|
||||||
let mut xen_notes: HashMap<u64, ElfNoteValue> = HashMap::new();
|
let mut xen_notes: HashMap<u64, ElfNoteValue> = HashMap::new();
|
||||||
|
|
||||||
@ -198,46 +175,42 @@ impl BootImageLoader for ElfImageLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if linux_notes.is_empty() {
|
if linux_notes.is_empty() {
|
||||||
return Err(Error::new(
|
return Err(Error::ElfInvalidImage);
|
||||||
"Provided kernel does not appear to be a Linux kernel image.",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if xen_notes.is_empty() {
|
if xen_notes.is_empty() {
|
||||||
return Err(Error::new("Provided kernel does not have Xen support."));
|
return Err(Error::ElfXenSupportMissing);
|
||||||
}
|
}
|
||||||
|
|
||||||
let paddr_offset = xen_notes
|
let paddr_offset = xen_notes
|
||||||
.get(&XEN_ELFNOTE_PADDR_OFFSET)
|
.get(&XEN_ELFNOTE_PADDR_OFFSET)
|
||||||
.ok_or(Error::new("Unable to find paddr_offset note in kernel."))?
|
.ok_or(Error::ElfInvalidImage)?
|
||||||
.value;
|
.value;
|
||||||
let virt_base = xen_notes
|
let virt_base = xen_notes
|
||||||
.get(&XEN_ELFNOTE_VIRT_BASE)
|
.get(&XEN_ELFNOTE_VIRT_BASE)
|
||||||
.ok_or(Error::new("Unable to find virt_base note in kernel."))?
|
.ok_or(Error::ElfInvalidImage)?
|
||||||
.value;
|
.value;
|
||||||
let entry = xen_notes
|
let entry = xen_notes
|
||||||
.get(&XEN_ELFNOTE_ENTRY)
|
.get(&XEN_ELFNOTE_ENTRY)
|
||||||
.ok_or(Error::new("Unable to find entry note in kernel."))?
|
.ok_or(Error::ElfInvalidImage)?
|
||||||
.value;
|
.value;
|
||||||
let virt_hypercall = xen_notes
|
let virt_hypercall = xen_notes
|
||||||
.get(&XEN_ELFNOTE_HYPERCALL_PAGE)
|
.get(&XEN_ELFNOTE_HYPERCALL_PAGE)
|
||||||
.ok_or(Error::new("Unable to find hypercall_page note in kernel."))?
|
.ok_or(Error::ElfInvalidImage)?
|
||||||
.value;
|
.value;
|
||||||
let init_p2m = xen_notes
|
let init_p2m = xen_notes
|
||||||
.get(&XEN_ELFNOTE_INIT_P2M)
|
.get(&XEN_ELFNOTE_INIT_P2M)
|
||||||
.ok_or(Error::new("Unable to find init_p2m note in kernel."))?
|
.ok_or(Error::ElfInvalidImage)?
|
||||||
.value;
|
.value;
|
||||||
let mod_start_pfn = xen_notes
|
let mod_start_pfn = xen_notes
|
||||||
.get(&XEN_ELFNOTE_MOD_START_PFN)
|
.get(&XEN_ELFNOTE_MOD_START_PFN)
|
||||||
.ok_or(Error::new("Unable to find mod_start_pfn note in kernel."))?
|
.ok_or(Error::ElfInvalidImage)?
|
||||||
.value;
|
.value;
|
||||||
|
|
||||||
let mut start: u64 = u64::MAX;
|
let mut start: u64 = u64::MAX;
|
||||||
let mut end: u64 = 0;
|
let mut end: u64 = 0;
|
||||||
|
|
||||||
let segments = elf.segments().ok_or(Error::new(
|
let segments = elf.segments().ok_or(Error::ElfInvalidImage)?;
|
||||||
"Unable to parse kernel image: segments not found.",
|
|
||||||
))?;
|
|
||||||
|
|
||||||
for header in segments {
|
for header in segments {
|
||||||
if (header.p_type != PT_LOAD) || (header.p_flags & (PF_R | PF_W | PF_X)) == 0 {
|
if (header.p_type != PT_LOAD) || (header.p_flags & (PF_R | PF_W | PF_X)) == 0 {
|
||||||
@ -255,9 +228,7 @@ impl BootImageLoader for ElfImageLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if paddr_offset != XEN_UNSET_ADDR && virt_base == XEN_UNSET_ADDR {
|
if paddr_offset != XEN_UNSET_ADDR && virt_base == XEN_UNSET_ADDR {
|
||||||
return Err(Error::new(
|
return Err(Error::ElfInvalidImage);
|
||||||
"Unable to load kernel image: paddr_offset set but virt_base is unset.",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let virt_offset = virt_base - paddr_offset;
|
let virt_offset = virt_base - paddr_offset;
|
||||||
@ -280,9 +251,7 @@ impl BootImageLoader for ElfImageLoader {
|
|||||||
|
|
||||||
fn load(&self, image_info: &BootImageInfo, dst: &mut [u8]) -> Result<()> {
|
fn load(&self, image_info: &BootImageInfo, dst: &mut [u8]) -> Result<()> {
|
||||||
let elf = ElfBytes::<AnyEndian>::minimal_parse(self.data.as_slice())?;
|
let elf = ElfBytes::<AnyEndian>::minimal_parse(self.data.as_slice())?;
|
||||||
let segments = elf.segments().ok_or(Error::new(
|
let segments = elf.segments().ok_or(Error::ElfInvalidImage)?;
|
||||||
"Unable to parse kernel image: segments not found.",
|
|
||||||
))?;
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"ElfImageLoader load dst={:#x} segments={}",
|
"ElfImageLoader load dst={:#x} segments={}",
|
||||||
|
@ -1,60 +1,39 @@
|
|||||||
use std::fmt::{Display, Formatter};
|
use std::io;
|
||||||
use std::string::FromUtf8Error;
|
|
||||||
use xencall::XenCallError;
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("io issue encountered")]
|
||||||
|
Io(#[from] io::Error),
|
||||||
|
#[error("xenstore issue encountered")]
|
||||||
|
XenStore(#[from] xenstore::error::Error),
|
||||||
|
#[error("xencall issue encountered")]
|
||||||
|
XenCall(#[from] xencall::XenCallError),
|
||||||
|
#[error("domain does not have a tty")]
|
||||||
|
TtyNotFound,
|
||||||
|
#[error("introducing the domain failed")]
|
||||||
|
IntroduceDomainFailed,
|
||||||
|
#[error("string conversion of a path failed")]
|
||||||
|
PathStringConversion,
|
||||||
|
#[error("parent of path not found")]
|
||||||
|
PathParentNotFound,
|
||||||
|
#[error("domain does not exist")]
|
||||||
|
DomainNonExistent,
|
||||||
|
#[error("elf parse failed")]
|
||||||
|
ElfParseFailed(#[from] elf::ParseError),
|
||||||
|
#[error("mmap failed")]
|
||||||
|
MmapFailed,
|
||||||
|
#[error("munmap failed")]
|
||||||
|
UnmapFailed,
|
||||||
|
#[error("memory setup failed")]
|
||||||
|
MemorySetupFailed,
|
||||||
|
#[error("populate physmap failed: wanted={0}, received={1}, input_extents={2}")]
|
||||||
|
PopulatePhysmapFailed(usize, usize, usize),
|
||||||
|
#[error("unknown elf compression method")]
|
||||||
|
ElfCompressionUnknown,
|
||||||
|
#[error("expected elf image format not found")]
|
||||||
|
ElfInvalidImage,
|
||||||
|
#[error("provided elf image does not contain xen support")]
|
||||||
|
ElfXenSupportMissing,
|
||||||
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Error {
|
|
||||||
message: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error {
|
|
||||||
pub fn new(msg: &str) -> Error {
|
|
||||||
Error {
|
|
||||||
message: msg.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Error {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}", self.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::error::Error for Error {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
&self.message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<std::io::Error> for Error {
|
|
||||||
fn from(value: std::io::Error) -> Self {
|
|
||||||
Error::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<xenstore::error::Error> for Error {
|
|
||||||
fn from(value: xenstore::error::Error) -> Self {
|
|
||||||
Error::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<XenCallError> for Error {
|
|
||||||
fn from(value: XenCallError) -> Self {
|
|
||||||
Error::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<FromUtf8Error> for Error {
|
|
||||||
fn from(value: FromUtf8Error) -> Self {
|
|
||||||
Error::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<xenevtchn::error::Error> for Error {
|
|
||||||
fn from(value: xenevtchn::error::Error) -> Self {
|
|
||||||
Error::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -98,7 +98,7 @@ impl XenClient {
|
|||||||
let dom_path = self.store.get_domain_path(domid)?;
|
let dom_path = self.store.get_domain_path(domid)?;
|
||||||
let vm_path = self.store.read_string(&format!("{}/vm", dom_path))?;
|
let vm_path = self.store.read_string(&format!("{}/vm", dom_path))?;
|
||||||
if vm_path.is_empty() {
|
if vm_path.is_empty() {
|
||||||
return Err(Error::new("cannot destroy domain that doesn't exist"));
|
return Err(Error::DomainNonExistent);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut backend_paths: Vec<String> = Vec::new();
|
let mut backend_paths: Vec<String> = Vec::new();
|
||||||
@ -161,12 +161,8 @@ impl XenClient {
|
|||||||
}
|
}
|
||||||
for path in &backend_removals {
|
for path in &backend_removals {
|
||||||
let path = PathBuf::from(path);
|
let path = PathBuf::from(path);
|
||||||
let parent = path
|
let parent = path.parent().ok_or(Error::PathParentNotFound)?;
|
||||||
.parent()
|
tx.rm(parent.to_str().ok_or(Error::PathStringConversion)?)?;
|
||||||
.ok_or(Error::new("unable to get parent of backend path"))?;
|
|
||||||
tx.rm(parent
|
|
||||||
.to_str()
|
|
||||||
.ok_or(Error::new("unable to convert parent to string"))?)?;
|
|
||||||
}
|
}
|
||||||
tx.rm(&vm_path)?;
|
tx.rm(&vm_path)?;
|
||||||
tx.rm(&dom_path)?;
|
tx.rm(&dom_path)?;
|
||||||
@ -336,7 +332,7 @@ impl XenClient {
|
|||||||
.store
|
.store
|
||||||
.introduce_domain(domid, xenstore_mfn, xenstore_evtchn)?
|
.introduce_domain(domid, xenstore_mfn, xenstore_evtchn)?
|
||||||
{
|
{
|
||||||
return Err(Error::new("failed to introduce domain"));
|
return Err(Error::IntroduceDomainFailed);
|
||||||
}
|
}
|
||||||
self.console_device_add(
|
self.console_device_add(
|
||||||
&dom_path,
|
&dom_path,
|
||||||
@ -570,7 +566,7 @@ impl XenClient {
|
|||||||
.read_string_optional(&console_tty_path)?
|
.read_string_optional(&console_tty_path)?
|
||||||
.unwrap_or("".to_string());
|
.unwrap_or("".to_string());
|
||||||
if tty.is_empty() {
|
if tty.is_empty() {
|
||||||
return Err(Error::new(&format!("domain {} does not have a tty", domid)));
|
return Err(Error::TtyNotFound);
|
||||||
}
|
}
|
||||||
let read = OpenOptions::new().read(true).write(false).open(&tty)?;
|
let read = OpenOptions::new().read(true).write(false).open(&tty)?;
|
||||||
let write = OpenOptions::new().read(false).write(true).open(&tty)?;
|
let write = OpenOptions::new().read(false).write(true).open(&tty)?;
|
||||||
|
@ -53,7 +53,7 @@ impl PhysicalPages<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if pfn < page.pfn || (pfn + count) > page.pfn + page.count {
|
if pfn < page.pfn || (pfn + count) > page.pfn + page.count {
|
||||||
return Err(Error::new("request overlaps allocated block"));
|
return Err(Error::MemorySetupFailed);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if pfn < page.pfn {
|
if pfn < page.pfn {
|
||||||
@ -69,9 +69,7 @@ impl PhysicalPages<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return Err(Error::new(
|
return Err(Error::MemorySetupFailed);
|
||||||
"allocation is only allowed when a size is given",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pfn_alloc(pfn, count)
|
self.pfn_alloc(pfn, count)
|
||||||
@ -96,11 +94,11 @@ impl PhysicalPages<'_> {
|
|||||||
let addr = self
|
let addr = self
|
||||||
.call
|
.call
|
||||||
.mmap(0, actual_mmap_len)
|
.mmap(0, actual_mmap_len)
|
||||||
.ok_or(Error::new("failed to mmap address"))?;
|
.ok_or(Error::MmapFailed)?;
|
||||||
debug!("mapped {:#x} foreign bytes at {:#x}", actual_mmap_len, addr);
|
debug!("mapped {:#x} foreign bytes at {:#x}", actual_mmap_len, addr);
|
||||||
let result = self.call.mmap_batch(self.domid, num as u64, addr, pfns)?;
|
let result = self.call.mmap_batch(self.domid, num as u64, addr, pfns)?;
|
||||||
if result != 0 {
|
if result != 0 {
|
||||||
return Err(Error::new("mmap_batch call failed"));
|
return Err(Error::MmapFailed);
|
||||||
}
|
}
|
||||||
let page = PhysicalPage {
|
let page = PhysicalPage {
|
||||||
pfn,
|
pfn,
|
||||||
@ -126,11 +124,11 @@ impl PhysicalPages<'_> {
|
|||||||
let addr = self
|
let addr = self
|
||||||
.call
|
.call
|
||||||
.mmap(0, actual_mmap_len)
|
.mmap(0, actual_mmap_len)
|
||||||
.ok_or(Error::new("failed to mmap address"))?;
|
.ok_or(Error::MmapFailed)?;
|
||||||
debug!("mapped {:#x} foreign bytes at {:#x}", actual_mmap_len, addr);
|
debug!("mapped {:#x} foreign bytes at {:#x}", actual_mmap_len, addr);
|
||||||
let result = self.call.mmap_batch(self.domid, num as u64, addr, pfns)?;
|
let result = self.call.mmap_batch(self.domid, num as u64, addr, pfns)?;
|
||||||
if result != 0 {
|
if result != 0 {
|
||||||
return Err(Error::new("mmap_batch call failed"));
|
return Err(Error::MmapFailed);
|
||||||
}
|
}
|
||||||
let page = PhysicalPage {
|
let page = PhysicalPage {
|
||||||
pfn: u64::MAX,
|
pfn: u64::MAX,
|
||||||
@ -153,7 +151,7 @@ impl PhysicalPages<'_> {
|
|||||||
(page.count << X86_PAGE_SHIFT) as usize,
|
(page.count << X86_PAGE_SHIFT) as usize,
|
||||||
);
|
);
|
||||||
if err != 0 {
|
if err != 0 {
|
||||||
return Err(Error::new("failed to munmap all pages"));
|
return Err(Error::UnmapFailed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,7 +162,7 @@ impl PhysicalPages<'_> {
|
|||||||
pub fn unmap(&mut self, pfn: u64) -> Result<()> {
|
pub fn unmap(&mut self, pfn: u64) -> Result<()> {
|
||||||
let page = self.pages.iter().enumerate().find(|(_, x)| x.pfn == pfn);
|
let page = self.pages.iter().enumerate().find(|(_, x)| x.pfn == pfn);
|
||||||
if page.is_none() {
|
if page.is_none() {
|
||||||
return Err(Error::new("unable to find page to unmap"));
|
return Err(Error::MemorySetupFailed);
|
||||||
}
|
}
|
||||||
let (i, page) = page.unwrap();
|
let (i, page) = page.unwrap();
|
||||||
|
|
||||||
@ -179,7 +177,7 @@ impl PhysicalPages<'_> {
|
|||||||
page.ptr
|
page.ptr
|
||||||
);
|
);
|
||||||
if err != 0 {
|
if err != 0 {
|
||||||
return Err(Error::new("failed to munmap page"));
|
return Err(Error::UnmapFailed);
|
||||||
}
|
}
|
||||||
self.pages.remove(i);
|
self.pages.remove(i);
|
||||||
}
|
}
|
||||||
|
@ -203,19 +203,19 @@ impl X86BootSetup {
|
|||||||
) -> Result<usize> {
|
) -> Result<usize> {
|
||||||
debug!("counting pgtables from={} to={} pfn={}", from, to, pfn);
|
debug!("counting pgtables from={} to={} pfn={}", from, to, pfn);
|
||||||
if self.table.mappings_count == X86_PAGE_TABLE_MAX_MAPPINGS {
|
if self.table.mappings_count == X86_PAGE_TABLE_MAX_MAPPINGS {
|
||||||
return Err(Error::new("too many mappings"));
|
return Err(Error::MemorySetupFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
let m = self.table.mappings_count;
|
let m = self.table.mappings_count;
|
||||||
|
|
||||||
let pfn_end = pfn + ((to - from) >> X86_PAGE_SHIFT);
|
let pfn_end = pfn + ((to - from) >> X86_PAGE_SHIFT);
|
||||||
if pfn_end >= setup.phys.p2m_size() {
|
if pfn_end >= setup.phys.p2m_size() {
|
||||||
return Err(Error::new("not enough memory for initial mapping"));
|
return Err(Error::MemorySetupFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
for idx in 0..self.table.mappings_count {
|
for idx in 0..self.table.mappings_count {
|
||||||
if from < self.table.mappings[idx].area.to && to > self.table.mappings[idx].area.from {
|
if from < self.table.mappings[idx].area.to && to > self.table.mappings[idx].area.from {
|
||||||
return Err(Error::new("overlapping mappings"));
|
return Err(Error::MemorySetupFailed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut map = PageTableMapping::default();
|
let mut map = PageTableMapping::default();
|
||||||
@ -494,7 +494,7 @@ impl ArchBootSetup for X86BootSetup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if total != total_pages {
|
if total != total_pages {
|
||||||
return Err(Error::new("page count mismatch while calculating pages"));
|
return Err(Error::MemorySetupFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup.total_pages = total;
|
setup.total_pages = total;
|
||||||
@ -561,14 +561,10 @@ impl ArchBootSetup for X86BootSetup {
|
|||||||
.populate_physmap(setup.domid, allocsz, 0, 0, input_extent_starts)?;
|
.populate_physmap(setup.domid, allocsz, 0, 0, input_extent_starts)?;
|
||||||
|
|
||||||
if result.len() != allocsz as usize {
|
if result.len() != allocsz as usize {
|
||||||
return Err(Error::new(
|
return Err(Error::PopulatePhysmapFailed(
|
||||||
format!(
|
allocsz as usize,
|
||||||
"failed to populate physmap: wanted={} received={} input_extents={}",
|
result.len(),
|
||||||
allocsz,
|
input_extent_starts.len(),
|
||||||
result.len(),
|
|
||||||
input_extent_starts.len()
|
|
||||||
)
|
|
||||||
.as_str(),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user