x86_64: configure MSRs needed by intel_pstate in initramfs

HWP CPUID bits are decoupled from ITMT feature and the related MSRs are
passthru to ChromeOS by default, thus we no longer need to setup HWP
MSRs at the time of enabling ITMT or PnP.

BUG=b:199380745
TEST=boot Redrix manatee and verified that all related features work

Change-Id: Ia600863f0846ed14e669b0bd3963ec175d148554
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3771066
Commit-Queue: Dmitry Torokhov <dtor@chromium.org>
Reviewed-by: Dmitry Torokhov <dtor@chromium.org>
Tested-by: Dmitry Torokhov <dtor@chromium.org>
This commit is contained in:
Zide Chen 2022-06-14 16:49:36 -07:00 committed by crosvm LUCI
parent c1f72f7d2e
commit e38dd0456a
2 changed files with 9 additions and 119 deletions

View file

@ -48,8 +48,6 @@ use uuid::Uuid;
use vm_control::BatteryType; use vm_control::BatteryType;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use x86_64::set_enable_pnp_data_msr_config; use x86_64::set_enable_pnp_data_msr_config;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use x86_64::set_itmt_msr_config;
use super::argument::parse_hex_or_decimal; use super::argument::parse_hex_or_decimal;
use super::check_opt_path; use super::check_opt_path;
@ -1704,7 +1702,7 @@ pub fn validate_config(cfg: &mut Config) -> std::result::Result<(), String> {
} }
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
set_enable_pnp_data_msr_config(cfg.itmt, &mut cfg.userspace_msr) set_enable_pnp_data_msr_config(&mut cfg.userspace_msr)
.map_err(|e| format!("MSR can't be passed through {}", e))?; .map_err(|e| format!("MSR can't be passed through {}", e))?;
} }
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
@ -1745,8 +1743,6 @@ pub fn validate_config(cfg: &mut Config) -> std::result::Result<(), String> {
if !cfg.enable_hwp { if !cfg.enable_hwp {
return Err("setting `itmt` requires `enable-hwp` is set.".to_string()); return Err("setting `itmt` requires `enable-hwp` is set.".to_string());
} }
set_itmt_msr_config(&mut cfg.userspace_msr)
.map_err(|e| format!("the cpu doesn't support itmt {}", e))?;
} }
if !cfg.balloon && cfg.balloon_control.is_some() { if !cfg.balloon && cfg.balloon_control.is_some() {
@ -2181,6 +2177,13 @@ mod tests {
assert_eq!(pass_cpu0_cfg.action, MsrAction::MsrPassthrough); assert_eq!(pass_cpu0_cfg.action, MsrAction::MsrPassthrough);
assert_eq!(pass_cpu0_cfg.from, MsrValueFrom::RWFromCPU0); assert_eq!(pass_cpu0_cfg.from, MsrValueFrom::RWFromCPU0);
let (pass_cpus_index, pass_cpus_cfg) =
parse_userspace_msr_options("0x10,type=rw,action=pass").unwrap();
assert_eq!(pass_cpus_index, 0x10);
assert_eq!(pass_cpus_cfg.rw_type, MsrRWType::ReadWrite);
assert_eq!(pass_cpus_cfg.action, MsrAction::MsrPassthrough);
assert_eq!(pass_cpus_cfg.from, MsrValueFrom::RWFromRunningCPU);
let (pass_cpus_index, pass_cpus_cfg) = let (pass_cpus_index, pass_cpus_cfg) =
parse_userspace_msr_options("0x10,type=rw,action=emu").unwrap(); parse_userspace_msr_options("0x10,type=rw,action=emu").unwrap();
assert_eq!(pass_cpus_index, 0x10); assert_eq!(pass_cpus_index, 0x10);

View file

@ -50,7 +50,6 @@ mod mptable;
mod regs; mod regs;
mod smbios; mod smbios;
use std::arch::x86_64::__cpuid;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::ffi::CStr; use std::ffi::CStr;
use std::ffi::CString; use std::ffi::CString;
@ -1850,10 +1849,9 @@ fn insert_msrs(
} }
pub fn set_enable_pnp_data_msr_config( pub fn set_enable_pnp_data_msr_config(
itmt: bool,
msr_map: &mut BTreeMap<u32, MsrConfig>, msr_map: &mut BTreeMap<u32, MsrConfig>,
) -> std::result::Result<(), MsrError> { ) -> std::result::Result<(), MsrError> {
let mut msrs = vec![ let msrs = vec![
( (
MSR_IA32_APERF, MSR_IA32_APERF,
MsrRWType::ReadOnly, MsrRWType::ReadOnly,
@ -1870,117 +1868,6 @@ pub fn set_enable_pnp_data_msr_config(
), ),
]; ];
// When itmt is enabled, the following 5 MSRs are already
// passed through or emulated, so just skip here.
if !itmt {
msrs.extend([
(
MSR_PLATFORM_INFO,
MsrRWType::ReadOnly,
MsrAction::MsrPassthrough,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Override,
),
(
MSR_TURBO_RATIO_LIMIT,
MsrRWType::ReadOnly,
MsrAction::MsrPassthrough,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Default,
),
(
MSR_PM_ENABLE,
MsrRWType::ReadOnly,
MsrAction::MsrPassthrough,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Default,
),
(
MSR_HWP_CAPABILITIES,
MsrRWType::ReadOnly,
MsrAction::MsrPassthrough,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Default,
),
(
MSR_HWP_REQUEST,
MsrRWType::ReadOnly,
MsrAction::MsrPassthrough,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Default,
),
]);
}
insert_msrs(msr_map, &msrs)?;
Ok(())
}
const EBX_INTEL_GENU: u32 = 0x756e6547; // "Genu"
const ECX_INTEL_NTEL: u32 = 0x6c65746e; // "ntel"
const EDX_INTEL_INEI: u32 = 0x49656e69; // "ineI"
fn check_itmt_cpu_support() -> std::result::Result<(), MsrError> {
// Safe because we pass 0 for this call and the host supports the
// `cpuid` instruction
let entry = unsafe { __cpuid(0) };
if entry.ebx == EBX_INTEL_GENU && entry.ecx == ECX_INTEL_NTEL && entry.edx == EDX_INTEL_INEI {
Ok(())
} else {
Err(MsrError::CpuUnSupport)
}
}
pub fn set_itmt_msr_config(
msr_map: &mut BTreeMap<u32, MsrConfig>,
) -> std::result::Result<(), MsrError> {
check_itmt_cpu_support()?;
let msrs = vec![
(
MSR_HWP_CAPABILITIES,
MsrRWType::ReadOnly,
MsrAction::MsrPassthrough,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Default,
),
(
MSR_PM_ENABLE,
MsrRWType::ReadWrite,
MsrAction::MsrEmulate,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Default,
),
(
MSR_HWP_REQUEST,
MsrRWType::ReadWrite,
MsrAction::MsrEmulate,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Default,
),
(
MSR_TURBO_RATIO_LIMIT,
MsrRWType::ReadOnly,
MsrAction::MsrPassthrough,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Default,
),
(
MSR_PLATFORM_INFO,
MsrRWType::ReadOnly,
MsrAction::MsrPassthrough,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Default,
),
(
MSR_IA32_PERF_CTL,
MsrRWType::ReadWrite,
MsrAction::MsrEmulate,
MsrValueFrom::RWFromRunningCPU,
MsrFilter::Default,
),
];
insert_msrs(msr_map, &msrs)?; insert_msrs(msr_map, &msrs)?;
Ok(()) Ok(())