Files
RedBear-OS/local/patches/base/P5-acpid-dmi-endpoint.patch
vasilito 29ff1ea8fc feat: ACPI Wave 1 boot-critical hardening (P19) + robust patch generation
- P19-init-startup-hardening: Replace panic-grade expect/unwrap in init
  startup paths (getns, register_scheme_to_ns, setrens, filename parsing)
  with graceful error handling and logging
- P19-acpid-startup-hardening: Replace panic-grade calls in acpid with
  graceful degradation (rxsdt read failure → warn + exit 0, SDT parse →
  error + exit 1, I/O privilege → fatal, scheme registration → fatal,
  setrens → warn + continue, event loop errors → log + continue)
- P18-9-msi-allocation-resilience: Regenerate with git diff -U0 -w format
  for maximum context resilience
- fetch.rs: Change --fuzz=0 to --fuzz=3 for resilient patch application
- AGENTS.md: Document robust patch generation technique as mandatory
- Add P4/P5/P6/P7 patches (estale, dmi, i2c, ps2d hardening)
- Add P21 kernel x2apic SMP fix patch
- Multiple local recipe source improvements (redox-drm, driver-manager,
  driver-acpi, thermald)
- Config updates for redbear-mini and redbear-device-services
- Subsystem assessment document
2026-05-18 14:07:42 +03:00

