mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
Compare commits
7 Commits
v50.2
...
stable/v21
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e01933c8ea | ||
|
|
c6307865eb | ||
|
|
6275d4f87e | ||
|
|
4dfe1ff77a | ||
|
|
bbda07c388 | ||
|
|
366223c9f4 | ||
|
|
375356a097 |
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -148,7 +148,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cloud-hypervisor"
|
name = "cloud-hypervisor"
|
||||||
version = "21.0.0"
|
version = "21.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"api_client",
|
"api_client",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cloud-hypervisor"
|
name = "cloud-hypervisor"
|
||||||
version = "21.0.0"
|
version = "21.1.0"
|
||||||
authors = ["The Cloud Hypervisor Authors"]
|
authors = ["The Cloud Hypervisor Authors"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
default-run = "cloud-hypervisor"
|
default-run = "cloud-hypervisor"
|
||||||
|
|||||||
@@ -443,4 +443,9 @@ pub trait Vcpu: Send + Sync {
|
|||||||
/// Return suspend registers(explicit and intercept suspend registers)
|
/// Return suspend registers(explicit and intercept suspend registers)
|
||||||
///
|
///
|
||||||
fn get_suspend_regs(&self) -> Result<SuspendRegisters>;
|
fn get_suspend_regs(&self) -> Result<SuspendRegisters>;
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
|
///
|
||||||
|
/// Set the "immediate_exit" state
|
||||||
|
///
|
||||||
|
fn set_immediate_exit(&self, exit: bool);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1574,6 +1574,13 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
tdx_command(&self.fd.as_raw_fd(), TdxCommand::InitVcpu, 0, hob_address)
|
tdx_command(&self.fd.as_raw_fd(), TdxCommand::InitVcpu, 0, hob_address)
|
||||||
.map_err(cpu::HypervisorCpuError::InitializeTdx)
|
.map_err(cpu::HypervisorCpuError::InitializeTdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Set the "immediate_exit" state
|
||||||
|
///
|
||||||
|
fn set_immediate_exit(&self, exit: bool) {
|
||||||
|
self.fd.set_kvm_immediate_exit(exit.into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Device struct for KVM
|
/// Device struct for KVM
|
||||||
|
|||||||
@@ -130,6 +130,9 @@ pub fn check_required_kvm_extensions(kvm: &Kvm) -> KvmResult<()> {
|
|||||||
if !kvm.check_extension(Cap::SetTssAddr) {
|
if !kvm.check_extension(Cap::SetTssAddr) {
|
||||||
return Err(KvmError::CapabilityMissing(Cap::SetTssAddr));
|
return Err(KvmError::CapabilityMissing(Cap::SetTssAddr));
|
||||||
}
|
}
|
||||||
|
if !kvm.check_extension(Cap::ImmediateExit) {
|
||||||
|
return Err(KvmError::CapabilityMissing(Cap::ImmediateExit));
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
|||||||
@@ -740,6 +740,11 @@ impl PciConfiguration {
|
|||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_msg_ctl(LittleEndian::read_u16(data));
|
.set_msg_ctl(LittleEndian::read_u16(data));
|
||||||
|
} else if msix_cap_reg_idx == reg_idx && offset == 0 && data.len() == 4 {
|
||||||
|
msix_config
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.set_msg_ctl((LittleEndian::read_u32(data) >> 16) as u16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
- [v21.1](#v211)
|
||||||
- [v21.0](#v210)
|
- [v21.0](#v210)
|
||||||
- [Efficient Local Live Migration (for Live Upgrade)](#efficient-local-live-migration-for-live-upgrade)
|
- [Efficient Local Live Migration (for Live Upgrade)](#efficient-local-live-migration-for-live-upgrade)
|
||||||
- [Recommended Kernel is Now 5.15](#recommended-kernel-is-now-515)
|
- [Recommended Kernel is Now 5.15](#recommended-kernel-is-now-515)
|
||||||
@@ -183,6 +184,16 @@
|
|||||||
- [Unit testing](#unit-testing)
|
- [Unit testing](#unit-testing)
|
||||||
- [Integration tests parallelization](#integration-tests-parallelization)
|
- [Integration tests parallelization](#integration-tests-parallelization)
|
||||||
|
|
||||||
|
# v21.1
|
||||||
|
|
||||||
|
This is a bug fix release. The following issues have been addressed:
|
||||||
|
|
||||||
|
* Missing `openat()` syscall from seccomp filter (#3609)
|
||||||
|
* Ensure MMIO/PIO exits complete before pausing (#3658)
|
||||||
|
* Support DWORD writes to MSI-X control register (#3714)
|
||||||
|
* VFIO ioctl reordering to fix MSI on AMD platforms (#3827)
|
||||||
|
* Fix `virtio-net` control queue (#3829)
|
||||||
|
|
||||||
# v21.0
|
# v21.0
|
||||||
|
|
||||||
This release has been tracked through the [v21.0
|
This release has been tracked through the [v21.0
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
Name: cloud-hypervisor
|
Name: cloud-hypervisor
|
||||||
Summary: Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on top of KVM.
|
Summary: Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on top of KVM.
|
||||||
Version: 21.0
|
Version: 21.1
|
||||||
Release: 0%{?dist}
|
Release: 0%{?dist}
|
||||||
License: ASL 2.0 or BSD-3-clause
|
License: ASL 2.0 or BSD-3-clause
|
||||||
Group: Applications/System
|
Group: Applications/System
|
||||||
@@ -112,6 +112,9 @@ rm -rf %{buildroot}
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Mar 10 2022 Rob Bradford <robert.bradford@intel.com> 21.1-0
|
||||||
|
- Update to 21.1
|
||||||
|
|
||||||
* Thu Jan 20 2022 Rob Bradford <robert.bradford@intel.com> 21.0-0
|
* Thu Jan 20 2022 Rob Bradford <robert.bradford@intel.com> 21.0-0
|
||||||
- Update to 21.0
|
- Update to 21.0
|
||||||
|
|
||||||
|
|||||||
@@ -563,10 +563,13 @@ impl VirtioDevice for Net {
|
|||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
||||||
|
|
||||||
let queue_num = queues.len();
|
let queue_num = queues.len();
|
||||||
|
let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into());
|
||||||
if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && queue_num % 2 != 0 {
|
if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && queue_num % 2 != 0 {
|
||||||
let cvq_queue = queues.remove(queue_num - 1);
|
let mut cvq_queue = queues.remove(queue_num - 1);
|
||||||
let cvq_queue_evt = queue_evts.remove(queue_num - 1);
|
let cvq_queue_evt = queue_evts.remove(queue_num - 1);
|
||||||
|
|
||||||
|
cvq_queue.set_event_idx(event_idx);
|
||||||
|
|
||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
let mut ctrl_handler = NetCtrlEpollHandler {
|
let mut ctrl_handler = NetCtrlEpollHandler {
|
||||||
kill_evt,
|
kill_evt,
|
||||||
@@ -599,8 +602,6 @@ impl VirtioDevice for Net {
|
|||||||
self.ctrl_queue_epoll_thread = Some(epoll_threads.remove(0));
|
self.ctrl_queue_epoll_thread = Some(epoll_threads.remove(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into());
|
|
||||||
|
|
||||||
let mut epoll_threads = Vec::new();
|
let mut epoll_threads = Vec::new();
|
||||||
let mut taps = self.taps.clone();
|
let mut taps = self.taps.clone();
|
||||||
for i in 0..queues.len() / 2 {
|
for i in 0..queues.len() / 2 {
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ fn virtio_block_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
|
|||||||
(libc::SYS_io_uring_enter, vec![]),
|
(libc::SYS_io_uring_enter, vec![]),
|
||||||
(libc::SYS_lseek, vec![]),
|
(libc::SYS_lseek, vec![]),
|
||||||
(libc::SYS_mprotect, vec![]),
|
(libc::SYS_mprotect, vec![]),
|
||||||
(libc::SYS_openat, vec![]),
|
|
||||||
(libc::SYS_prctl, vec![]),
|
(libc::SYS_prctl, vec![]),
|
||||||
(libc::SYS_pread64, vec![]),
|
(libc::SYS_pread64, vec![]),
|
||||||
(libc::SYS_preadv, vec![]),
|
(libc::SYS_preadv, vec![]),
|
||||||
@@ -130,7 +129,6 @@ fn virtio_mem_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
|
|||||||
|
|
||||||
fn virtio_net_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
|
fn virtio_net_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
|
||||||
vec![
|
vec![
|
||||||
(libc::SYS_openat, vec![]),
|
|
||||||
(libc::SYS_readv, vec![]),
|
(libc::SYS_readv, vec![]),
|
||||||
(libc::SYS_timerfd_settime, vec![]),
|
(libc::SYS_timerfd_settime, vec![]),
|
||||||
(libc::SYS_writev, vec![]),
|
(libc::SYS_writev, vec![]),
|
||||||
@@ -258,6 +256,7 @@ fn virtio_thread_common() -> Vec<(i64, Vec<SeccompRule>)> {
|
|||||||
(libc::SYS_madvise, vec![]),
|
(libc::SYS_madvise, vec![]),
|
||||||
(libc::SYS_mmap, vec![]),
|
(libc::SYS_mmap, vec![]),
|
||||||
(libc::SYS_munmap, vec![]),
|
(libc::SYS_munmap, vec![]),
|
||||||
|
(libc::SYS_openat, vec![]),
|
||||||
(libc::SYS_read, vec![]),
|
(libc::SYS_read, vec![]),
|
||||||
(libc::SYS_rt_sigprocmask, vec![]),
|
(libc::SYS_rt_sigprocmask, vec![]),
|
||||||
(libc::SYS_sigaltstack, vec![]),
|
(libc::SYS_sigaltstack, vec![]),
|
||||||
|
|||||||
@@ -792,6 +792,31 @@ impl CpuManager {
|
|||||||
// to see them in a consistent order in all threads
|
// to see them in a consistent order in all threads
|
||||||
|
|
||||||
if vcpu_pause_signalled.load(Ordering::SeqCst) {
|
if vcpu_pause_signalled.load(Ordering::SeqCst) {
|
||||||
|
// As a pause can be caused by PIO & MMIO exits then we need to ensure they are
|
||||||
|
// completed by returning to KVM_RUN. From the kernel docs:
|
||||||
|
//
|
||||||
|
// For KVM_EXIT_IO, KVM_EXIT_MMIO, KVM_EXIT_OSI, KVM_EXIT_PAPR, KVM_EXIT_XEN,
|
||||||
|
// KVM_EXIT_EPR, KVM_EXIT_X86_RDMSR and KVM_EXIT_X86_WRMSR the corresponding
|
||||||
|
// operations are complete (and guest state is consistent) only after userspace
|
||||||
|
// has re-entered the kernel with KVM_RUN. The kernel side will first finish
|
||||||
|
// incomplete operations and then check for pending signals.
|
||||||
|
// The pending state of the operation is not preserved in state which is
|
||||||
|
// visible to userspace, thus userspace should ensure that the operation is
|
||||||
|
// completed before performing a live migration. Userspace can re-enter the
|
||||||
|
// guest with an unmasked signal pending or with the immediate_exit field set
|
||||||
|
// to complete pending operations without allowing any further instructions
|
||||||
|
// to be executed.
|
||||||
|
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
|
{
|
||||||
|
vcpu.lock().as_ref().unwrap().vcpu.set_immediate_exit(true);
|
||||||
|
if !matches!(vcpu.lock().unwrap().run(), Ok(VmExit::Ignore)) {
|
||||||
|
error!("Unexpected VM exit on \"immediate_exit\" run");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vcpu.lock().as_ref().unwrap().vcpu.set_immediate_exit(false);
|
||||||
|
}
|
||||||
|
|
||||||
vcpu_run_interrupted.store(true, Ordering::SeqCst);
|
vcpu_run_interrupted.store(true, Ordering::SeqCst);
|
||||||
while vcpu_pause_signalled.load(Ordering::SeqCst) {
|
while vcpu_pause_signalled.load(Ordering::SeqCst) {
|
||||||
thread::park();
|
thread::park();
|
||||||
|
|||||||
@@ -190,8 +190,8 @@ impl InterruptSourceGroup for MsiInterruptGroup<IrqRoutingEntry> {
|
|||||||
format!("mask: No existing route for interrupt index {}", index),
|
format!("mask: No existing route for interrupt index {}", index),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
self.set_gsi_routes(&routes)?;
|
route.disable(&self.vm)?;
|
||||||
return route.disable(&self.vm);
|
return self.set_gsi_routes(&routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(
|
||||||
@@ -211,8 +211,8 @@ impl InterruptSourceGroup for MsiInterruptGroup<IrqRoutingEntry> {
|
|||||||
format!("mask: No existing route for interrupt index {}", index),
|
format!("mask: No existing route for interrupt index {}", index),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
self.set_gsi_routes(&routes)?;
|
route.enable(&self.vm)?;
|
||||||
return route.enable(&self.vm);
|
return self.set_gsi_routes(&routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(
|
||||||
|
|||||||
Reference in New Issue
Block a user