From 2dc70ea6af2b824db2e85b3ce224aeb78568b509 Mon Sep 17 00:00:00 2001 From: Luke D Jones Date: Sat, 3 Apr 2021 09:59:36 +1300 Subject: [PATCH 1/2] Put vfio behind config option --- CHANGELOG.md | 3 ++ Cargo.lock | 2 +- asusctl/examples/animatrix.rs | 9 +++-- daemon/Cargo.toml | 2 +- daemon/src/config.rs | 7 ++++ daemon/src/config_old.rs | 31 +++++++++++++++++ daemon/src/ctrl_gfx/error.rs | 4 +++ daemon/src/ctrl_gfx/gfx.rs | 63 +++++++++++++++++++++++++---------- daemon/src/daemon.rs | 7 +++- 9 files changed, 102 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5779c2a..5844d29a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +# [3.3.0] - 2021-04-3 ### Changed - Add ledmodes for G733QS - Add ledmodes for GA401Q +- Default to vfio disabled in configuration. Will now hard-error if enabled and + the kernel modules are builtin. # [3.2.4] - 2021-03-24 ### Changed diff --git a/Cargo.lock b/Cargo.lock index 9d71ca4f..b3ee9a81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,7 +197,7 @@ dependencies = [ [[package]] name = "daemon" -version = "3.2.4" +version = "3.3.0" dependencies = [ "env_logger", "intel-pstate", diff --git a/asusctl/examples/animatrix.rs b/asusctl/examples/animatrix.rs index 990ced71..dcaa4106 100644 --- a/asusctl/examples/animatrix.rs +++ b/asusctl/examples/animatrix.rs @@ -1,12 +1,11 @@ use rog_dbus::AuraDbusClient; -use rog_types::anime_matrix::{AniMeImageBuffer, AniMePacketType, HEIGHT, WIDTH}; +use rog_types::anime_matrix::{AniMeImageBuffer, HEIGHT, WIDTH}; use tinybmp::{Bmp, Pixel}; fn main() { let (client, _) = AuraDbusClient::new().unwrap(); - let bmp = - Bmp::from_slice(include_bytes!("skewed_r.bmp")).expect("Failed to parse BMP image"); + let bmp = Bmp::from_slice(include_bytes!("rust.bmp")).expect("Failed to parse BMP image"); let pixels: Vec = bmp.into_iter().collect(); //assert_eq!(pixels.len(), 56 * 56); @@ -16,7 +15,7 @@ fn main() { // Aligned left for (i, px) in pixels.iter().enumerate() { if (px.x as usize / 2) < WIDTH && (px.y as usize) < HEIGHT && px.x % 2 == 0 { - let mut c = px.color as u32; + let c = px.color as u32; matrix.get_mut()[px.y as usize][px.x as usize / 2] = c as u8; } } @@ -27,7 +26,7 @@ fn main() { for x in tmp[0].iter_mut() { *x = 0xff; } - for (i,row) in tmp.iter_mut().enumerate() { + for (i, row) in tmp.iter_mut().enumerate() { if i % 2 == 0 { let l = row.len(); row[l - 1] = 0xff; diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index b0be9293..5fe268b9 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "daemon" -version = "3.2.4" +version = "3.3.0" license = "MPL-2.0" readme = "README.md" authors = ["Luke "] diff --git a/daemon/src/config.rs b/daemon/src/config.rs index 13c10264..fa98cdf3 100644 --- a/daemon/src/config.rs +++ b/daemon/src/config.rs @@ -15,6 +15,7 @@ pub static AURA_CONFIG_PATH: &str = "/etc/asusd/asusd.conf"; pub struct Config { pub gfx_mode: GfxVendors, pub gfx_managed: bool, + pub gfx_vfio_enable: bool, pub active_profile: String, pub toggle_profiles: Vec, #[serde(skip)] @@ -33,6 +34,7 @@ impl Default for Config { Config { gfx_mode: GfxVendors::Hybrid, gfx_managed: true, + gfx_vfio_enable: false, active_profile: "normal".into(), toggle_profiles: vec!["normal".into(), "boost".into(), "silent".into()], curr_fan_mode: 0, @@ -63,6 +65,11 @@ impl Config { } else { if let Ok(data) = serde_json::from_str(&buf) { return data; + } else if let Ok(data) = serde_json::from_str::(&buf) { + let config = data.into_current(); + config.write(); + info!("Updated config version to: {}", VERSION); + return config; } else if let Ok(data) = serde_json::from_str::(&buf) { let config = data.into_current(); config.write(); diff --git a/daemon/src/config_old.rs b/daemon/src/config_old.rs index 0e307617..e01b22c2 100644 --- a/daemon/src/config_old.rs +++ b/daemon/src/config_old.rs @@ -25,6 +25,7 @@ impl ConfigV212 { gfx_mode: GfxVendors::Hybrid, gfx_managed: self.gfx_managed, active_profile: self.active_profile, + gfx_vfio_enable: false, toggle_profiles: self.toggle_profiles, curr_fan_mode: self.power_profile, bat_charge_limit: self.bat_charge_limit, @@ -53,6 +54,7 @@ impl ConfigV222 { Config { gfx_mode: GfxVendors::Hybrid, gfx_managed: self.gfx_managed, + gfx_vfio_enable: false, active_profile: self.active_profile, toggle_profiles: self.toggle_profiles, curr_fan_mode: self.power_profile, @@ -84,6 +86,7 @@ impl ConfigV301 { Config { gfx_mode: GfxVendors::Hybrid, gfx_managed: self.gfx_managed, + gfx_vfio_enable: false, active_profile: self.active_profile, toggle_profiles: self.toggle_profiles, curr_fan_mode: self.curr_fan_mode, @@ -115,6 +118,34 @@ impl ConfigV317 { Config { gfx_mode: GfxVendors::Hybrid, gfx_managed: self.gfx_managed, + gfx_vfio_enable: false, + active_profile: self.active_profile, + toggle_profiles: self.toggle_profiles, + curr_fan_mode: self.curr_fan_mode, + bat_charge_limit: self.bat_charge_limit, + power_profiles: self.power_profiles, + } + } +} + +#[derive(Deserialize, Serialize)] +pub struct ConfigV324 { + pub gfx_mode: GfxVendors, + pub gfx_managed: bool, + pub active_profile: String, + pub toggle_profiles: Vec, + #[serde(skip)] + pub curr_fan_mode: u8, + pub bat_charge_limit: u8, + pub power_profiles: BTreeMap, +} + +impl ConfigV324 { + pub(crate) fn into_current(self) -> Config { + Config { + gfx_mode: GfxVendors::Hybrid, + gfx_managed: self.gfx_managed, + gfx_vfio_enable: false, active_profile: self.active_profile, toggle_profiles: self.toggle_profiles, curr_fan_mode: self.curr_fan_mode, diff --git a/daemon/src/ctrl_gfx/error.rs b/daemon/src/ctrl_gfx/error.rs index 349fb87d..fb039cd6 100644 --- a/daemon/src/ctrl_gfx/error.rs +++ b/daemon/src/ctrl_gfx/error.rs @@ -11,6 +11,7 @@ pub enum GfxError { DisplayManagerTimeout(String), GsyncModeActive, VfioBuiltin, + VfioDisabled, MissingModule(String), Modprobe(String), Command(String, std::io::Error), @@ -36,6 +37,9 @@ impl fmt::Display for GfxError { f, "Can not switch to vfio mode if the modules are built in to kernel" ), + GfxError::VfioDisabled => { + write!(f, "Can not switch to vfio mode if disabled in config file") + } GfxError::MissingModule(m) => write!(f, "The module {} is missing", m), GfxError::Modprobe(detail) => write!(f, "Modprobe error: {}", detail), GfxError::Command(func, error) => write!(f, "Command exec error: {}: {}", func, error), diff --git a/daemon/src/ctrl_gfx/gfx.rs b/daemon/src/ctrl_gfx/gfx.rs index 9fa282b3..62e909e2 100644 --- a/daemon/src/ctrl_gfx/gfx.rs +++ b/daemon/src/ctrl_gfx/gfx.rs @@ -427,6 +427,7 @@ impl CtrlGraphics { /// The daemon needs direct access to this function when it detects that the pub fn do_vendor_tasks( vendor: GfxVendors, + vfio_enable: bool, devices: &[GraphicsDevice], bus: &PciBus, ) -> Result<(), RogError> { @@ -439,31 +440,33 @@ impl CtrlGraphics { match vendor { GfxVendors::Nvidia | GfxVendors::Hybrid | GfxVendors::Compute => { - for driver in VFIO_DRIVERS.iter() { - Self::do_driver_action(driver, "rmmod")?; + if vfio_enable { + for driver in VFIO_DRIVERS.iter() { + Self::do_driver_action(driver, "rmmod")?; + } } for driver in NVIDIA_DRIVERS.iter() { Self::do_driver_action(driver, "modprobe")?; } } GfxVendors::Vfio => { - Self::do_driver_action("nouveau", "rmmod")?; - for driver in NVIDIA_DRIVERS.iter() { - Self::do_driver_action(driver, "rmmod")?; + if vfio_enable { + Self::do_driver_action("nouveau", "rmmod")?; + for driver in NVIDIA_DRIVERS.iter() { + Self::do_driver_action(driver, "rmmod")?; + } + Self::unbind_only(&devices)?; + Self::do_driver_action("vfio-pci", "modprobe")?; + } else { + return Err(GfxError::VfioDisabled.into()); } - Self::unbind_only(&devices)?; - Self::do_driver_action("vfio-pci", "modprobe")?; } GfxVendors::Integrated => { Self::do_driver_action("nouveau", "rmmod")?; - for driver in VFIO_DRIVERS.iter() { - Self::do_driver_action(driver, "rmmod").or_else(|err| { - if matches!(err, GfxError::VfioBuiltin) { - warn!("{}", err); - return Ok(()); - } - Err(err) - })?; + if vfio_enable { + for driver in VFIO_DRIVERS.iter() { + Self::do_driver_action(driver, "rmmod")?; + } } for driver in NVIDIA_DRIVERS.iter() { Self::do_driver_action(driver, "rmmod")?; @@ -543,7 +546,13 @@ impl CtrlGraphics { Self::do_display_manager_action("stop")?; Self::wait_display_manager_state("inactive")?; - Self::do_vendor_tasks(vendor, &devices, &bus)?; + let vfio_enable = if let Ok(config) = config.lock() { + config.gfx_vfio_enable + } else { + false + }; + + Self::do_vendor_tasks(vendor, vfio_enable, &devices, &bus)?; Self::do_display_manager_action("restart")?; // Save selected mode in case of reboot Self::save_gfx_mode(vendor, config); @@ -607,6 +616,17 @@ impl CtrlGraphics { return Err(GfxError::GsyncModeActive.into()); } } + + let vfio_enable = if let Ok(config) = self.config.lock() { + config.gfx_vfio_enable + } else { + false + }; + + if !vfio_enable { + return Err(GfxError::VfioDisabled.into()); + } + // Must always cancel any thread running self.cancel_thread(); // determine which method we need here @@ -620,7 +640,7 @@ impl CtrlGraphics { info!("GFX: mode change does not require logout"); let devices = self.nvidia.clone(); let bus = self.bus.clone(); - Self::do_vendor_tasks(vendor, &devices, &bus)?; + Self::do_vendor_tasks(vendor, vfio_enable, &devices, &bus)?; info!("GFX: Graphics mode changed to {}", <&str>::from(vendor)); } // TODO: undo if failed? Save last mode, catch errors... @@ -632,7 +652,14 @@ impl CtrlGraphics { let vendor = self.get_gfx_mode()?; let devices = self.nvidia.clone(); let bus = self.bus.clone(); - Self::do_vendor_tasks(vendor, &devices, &bus)?; + + let vfio_enable = if let Ok(config) = self.config.lock() { + config.gfx_vfio_enable + } else { + false + }; + + Self::do_vendor_tasks(vendor, vfio_enable, &devices, &bus)?; Self::toggle_fallback_service(vendor)?; Ok(()) } diff --git a/daemon/src/daemon.rs b/daemon/src/daemon.rs index 367ae9c9..b07842fd 100644 --- a/daemon/src/daemon.rs +++ b/daemon/src/daemon.rs @@ -109,7 +109,12 @@ fn start_daemon() -> Result<(), Box> { warn!("Dedicated GFX toggle is on but driver mode is not nvidia \nSetting to nvidia driver mode"); let devices = ctrl.devices(); let bus = ctrl.bus(); - CtrlGraphics::do_vendor_tasks(GfxVendors::Nvidia, &devices, &bus)?; + CtrlGraphics::do_vendor_tasks( + GfxVendors::Nvidia, + false, + &devices, + &bus, + )?; } else if ded == 0 { info!("Dedicated GFX toggle is off"); } From fc3d7653f5198de21cf38b595417d41df03d419c Mon Sep 17 00:00:00 2001 From: Luke D Jones Date: Sat, 3 Apr 2021 12:20:56 +1300 Subject: [PATCH 2/2] Add missing if condition for vfio --- CHANGELOG.md | 3 ++- README.md | 2 ++ daemon/src/ctrl_gfx/gfx.rs | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5844d29a..6f80a5fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add ledmodes for G733QS - Add ledmodes for GA401Q - Default to vfio disabled in configuration. Will now hard-error if enabled and - the kernel modules are builtin. + the kernel modules are builtin. To enable vfio switching `"gfx_vfio_enable": false,` + must be changed to `true` in `/etc/asusd/asusd.conf` # [3.2.4] - 2021-03-24 ### Changed diff --git a/README.md b/README.md index 9ba50571..fd3f2e3c 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,8 @@ stray configs blocking nvidia modules from loading in: to be separate modules. If you don't plan to use vfio mode then you can ignore this otherwise you may need a custom built kernel. +To enable vfio switching you need to edit `/etc/asusd/asusd.conf` and change `"gfx_vfio_enable": false,` to true. + ### Power management udev rule If you have installed the Nvidia driver manually you will require the diff --git a/daemon/src/ctrl_gfx/gfx.rs b/daemon/src/ctrl_gfx/gfx.rs index 62e909e2..d61aadbe 100644 --- a/daemon/src/ctrl_gfx/gfx.rs +++ b/daemon/src/ctrl_gfx/gfx.rs @@ -623,7 +623,7 @@ impl CtrlGraphics { false }; - if !vfio_enable { + if !vfio_enable && matches!(vendor, GfxVendors::Vfio) { return Err(GfxError::VfioDisabled.into()); }