Only set iopl for helper threads when actually necessary
This commit is contained in:
+3
-4
@@ -470,12 +470,11 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, addr: PciAddress, he
|
||||
state: Arc::clone(&state),
|
||||
capabilities,
|
||||
};
|
||||
thread::spawn(move || {
|
||||
// RFLAGS are no longer kept in the relibc clone() implementation.
|
||||
unsafe { syscall::iopl(3).expect("pcid: failed to set IOPL"); }
|
||||
|
||||
let _handle = thread::spawn(move || {
|
||||
driver_handler.handle_spawn(pcid_to_client_write, pcid_from_client_read, subdriver_args);
|
||||
});
|
||||
// FIXME this currently deadlocks as pcid doesn't daemonize
|
||||
//state.threads.lock().unwrap().push(handle);
|
||||
match child.wait() {
|
||||
Ok(_status) => (),
|
||||
Err(err) => error!("pcid: failed to wait for {:?}: {}", command, err),
|
||||
|
||||
+22
-10
@@ -1,5 +1,6 @@
|
||||
use std::cell::Cell;
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::{Mutex, Once};
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
use syscall::io::{Io as _, Pio};
|
||||
@@ -10,25 +11,36 @@ use crate::pci::{CfgAccess, PciAddress};
|
||||
|
||||
pub(crate) struct Pci {
|
||||
lock: Mutex<()>,
|
||||
iopl_once: Once,
|
||||
}
|
||||
|
||||
impl Pci {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
lock: Mutex::new(()),
|
||||
iopl_once: Once::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_iopl() {
|
||||
// make sure that pcid is not granted io port permission unless pcie memory-mapped
|
||||
// configuration space is not available.
|
||||
info!("PCI: couldn't find or access PCIe extended configuration, and thus falling back to PCI 3.0 io ports");
|
||||
unsafe {
|
||||
syscall::iopl(3).expect("pcid: failed to set iopl to 3");
|
||||
// The IO privilege level is per-thread, so we need to do the initialization on every thread.
|
||||
thread_local! {
|
||||
static IOPL_ONCE: Cell<bool> = Cell::new(false);
|
||||
}
|
||||
|
||||
IOPL_ONCE.with(|iopl_once| {
|
||||
if !iopl_once.replace(true) {
|
||||
// make sure that pcid is not granted io port permission unless pcie memory-mapped
|
||||
// configuration space is not available.
|
||||
info!(
|
||||
"PCI: couldn't find or access PCIe extended configuration, \
|
||||
and thus falling back to PCI 3.0 io ports"
|
||||
);
|
||||
unsafe {
|
||||
syscall::iopl(3).expect("pcid: failed to set iopl to 3");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn address(address: PciAddress, offset: u8) -> u32 {
|
||||
// TODO: Find the part of pcid that uses an unaligned offset!
|
||||
//
|
||||
@@ -54,7 +66,7 @@ impl CfgAccess for Pci {
|
||||
unsafe fn read(&self, address: PciAddress, offset: u16) -> u32 {
|
||||
let _guard = self.lock.lock().unwrap();
|
||||
|
||||
self.iopl_once.call_once(Self::set_iopl);
|
||||
Self::set_iopl();
|
||||
|
||||
let offset =
|
||||
u8::try_from(offset).expect("offset too large for PCI 3.0 configuration space");
|
||||
@@ -67,7 +79,7 @@ impl CfgAccess for Pci {
|
||||
unsafe fn write(&self, address: PciAddress, offset: u16, value: u32) {
|
||||
let _guard = self.lock.lock().unwrap();
|
||||
|
||||
self.iopl_once.call_once(Self::set_iopl);
|
||||
Self::set_iopl();
|
||||
|
||||
let offset =
|
||||
u8::try_from(offset).expect("offset too large for PCI 3.0 configuration space");
|
||||
|
||||
@@ -141,7 +141,7 @@ impl Pcie {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok(Self {
|
||||
lock: Mutex::new(()),
|
||||
|
||||
Reference in New Issue
Block a user