hypervisor: kvm: check for KVM_SET_MSRS failures

The KVM docs say

  If setting an MSR fails, ..., it stops processing the MSR list and
  returns the number of MSRs that have been set successfully.

So, a return value of zero really means the operation completely failed.

Change-Id: Ic98cdb02513ff86e22fb6b048e7ceb2d6b7e554a
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4500732
Reviewed-by: Elie Kheirallah <khei@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Frederick Mayle <fmayle@google.com>
Reviewed-by: Noah Gold <nkgold@google.com>
This commit is contained in:
Frederick Mayle 2023-05-02 18:50:46 -07:00 committed by crosvm LUCI
parent 2fb38f73d5
commit 5441c064e5
2 changed files with 32 additions and 4 deletions

View file

@ -903,11 +903,25 @@ impl VcpuX86_64 for KvmVcpu {
ioctl_with_ref(self, KVM_SET_MSRS(), &msrs[0])
};
// KVM_SET_MSRS actually returns the number of msr entries written.
if ret >= 0 {
Ok(())
} else {
errno_result()
if ret < 0 {
return errno_result();
}
let num_set = ret as usize;
if num_set != vec.len() {
if let Some(register) = vec.get(num_set) {
error!(
"failed to set MSR {:#x?} to {:#x?}",
register.id, register.value
);
} else {
error!(
"unexpected KVM_SET_MSRS return value {num_set} (nmsrs={})",
vec.len()
);
}
return Err(base::Error::new(libc::EPERM));
}
Ok(())
}
fn set_cpuid(&self, cpuid: &CpuId) -> Result<()> {

View file

@ -408,6 +408,20 @@ fn set_msrs() {
assert_eq!(msrs[0].value, 42);
}
#[test]
fn set_msrs_unsupported() {
let kvm = Kvm::new().unwrap();
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
let vm = KvmVm::new(&kvm, gm, Default::default()).unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let msrs = vec![Register {
id: u32::MAX,
value: u64::MAX,
}];
assert_eq!(vcpu.set_msrs(&msrs), Err(base::Error::new(libc::EPERM)));
}
#[test]
fn get_hyperv_cpuid() {
let kvm = Kvm::new().unwrap();