682 lines
23 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
diff --git a/drivers/acpid/src/dmi.rs b/drivers/acpid/src/dmi.rs
new file mode 100644
--- /dev/null
+++ b/drivers/acpid/src/dmi.rs
@@ -0,0 +1,350 @@
+use std::fmt;
+use syscall::PAGE_SIZE;
+
+use crate::acpi::PhysmapGuard;
+
+#[derive(Clone, Debug, Default)]
+pub struct DmiStrings {
+ pub sys_vendor: Option<String>,
+ pub board_vendor: Option<String>,
+ pub board_name: Option<String>,
+ pub board_version: Option<String>,
+ pub product_name: Option<String>,
+ pub product_version: Option<String>,
+ pub bios_version: Option<String>,
+}
+
+impl DmiStrings {
+ pub fn to_text(&self) -> String {
+ let mut text = String::new();
+ if let Some(ref v) = self.sys_vendor {
+ text.push_str("sys_vendor=");
+ text.push_str(v);
+ text.push('\n');
+ }
+ if let Some(ref v) = self.board_vendor {
+ text.push_str("board_vendor=");
+ text.push_str(v);
+ text.push('\n');
+ }
+ if let Some(ref v) = self.board_name {
+ text.push_str("board_name=");
+ text.push_str(v);
+ text.push('\n');
+ }
+ if let Some(ref v) = self.board_version {
+ text.push_str("board_version=");
+ text.push_str(v);
+ text.push('\n');
+ }
+ if let Some(ref v) = self.product_name {
+ text.push_str("product_name=");
+ text.push_str(v);
+ text.push('\n');
+ }
+ if let Some(ref v) = self.product_version {
+ text.push_str("product_version=");
+ text.push_str(v);
+ text.push('\n');
+ }
+ if let Some(ref v) = self.bios_version {
+ text.push_str("bios_version=");
+ text.push_str(v);
+ text.push('\n');
+ }
+ text
+ }
+}
+
+#[derive(Debug)]
+pub enum DmiError {
+ InvalidData,
+ Io(std::io::Error),
+}
+
+impl fmt::Display for DmiError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::InvalidData => write!(f, "invalid SMBIOS data"),
+ Self::Io(e) => write!(f, "I/O error: {}", e),
+ }
+ }
+}
+
+impl From<std::io::Error> for DmiError {
+ fn from(e: std::io::Error) -> Self {
+ DmiError::Io(e)
+ }
+}
+
+/// Scan physical memory for SMBIOS entry point and parse DMI strings.
+pub fn read_smbios_dmi() -> Result<DmiStrings, DmiError> {
+ // SMBIOS entry point is in the BIOS ROM area 0xF0000-0xFFFFF
+ let scan_start = 0xF_0000usize;
+ let scan_size = 0x10_0000usize - scan_start;
+ let start_page = scan_start / PAGE_SIZE * PAGE_SIZE;
+ let start_offset = scan_start % PAGE_SIZE;
+ let page_count = (start_offset + scan_size).div_ceil(PAGE_SIZE);
+
+ let pages = PhysmapGuard::map(start_page, page_count)?;
+ let bios_region = &pages[start_offset..start_offset + scan_size];
+
+ // Search for 64-bit entry point first (_SM3_), then 32-bit (_SM_)
+ // Entry points must be 16-byte aligned
+ let mut entry_point_addr = None;
+ let mut is_64bit = false;
+
+ for offset in (0..bios_region.len().saturating_sub(5)).step_by(16) {
+ if bios_region[offset..].starts_with(b"_SM3_") {
+ entry_point_addr = Some(scan_start + offset);
+ is_64bit = true;
+ break;
+ }
+ }
+
+ if entry_point_addr.is_none() {
+ for offset in (0..bios_region.len().saturating_sub(4)).step_by(16) {
+ if bios_region[offset..].starts_with(b"_SM_") {
+ // Verify intermediate anchor "_DMI_" at offset 0x10 from anchor start
+ let dmi_offset = offset + 0x10;
+ if dmi_offset + 5 <= bios_region.len()
+ && bios_region[dmi_offset..dmi_offset + 5].starts_with(b"_DMI_")
+ {
+ entry_point_addr = Some(scan_start + offset);
+ is_64bit = false;
+ break;
+ }
+ }
+ }
+ }
+
+ let entry_addr = match entry_point_addr {
+ Some(addr) => addr,
+ None => {
+ log::warn!("SMBIOS entry point not found in 0xF0000-0xFFFFF");
+ return Ok(DmiStrings::default());
+ }
+ };
+
+ log::info!(
+ "Found SMBIOS {} entry point at {:#x}",
+ if is_64bit { "3.0" } else { "2.x" },
+ entry_addr
+ );
+
+ if is_64bit {
+ parse_smbios_64(entry_addr)
+ } else {
+ parse_smbios_32(entry_addr)
+ }
+}
+
+fn parse_smbios_32(entry_addr: usize) -> Result<DmiStrings, DmiError> {
+ // 32-bit entry point is at least 0x1F bytes
+ let page = entry_addr / PAGE_SIZE * PAGE_SIZE;
+ let offset = entry_addr % PAGE_SIZE;
+ let pages = PhysmapGuard::map(page, 1)?;
+
+ if pages.len() < offset + 0x1F {
+ log::warn!("SMBIOS 32-bit entry point truncated");
+ return Err(DmiError::InvalidData);
+ }
+
+ let ep = &pages[offset..];
+ let ep_len = ep[0x05] as usize;
+ if ep_len < 0x1F || pages.len() < offset + ep_len {
+ log::warn!("SMBIOS 32-bit entry point length invalid: {}", ep_len);
+ return Err(DmiError::InvalidData);
+ }
+
+ let checksum = ep[..ep_len].iter().fold(0u8, |sum, &b| sum.wrapping_add(b));
+ if checksum != 0 {
+ log::warn!("SMBIOS 32-bit entry point checksum failed");
+ return Err(DmiError::InvalidData);
+ }
+
+ let table_len = u16::from_le_bytes([ep[0x16], ep[0x17]]) as usize;
+ let table_addr = u32::from_le_bytes([ep[0x18], ep[0x19], ep[0x1A], ep[0x1B]]) as usize;
+
+ log::info!("SMBIOS 32-bit: table at {:#x}, len {}", table_addr, table_len);
+
+ parse_smbios_structures(table_addr, table_len)
+}
+
+fn parse_smbios_64(entry_addr: usize) -> Result<DmiStrings, DmiError> {
+ // 64-bit entry point is at least 0x18 bytes
+ let page = entry_addr / PAGE_SIZE * PAGE_SIZE;
+ let offset = entry_addr % PAGE_SIZE;
+ let pages = PhysmapGuard::map(page, 1)?;
+
+ if pages.len() < offset + 0x18 {
+ log::warn!("SMBIOS 64-bit entry point truncated");
+ return Err(DmiError::InvalidData);
+ }
+
+ let ep = &pages[offset..];
+ let ep_len = ep[0x06] as usize;
+ if ep_len < 0x18 || pages.len() < offset + ep_len {
+ log::warn!("SMBIOS 64-bit entry point length invalid: {}", ep_len);
+ return Err(DmiError::InvalidData);
+ }
+
+ let checksum = ep[..ep_len].iter().fold(0u8, |sum, &b| sum.wrapping_add(b));
+ if checksum != 0 {
+ log::warn!("SMBIOS 64-bit entry point checksum failed");
+ return Err(DmiError::InvalidData);
+ }
+
+ let table_max_size =
+ u32::from_le_bytes([ep[0x0C], ep[0x0D], ep[0x0E], ep[0x0F]]) as usize;
+ let table_addr = u64::from_le_bytes([
+ ep[0x10], ep[0x11], ep[0x12], ep[0x13], ep[0x14], ep[0x15], ep[0x16], ep[0x17],
+ ]) as usize;
+
+ log::info!(
+ "SMBIOS 64-bit: table at {:#x}, max size {}",
+ table_addr,
+ table_max_size
+ );
+
+ parse_smbios_structures(table_addr, table_max_size)
+}
+
+fn parse_smbios_structures(table_addr: usize, table_len: usize) -> Result<DmiStrings, DmiError> {
+ if table_addr == 0 || table_len == 0 {
+ log::warn!("SMBIOS structure table address or length is zero");
+ return Ok(DmiStrings::default());
+ }
+
+ // Map the structure table. It may span multiple pages.
+ let start_page = table_addr / PAGE_SIZE * PAGE_SIZE;
+ let start_offset = table_addr % PAGE_SIZE;
+ let total_needed = start_offset + table_len;
+ let page_count = total_needed.div_ceil(PAGE_SIZE);
+
+ let pages = PhysmapGuard::map(start_page, page_count)?;
+ if pages.len() < total_needed {
+ log::warn!("SMBIOS structure table mapping truncated");
+ return Err(DmiError::InvalidData);
+ }
+
+ let table = &pages[start_offset..start_offset + table_len];
+
+ let mut dmi = DmiStrings::default();
+ let mut pos = 0;
+
+ while pos + 4 <= table.len() {
+ let stype = table[pos];
+ let slen = table[pos + 1] as usize;
+ let _handle = u16::from_le_bytes([table[pos + 2], table[pos + 3]]);
+
+ if slen < 4 {
+ log::warn!(
+ "Malformed SMBIOS structure at offset {}, type {}, len {}",
+ pos,
+ stype,
+ slen
+ );
+ break;
+ }
+
+ if pos + slen > table.len() {
+ log::warn!(
+ "SMBIOS structure at offset {} extends past table end", pos
+ );
+ break;
+ }
+
+ // Parse strings after the formatted section
+ let strings_start = pos + slen;
+ let mut strings = Vec::new();
+ let mut s = strings_start;
+
+ while s < table.len() {
+ // Find null terminator
+ let mut end = s;
+ while end < table.len() && table[end] != 0 {
+ end += 1;
+ }
+
+ if end >= table.len() {
+ log::warn!("Unterminated SMBIOS strings at offset {}", s);
+ break;
+ }
+
+ let string = std::str::from_utf8(&table[s..end]).unwrap_or("").to_string();
+ strings.push(string);
+
+ s = end + 1;
+
+ // Double null terminates the string set
+ if s < table.len() && table[s] == 0 {
+ s += 1;
+ break;
+ }
+ }
+
+ match stype {
+ 0 => {
+ // BIOS Information
+ if slen > 5 {
+ let idx = table[pos + 5] as usize;
+ if idx > 0 && idx <= strings.len() {
+ dmi.bios_version = Some(strings[idx - 1].clone());
+ }
+ }
+ }
+ 1 => {
+ // System Information
+ if slen > 4 {
+ let idx = table[pos + 4] as usize;
+ if idx > 0 && idx <= strings.len() {
+ dmi.sys_vendor = Some(strings[idx - 1].clone());
+ }
+ }
+ if slen > 5 {
+ let idx = table[pos + 5] as usize;
+ if idx > 0 && idx <= strings.len() {
+ dmi.product_name = Some(strings[idx - 1].clone());
+ }
+ }
+ if slen > 6 {
+ let idx = table[pos + 6] as usize;
+ if idx > 0 && idx <= strings.len() {
+ dmi.product_version = Some(strings[idx - 1].clone());
+ }
+ }
+ }
+ 2 => {
+ // Base Board Information
+ if slen > 4 {
+ let idx = table[pos + 4] as usize;
+ if idx > 0 && idx <= strings.len() {
+ dmi.board_vendor = Some(strings[idx - 1].clone());
+ }
+ }
+ if slen > 5 {
+ let idx = table[pos + 5] as usize;
+ if idx > 0 && idx <= strings.len() {
+ dmi.board_name = Some(strings[idx - 1].clone());
+ }
+ }
+ if slen > 6 {
+ let idx = table[pos + 6] as usize;
+ if idx > 0 && idx <= strings.len() {
+ dmi.board_version = Some(strings[idx - 1].clone());
+ }
+ }
+ }
+ 127 => {
+ // End-of-table marker
+ break;
+ }
+ _ => {}
+ }
+
+ pos = s;
+ }
+
+ Ok(dmi)
+}
diff --git a/drivers/acpid/src/acpi.rs b/drivers/acpid/src/acpi.rs
--- a/drivers/acpid/src/acpi.rs
+++ b/drivers/acpid/src/acpi.rs
@@ -95,12 +95,12 @@
BadChecksum,
}
-struct PhysmapGuard {
+pub struct PhysmapGuard {
virt: *const u8,
size: usize,
}
impl PhysmapGuard {
- fn map(page: usize, page_count: usize) -> std::io::Result<Self> {
+ pub fn map(page: usize, page_count: usize) -> std::io::Result<Self> {
let size = page_count * PAGE_SIZE;
let virt = unsafe {
common::physmap(page, size, common::Prot::RO, common::MemoryType::default())
@@ -245,26 +245,55 @@
symbol_cache: FxHashMap<String, String>,
page_cache: Arc<Mutex<AmlPageCache>>,
aml_region_handlers: Vec<(RegionSpace, Box<dyn RegionHandler>)>,
+ pci_fd: Arc<parking_lot::RwLock<Option<libredox::Fd>>>,
}
impl AmlSymbols {
- pub fn new(aml_region_handlers: Vec<(RegionSpace, Box<dyn RegionHandler>)>) -> Self {
+ pub fn new(aml_region_handlers: Vec<(RegionSpace, Box<dyn RegionHandler>)>, pci_fd: Arc<parking_lot::RwLock<Option<libredox::Fd>>>) -> Self {
Self {
aml_context: None,
symbol_cache: FxHashMap::default(),
page_cache: Arc::new(Mutex::new(AmlPageCache::default())),
aml_region_handlers,
+ pci_fd,
}
}
- pub fn init(&mut self, pci_fd: Option<&libredox::Fd>) -> Result<(), Box<dyn Error>> {
+ pub fn init(&mut self) -> Result<(), Box<dyn Error>> {
if self.aml_context.is_some() {
return Err("AML interpreter already initialized".into());
}
let format_err = |err| format!("{:?}", err);
- let handler = AmlPhysMemHandler::new(pci_fd, Arc::clone(&self.page_cache));
+ let handler = AmlPhysMemHandler::new(Arc::clone(&self.pci_fd), Arc::clone(&self.page_cache));
//TODO: use these parsed tables for the rest of acpid
- let rsdp_address = usize::from_str_radix(&std::env::var("RSDP_ADDR")?, 16)?;
+ let rsdp_address = match std::env::var("RSDP_ADDR") {
+ Ok(addr) => usize::from_str_radix(&addr, 16)?,
+ Err(_) => {
+ // RSDP_ADDR not provided — probe BIOS area (0xE00000xFFFFF) for RSDP signature
+ log::info!("RSDP_ADDR not set, probing BIOS area for RSDP...");
+ let mut found = None;
+ for page_base in (0xE_0000..0x10_0000).step_by(16) {
+ let mapped = unsafe {
+ common::physmap(
+ page_base,
+ 16,
+ common::Prot::RW,
+ common::MemoryType::default(),
+ )
+ };
+ if let Ok(virt) = mapped {
+ let sig = unsafe { std::slice::from_raw_parts(virt as *const u8, 8) };
+ if sig == b"RSD PTR " {
+ log::info!("found RSDP at physical {:#x}", page_base);
+ found = Some(page_base);
+ break;
+ }
+ let _ = unsafe { libredox::call::munmap(virt as *mut (), 16) };
+ }
+ }
+ found.ok_or("RSDP not found in BIOS area (0xE0000-0xFFFFF)")?
+ }
+ };
let tables =
unsafe { AcpiTables::from_rsdp(handler.clone(), rsdp_address).map_err(format_err)? };
let platform = AcpiPlatform::new(tables, handler).map_err(format_err)?;
@@ -278,10 +307,9 @@
pub fn aml_context_mut(
&mut self,
- pci_fd: Option<&libredox::Fd>,
) -> Result<&mut Interpreter<AmlPhysMemHandler>, AmlEvalError> {
if self.aml_context.is_none() {
- match self.init(pci_fd) {
+ match self.init() {
Ok(()) => (),
Err(err) => {
log::error!("failed to initialize AML context: {}", err);
@@ -305,8 +333,8 @@
None
}
- pub fn build_cache(&mut self, pci_fd: Option<&libredox::Fd>) {
- let Ok(aml_context) = self.aml_context_mut(pci_fd) else {
+ pub fn build_cache(&mut self) {
+ let Ok(aml_context) = self.aml_context_mut() else {
return;
};
@@ -382,6 +410,8 @@
aml_symbols: RwLock<AmlSymbols>,
+ pub pci_fd: Arc<parking_lot::RwLock<Option<libredox::Fd>>>,
+
// TODO: The kernel ACPI code seemed to use load_table quite ubiquitously, however ACPI 5.1
// states that DDBHandles can only be obtained when loading XSDT-pointed tables. So, we'll
// generate an index only for those.
@@ -397,7 +427,7 @@
args: Vec<AmlSerdeValue>,
) -> Result<AmlSerdeValue, AmlEvalError> {
let mut symbols = self.aml_symbols.write();
- let interpreter = symbols.aml_context_mut(None)?;
+ let interpreter = symbols.aml_context_mut()?;
interpreter.acquire_global_lock(16)?;
let args = args
@@ -440,13 +470,17 @@
})
.collect::<Vec<Sdt>>();
+ let pci_fd = Arc::new(parking_lot::RwLock::new(None));
+
let mut this = Self {
tables,
dsdt: None,
fadt: None,
// Temporary values
- aml_symbols: RwLock::new(AmlSymbols::new(ec)),
+ aml_symbols: RwLock::new(AmlSymbols::new(ec, Arc::clone(&pci_fd))),
+
+ pci_fd,
next_ctx: RwLock::new(0),
@@ -526,7 +560,7 @@
}
pub fn aml_lookup(&self, symbol: &str) -> Option<String> {
- if let Ok(aml_symbols) = self.aml_symbols(None) {
+ if let Ok(aml_symbols) = self.aml_symbols() {
aml_symbols.lookup(symbol)
} else {
None
@@ -535,7 +569,6 @@
pub fn aml_symbols(
&self,
- pci_fd: Option<&libredox::Fd>,
) -> Result<RwLockReadGuard<'_, AmlSymbols>, AmlError> {
// return the cached value if it exists
let symbols = self.aml_symbols.read();
@@ -550,7 +583,7 @@
let mut aml_symbols = self.aml_symbols.write();
- aml_symbols.build_cache(pci_fd);
+ aml_symbols.build_cache();
// return the cached value
Ok(RwLockWriteGuard::downgrade(aml_symbols))
diff --git a/drivers/acpid/src/main.rs b/drivers/acpid/src/main.rs
--- a/drivers/acpid/src/main.rs
+++ b/drivers/acpid/src/main.rs
@@ -14,6 +14,7 @@
mod aml_physmem;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
mod ec;
+mod dmi;
mod scheme;
@@ -73,6 +74,14 @@
];
let acpi_context = self::acpi::AcpiContext::init(physaddrs_iter, region_handlers);
+ let dmi_strings = match self::dmi::read_smbios_dmi() {
+ Ok(strings) => Some(strings),
+ Err(e) => {
+ log::warn!("Failed to read SMBIOS DMI: {}", e);
+ None
+ }
+ };
+
// TODO: I/O permission bitmap?
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
common::acquire_port_io_rights().expect("acpid: failed to set I/O privilege level to Ring 3");
@@ -83,7 +92,7 @@
let mut event_queue = RawEventQueue::new().expect("acpid: failed to create event queue");
let socket = Socket::nonblock().expect("acpid: failed to create disk scheme");
- let mut scheme = self::scheme::AcpiScheme::new(&acpi_context, &socket);
+ let mut scheme = self::scheme::AcpiScheme::new(&acpi_context, &socket, dmi_strings);
let mut handler = Blocking::new(&socket, 16);
event_queue
diff --git a/drivers/acpid/src/scheme.rs b/drivers/acpid/src/scheme.rs
--- a/drivers/acpid/src/scheme.rs
+++ b/drivers/acpid/src/scheme.rs
@@ -22,12 +22,13 @@
use syscall::{EOVERFLOW, EPERM};
use crate::acpi::{AcpiContext, AmlSymbols, SdtSignature};
+use crate::dmi::DmiStrings;
pub struct AcpiScheme<'acpi, 'sock> {
ctx: &'acpi AcpiContext,
handles: HandleMap<Handle<'acpi>>,
- pci_fd: Option<Fd>,
socket: &'sock Socket,
+ dmi_text: Option<String>,
}
struct Handle<'a> {
@@ -43,6 +44,7 @@
Symbol { name: String, description: String },
SchemeRoot,
RegisterPci,
+ Dmi(String),
}
impl HandleKind<'_> {
@@ -55,6 +57,7 @@
Self::Symbol { .. } => false,
Self::SchemeRoot => false,
Self::RegisterPci => false,
+ Self::Dmi(_) => false,
}
}
fn len(&self, acpi_ctx: &AcpiContext) -> Result<usize> {
@@ -65,6 +68,7 @@
.ok_or(Error::new(EBADFD))?
.length(),
Self::Symbol { description, .. } => description.len(),
+ Self::Dmi(text) => text.len(),
// Directories
Self::TopLevel | Self::Symbols(_) | Self::Tables => 0,
Self::SchemeRoot | Self::RegisterPci => return Err(Error::new(EBADF)),
@@ -73,12 +77,12 @@
}
impl<'acpi, 'sock> AcpiScheme<'acpi, 'sock> {
- pub fn new(ctx: &'acpi AcpiContext, socket: &'sock Socket) -> Self {
+ pub fn new(ctx: &'acpi AcpiContext, socket: &'sock Socket, dmi: Option<DmiStrings>) -> Self {
Self {
ctx,
handles: HandleMap::new(),
- pci_fd: None,
socket,
+ dmi_text: dmi.map(|d| d.to_text()),
}
}
}
@@ -196,6 +200,7 @@
match &*components {
[""] => HandleKind::TopLevel,
["register_pci"] => HandleKind::RegisterPci,
+ ["dmi"] => HandleKind::Dmi(self.dmi_text.clone().unwrap_or_default()),
["tables"] => HandleKind::Tables,
["tables", table] => {
@@ -204,7 +209,7 @@
}
["symbols"] => {
- if let Ok(aml_symbols) = self.ctx.aml_symbols(self.pci_fd.as_ref()) {
+ if let Ok(aml_symbols) = self.ctx.aml_symbols() {
HandleKind::Symbols(aml_symbols)
} else {
return Err(Error::new(EIO));
@@ -309,6 +314,7 @@
.ok_or(Error::new(EBADFD))?
.as_slice(),
HandleKind::Symbol { description, .. } => description.as_bytes(),
+ HandleKind::Dmi(ref text) => text.as_bytes(),
_ => return Err(Error::new(EINVAL)),
};
@@ -332,9 +338,13 @@
match &handle.kind {
HandleKind::TopLevel => {
- const TOPLEVEL_ENTRIES: &[&str] = &["tables", "symbols"];
+ const TOPLEVEL_ENTRIES: &[(DirentKind, &str)] = &[
+ (DirentKind::Regular, "dmi"),
+ (DirentKind::Directory, "tables"),
+ (DirentKind::Directory, "symbols"),
+ ];
- for (idx, name) in TOPLEVEL_ENTRIES
+ for (idx, (kind, name)) in TOPLEVEL_ENTRIES
.iter()
.enumerate()
.skip(opaque_offset as usize)
@@ -343,7 +353,7 @@
inode: 0,
next_opaque_id: idx as u64 + 1,
name,
- kind: DirentKind::Directory,
+ kind: *kind,
})?;
}
}
@@ -470,10 +480,12 @@
}
let new_fd = libredox::Fd::new(new_fd);
- if self.pci_fd.is_some() {
- return Err(Error::new(EINVAL));
- } else {
- self.pci_fd = Some(new_fd);
+ {
+ let mut pci_fd = self.ctx.pci_fd.write();
+ if pci_fd.is_some() {
+ return Err(Error::new(EINVAL));
+ }
+ *pci_fd = Some(new_fd);
}
Ok(num_fds)