mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-09 03:57:24 +00:00
config: parse --userspace-msr with serde_keyvalue
This removes the last caller of parse_key_value_options(). BUG=b:255223604 TEST=cargo test Change-Id: Ia17eb320094ee3d46f0db238f2077163e257b7f8 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4049037 Reviewed-by: Alexandre Courbot <acourbot@chromium.org> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
parent
2eb36ff983
commit
a444d2592e
2 changed files with 39 additions and 49 deletions
|
@ -1066,8 +1066,11 @@ where
|
||||||
/// Wrap read_allow and write_allow to store them in MsrHandlers level.
|
/// Wrap read_allow and write_allow to store them in MsrHandlers level.
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
pub enum MsrRWType {
|
pub enum MsrRWType {
|
||||||
|
#[serde(rename = "r")]
|
||||||
ReadOnly,
|
ReadOnly,
|
||||||
|
#[serde(rename = "w")]
|
||||||
WriteOnly,
|
WriteOnly,
|
||||||
|
#[serde(rename = "rw", alias = "wr")]
|
||||||
ReadWrite,
|
ReadWrite,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1076,9 +1079,11 @@ pub enum MsrRWType {
|
||||||
pub enum MsrAction {
|
pub enum MsrAction {
|
||||||
/// Read and write from host directly, and the control of MSR will
|
/// Read and write from host directly, and the control of MSR will
|
||||||
/// take effect on host.
|
/// take effect on host.
|
||||||
|
#[serde(rename = "pass")]
|
||||||
MsrPassthrough,
|
MsrPassthrough,
|
||||||
/// Store the dummy value for msr (copy from host or custom values),
|
/// Store the dummy value for msr (copy from host or custom values),
|
||||||
/// and the control(WRMSR) of MSR won't take effect on host.
|
/// and the control(WRMSR) of MSR won't take effect on host.
|
||||||
|
#[serde(rename = "emu")]
|
||||||
MsrEmulate,
|
MsrEmulate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,9 +1094,11 @@ pub enum MsrAction {
|
||||||
pub enum MsrValueFrom {
|
pub enum MsrValueFrom {
|
||||||
/// Read/write MSR value from/into CPU 0.
|
/// Read/write MSR value from/into CPU 0.
|
||||||
/// The MSR source CPU always be CPU 0.
|
/// The MSR source CPU always be CPU 0.
|
||||||
|
#[serde(rename = "cpu0")]
|
||||||
RWFromCPU0,
|
RWFromCPU0,
|
||||||
/// Read/write MSR value from/into the running CPU.
|
/// Read/write MSR value from/into the running CPU.
|
||||||
/// If vCPU migrates to another pcpu, the MSR source CPU will also change.
|
/// If vCPU migrates to another pcpu, the MSR source CPU will also change.
|
||||||
|
#[serde(skip)]
|
||||||
RWFromRunningCPU,
|
RWFromRunningCPU,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,9 +1106,11 @@ pub enum MsrValueFrom {
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
pub enum MsrFilter {
|
pub enum MsrFilter {
|
||||||
/// Leave it to hypervisor (KVM) default.
|
/// Leave it to hypervisor (KVM) default.
|
||||||
|
#[serde(rename = "no")]
|
||||||
Default,
|
Default,
|
||||||
/// Don't let KVM do the default thing and use our userspace MSR
|
/// Don't let KVM do the default thing and use our userspace MSR
|
||||||
/// implementation.
|
/// implementation.
|
||||||
|
#[serde(rename = "yes")]
|
||||||
Override,
|
Override,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -589,60 +589,41 @@ pub fn parse_mmio_address_range(s: &str) -> Result<Vec<AddressRange>, String> {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
|
#[derive(Deserialize, Serialize, serde_keyvalue::FromKeyValues)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct UserspaceMsrOptions {
|
||||||
|
pub index: u32,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub rw_type: MsrRWType,
|
||||||
|
pub action: MsrAction,
|
||||||
|
#[serde(default = "default_msr_value_from")]
|
||||||
|
pub from: MsrValueFrom,
|
||||||
|
#[serde(default = "default_msr_filter")]
|
||||||
|
pub filter: MsrFilter,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
|
fn default_msr_value_from() -> MsrValueFrom {
|
||||||
|
MsrValueFrom::RWFromRunningCPU
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
|
fn default_msr_filter() -> MsrFilter {
|
||||||
|
MsrFilter::Default
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
pub fn parse_userspace_msr_options(value: &str) -> Result<(u32, MsrConfig), String> {
|
pub fn parse_userspace_msr_options(value: &str) -> Result<(u32, MsrConfig), String> {
|
||||||
let mut rw_type: Option<MsrRWType> = None;
|
let options: UserspaceMsrOptions = from_key_values(value)?;
|
||||||
let mut action: Option<MsrAction> = None;
|
|
||||||
let mut from = MsrValueFrom::RWFromRunningCPU;
|
|
||||||
let mut filter = MsrFilter::Default;
|
|
||||||
|
|
||||||
let mut options = super::argument::parse_key_value_options("userspace-msr", value, ',');
|
|
||||||
let index: u32 = options
|
|
||||||
.next()
|
|
||||||
.ok_or(String::from("userspace-msr: expected index"))?
|
|
||||||
.key_numeric()
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
for opt in options {
|
|
||||||
match opt.key() {
|
|
||||||
"type" => match opt.value().map_err(|e| e.to_string())? {
|
|
||||||
"r" => rw_type = Some(MsrRWType::ReadOnly),
|
|
||||||
"w" => rw_type = Some(MsrRWType::WriteOnly),
|
|
||||||
"rw" | "wr" => rw_type = Some(MsrRWType::ReadWrite),
|
|
||||||
_ => {
|
|
||||||
return Err(String::from("bad type"));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"action" => match opt.value().map_err(|e| e.to_string())? {
|
|
||||||
"pass" => action = Some(MsrAction::MsrPassthrough),
|
|
||||||
"emu" => action = Some(MsrAction::MsrEmulate),
|
|
||||||
_ => return Err(String::from("bad action")),
|
|
||||||
},
|
|
||||||
"from" => match opt.value().map_err(|e| e.to_string())? {
|
|
||||||
"cpu0" => from = MsrValueFrom::RWFromCPU0,
|
|
||||||
_ => return Err(String::from("bad from")),
|
|
||||||
},
|
|
||||||
"filter" => match opt.value().map_err(|e| e.to_string())? {
|
|
||||||
"yes" => filter = MsrFilter::Override,
|
|
||||||
"no" => filter = MsrFilter::Default,
|
|
||||||
_ => return Err(String::from("bad filter")),
|
|
||||||
},
|
|
||||||
|
|
||||||
_ => return Err(opt.invalid_key_err().to_string()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let rw_type = rw_type.ok_or(String::from("userspace-msr: type is required"))?;
|
|
||||||
|
|
||||||
let action = action.ok_or(String::from("userspace-msr: action is required"))?;
|
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
index,
|
options.index,
|
||||||
MsrConfig {
|
MsrConfig {
|
||||||
rw_type,
|
rw_type: options.rw_type,
|
||||||
action,
|
action: options.action,
|
||||||
from,
|
from: options.from,
|
||||||
filter,
|
filter: options.filter,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue