From cf7fbacdaf6b89059f8e9421ef019e07cc5746d4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 19 Jan 2024 19:53:39 +0100 Subject: [PATCH] Stop leaking Mcfg again We don't need it after Pcie::new anymore --- pcid/src/pcie/mod.rs | 55 ++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/pcid/src/pcie/mod.rs b/pcid/src/pcie/mod.rs index b8f4da6c0a..a5f41014ad 100644 --- a/pcid/src/pcie/mod.rs +++ b/pcid/src/pcie/mod.rs @@ -38,7 +38,7 @@ pub struct PcieAlloc { unsafe impl plain::Plain for PcieAlloc {} impl Mcfg { - fn fetch() -> io::Result<&'static Mcfg> { + fn with(f: impl FnOnce(&Mcfg) -> io::Result) -> io::Result { let table_dir = fs::read_dir("acpi:tables")?; for table_direntry in table_dir { @@ -53,24 +53,15 @@ impl Mcfg { let table_filename = table_path.file_name().unwrap().as_encoded_bytes(); if table_filename.get(0..4) == Some(&MCFG_NAME) { let bytes = fs::read(table_path)?.into_boxed_slice(); - if Mcfg::parse(&*bytes).is_none() { - return Err(io::Error::new( - io::ErrorKind::InvalidData, - "couldn't find mcfg table", - )); + match Mcfg::parse(&*bytes) { + Some(mcfg) => return f(mcfg), + None => { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "couldn't find mcfg table", + )); + } } - - // Leaking memory is fine as this function is only called once - // and we need this for the entire lifetime of pcid anyway. - let bytes = Box::leak(bytes); - - // This unwrap is fine as we checked that it will return Some above. - let mcfg = Mcfg::parse(bytes).unwrap(); - - // There should only be a single MCFG table and Linux ignores - // all MCFG tables beyond the first too, so doing an early - // return here is fine. - return Ok(mcfg); } } @@ -136,22 +127,22 @@ unsafe impl Sync for Pcie {} impl Pcie { pub fn new(fallback: Arc) -> io::Result { - let mcfg = Mcfg::fetch()?; + Mcfg::with(|mcfg| { + let alloc_maps = (0..=255) + .map(|bus| { + if let Some(alloc) = mcfg.at_bus(bus) { + Some(unsafe { Self::physmap_pcie_bus(alloc, bus) }) + } else { + None + } + }) + .collect(); - let alloc_maps = (0..=255) - .map(|bus| { - if let Some(alloc) = mcfg.at_bus(bus) { - Some(unsafe { Self::physmap_pcie_bus(alloc, bus) }) - } else { - None - } + Ok(Self { + lock: Mutex::new(()), + bus_maps: alloc_maps, + fallback, }) - .collect(); - - Ok(Self { - lock: Mutex::new(()), - bus_maps: alloc_maps, - fallback, }) }