mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
misc: Change cpu ID type from u8 to u32
This is the first change to Cloud Hypervisor in a series of changes intended to increase the max number of supported vCPUs in guest VMs, which is currently limited to 255 (254 on x86_64). No user-visible/behavior changes are expected as a result of applying this patch, as the type of boot_cpus and related fields in config structs remains u8 for now, and all configuration validations remain the same. Signed-off-by: Barret Rhoden <brho@google.com> Signed-off-by: Neel Natu <neelnatu@google.com> Signed-off-by: Ofir Weisse <oweisse@google.com> Signed-off-by: Peter Oskolkov <posk@google.com>
This commit is contained in:
@@ -370,7 +370,7 @@ fn create_cpu_nodes(
|
|||||||
if numa_nodes.len() > 1 {
|
if numa_nodes.len() > 1 {
|
||||||
for numa_node_idx in 0..numa_nodes.len() {
|
for numa_node_idx in 0..numa_nodes.len() {
|
||||||
let numa_node = numa_nodes.get(&(numa_node_idx as u32));
|
let numa_node = numa_nodes.get(&(numa_node_idx as u32));
|
||||||
if numa_node.unwrap().cpus.contains(&(cpu_id as u8)) {
|
if numa_node.unwrap().cpus.contains(&(cpu_id as u32)) {
|
||||||
fdt.property_u32("numa-node-id", numa_node_idx as u32)?;
|
fdt.property_u32("numa-node-id", numa_node_idx as u32)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ pub struct EntryPoint {
|
|||||||
/// Configure the specified VCPU, and return its MPIDR.
|
/// Configure the specified VCPU, and return its MPIDR.
|
||||||
pub fn configure_vcpu(
|
pub fn configure_vcpu(
|
||||||
vcpu: &Arc<dyn hypervisor::Vcpu>,
|
vcpu: &Arc<dyn hypervisor::Vcpu>,
|
||||||
id: u8,
|
id: u32,
|
||||||
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
|
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
|
||||||
) -> super::Result<u64> {
|
) -> super::Result<u64> {
|
||||||
if let Some((kernel_entry_point, _guest_memory)) = boot_setup {
|
if let Some((kernel_entry_point, _guest_memory)) = boot_setup {
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ fn pagesize() -> usize {
|
|||||||
pub struct NumaNode {
|
pub struct NumaNode {
|
||||||
pub memory_regions: Vec<Arc<GuestRegionMmap>>,
|
pub memory_regions: Vec<Arc<GuestRegionMmap>>,
|
||||||
pub hotplug_regions: Vec<Arc<GuestRegionMmap>>,
|
pub hotplug_regions: Vec<Arc<GuestRegionMmap>>,
|
||||||
pub cpus: Vec<u8>,
|
pub cpus: Vec<u32>,
|
||||||
pub pci_segments: Vec<u16>,
|
pub pci_segments: Vec<u16>,
|
||||||
pub distances: BTreeMap<u32, u8>,
|
pub distances: BTreeMap<u32, u8>,
|
||||||
pub memory_zones: Vec<String>,
|
pub memory_zones: Vec<String>,
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ pub struct EntryPoint {
|
|||||||
/// Configure the specified VCPU, and return its MPIDR.
|
/// Configure the specified VCPU, and return its MPIDR.
|
||||||
pub fn configure_vcpu(
|
pub fn configure_vcpu(
|
||||||
vcpu: &Arc<dyn hypervisor::Vcpu>,
|
vcpu: &Arc<dyn hypervisor::Vcpu>,
|
||||||
id: u8,
|
id: u32,
|
||||||
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
|
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
|
||||||
) -> super::Result<()> {
|
) -> super::Result<()> {
|
||||||
if let Some((kernel_entry_point, _guest_memory)) = boot_setup {
|
if let Some((kernel_entry_point, _guest_memory)) = boot_setup {
|
||||||
|
|||||||
@@ -820,14 +820,14 @@ pub fn generate_common_cpuid(
|
|||||||
|
|
||||||
pub fn configure_vcpu(
|
pub fn configure_vcpu(
|
||||||
vcpu: &Arc<dyn hypervisor::Vcpu>,
|
vcpu: &Arc<dyn hypervisor::Vcpu>,
|
||||||
id: u8,
|
id: u32,
|
||||||
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
|
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
|
||||||
cpuid: Vec<CpuIdEntry>,
|
cpuid: Vec<CpuIdEntry>,
|
||||||
kvm_hyperv: bool,
|
kvm_hyperv: bool,
|
||||||
cpu_vendor: CpuVendor,
|
cpu_vendor: CpuVendor,
|
||||||
topology: Option<(u8, u8, u8)>,
|
topology: Option<(u8, u8, u8)>,
|
||||||
) -> super::Result<()> {
|
) -> super::Result<()> {
|
||||||
let x2apic_id = get_x2apic_id(id as u32, topology);
|
let x2apic_id = get_x2apic_id(id, topology);
|
||||||
|
|
||||||
// Per vCPU CPUID changes; common are handled via generate_common_cpuid()
|
// Per vCPU CPUID changes; common are handled via generate_common_cpuid()
|
||||||
let mut cpuid = cpuid;
|
let mut cpuid = cpuid;
|
||||||
@@ -946,7 +946,7 @@ pub fn configure_system(
|
|||||||
cmdline_addr: GuestAddress,
|
cmdline_addr: GuestAddress,
|
||||||
cmdline_size: usize,
|
cmdline_size: usize,
|
||||||
initramfs: &Option<InitramfsConfig>,
|
initramfs: &Option<InitramfsConfig>,
|
||||||
_num_cpus: u8,
|
_num_cpus: u32,
|
||||||
setup_header: Option<setup_header>,
|
setup_header: Option<setup_header>,
|
||||||
rsdp_addr: Option<GuestAddress>,
|
rsdp_addr: Option<GuestAddress>,
|
||||||
sgx_epc_region: Option<SgxEpcRegion>,
|
sgx_epc_region: Option<SgxEpcRegion>,
|
||||||
@@ -1365,10 +1365,10 @@ fn update_cpuid_topology(
|
|||||||
cores_per_die: u8,
|
cores_per_die: u8,
|
||||||
dies_per_package: u8,
|
dies_per_package: u8,
|
||||||
cpu_vendor: CpuVendor,
|
cpu_vendor: CpuVendor,
|
||||||
id: u8,
|
id: u32,
|
||||||
) {
|
) {
|
||||||
let x2apic_id = get_x2apic_id(
|
let x2apic_id = get_x2apic_id(
|
||||||
id as u32,
|
id,
|
||||||
Some((threads_per_core, cores_per_die, dies_per_package)),
|
Some((threads_per_core, cores_per_die, dies_per_package)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ fn mpf_intel_compute_checksum(v: &mpspec::mpf_intel) -> u8 {
|
|||||||
(!checksum).wrapping_add(1)
|
(!checksum).wrapping_add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_mp_size(num_cpus: u8) -> usize {
|
fn compute_mp_size(num_cpus: u32) -> usize {
|
||||||
mem::size_of::<MpfIntelWrapper>()
|
mem::size_of::<MpfIntelWrapper>()
|
||||||
+ mem::size_of::<MpcTableWrapper>()
|
+ mem::size_of::<MpcTableWrapper>()
|
||||||
+ mem::size_of::<MpcCpuWrapper>() * (num_cpus as usize)
|
+ mem::size_of::<MpcCpuWrapper>() * (num_cpus as usize)
|
||||||
@@ -135,12 +135,12 @@ fn compute_mp_size(num_cpus: u8) -> usize {
|
|||||||
pub fn setup_mptable(
|
pub fn setup_mptable(
|
||||||
offset: GuestAddress,
|
offset: GuestAddress,
|
||||||
mem: &GuestMemoryMmap,
|
mem: &GuestMemoryMmap,
|
||||||
num_cpus: u8,
|
num_cpus: u32,
|
||||||
topology: Option<(u8, u8, u8)>,
|
topology: Option<(u8, u8, u8)>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if num_cpus > 0 {
|
if num_cpus > 0 {
|
||||||
let cpu_id_max = num_cpus - 1;
|
let cpu_id_max = num_cpus - 1;
|
||||||
let x2apic_id_max = get_x2apic_id(cpu_id_max.into(), topology);
|
let x2apic_id_max = get_x2apic_id(cpu_id_max, topology);
|
||||||
if x2apic_id_max >= MAX_SUPPORTED_CPUS {
|
if x2apic_id_max >= MAX_SUPPORTED_CPUS {
|
||||||
return Err(Error::TooManyCpus);
|
return Err(Error::TooManyCpus);
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ pub fn setup_mptable(
|
|||||||
for cpu_id in 0..num_cpus {
|
for cpu_id in 0..num_cpus {
|
||||||
let mut mpc_cpu = MpcCpuWrapper(mpspec::mpc_cpu::default());
|
let mut mpc_cpu = MpcCpuWrapper(mpspec::mpc_cpu::default());
|
||||||
mpc_cpu.0.type_ = mpspec::MP_PROCESSOR as u8;
|
mpc_cpu.0.type_ = mpspec::MP_PROCESSOR as u8;
|
||||||
mpc_cpu.0.apicid = get_x2apic_id(cpu_id as u32, topology) as u8;
|
mpc_cpu.0.apicid = get_x2apic_id(cpu_id, topology) as u8;
|
||||||
mpc_cpu.0.apicver = APIC_VERSION;
|
mpc_cpu.0.apicver = APIC_VERSION;
|
||||||
mpc_cpu.0.cpuflag = mpspec::CPU_ENABLED as u8
|
mpc_cpu.0.cpuflag = mpspec::CPU_ENABLED as u8
|
||||||
| if cpu_id == 0 {
|
| if cpu_id == 0 {
|
||||||
@@ -392,13 +392,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cpu_entry_count() {
|
fn cpu_entry_count() {
|
||||||
let mem = GuestMemoryMmap::from_ranges(&[(
|
let mem =
|
||||||
MPTABLE_START,
|
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(MAX_SUPPORTED_CPUS))])
|
||||||
compute_mp_size(MAX_SUPPORTED_CPUS as u8),
|
.unwrap();
|
||||||
)])
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for i in 0..MAX_SUPPORTED_CPUS as u8 {
|
for i in 0..MAX_SUPPORTED_CPUS {
|
||||||
setup_mptable(MPTABLE_START, &mem, i, None).unwrap();
|
setup_mptable(MPTABLE_START, &mem, i, None).unwrap();
|
||||||
|
|
||||||
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
|
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
|
||||||
@@ -429,10 +427,9 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn cpu_entry_count_max() {
|
fn cpu_entry_count_max() {
|
||||||
let cpus = MAX_SUPPORTED_CPUS + 1;
|
let cpus = MAX_SUPPORTED_CPUS + 1;
|
||||||
let mem =
|
let mem = GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(cpus))]).unwrap();
|
||||||
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(cpus as u8))]).unwrap();
|
|
||||||
|
|
||||||
let result = setup_mptable(MPTABLE_START, &mem, cpus as u8, None);
|
let result = setup_mptable(MPTABLE_START, &mem, cpus, None);
|
||||||
result.unwrap_err();
|
result.unwrap_err();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub struct Aia {
|
|||||||
|
|
||||||
impl Aia {
|
impl Aia {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
vcpu_count: u8,
|
vcpu_count: u32,
|
||||||
interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
|
interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
|
||||||
vm: Arc<dyn hypervisor::Vm>,
|
vm: Arc<dyn hypervisor::Vm>,
|
||||||
) -> Result<Aia> {
|
) -> Result<Aia> {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub struct Gic {
|
|||||||
|
|
||||||
impl Gic {
|
impl Gic {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
vcpu_count: u8,
|
vcpu_count: u32,
|
||||||
interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
|
interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
|
||||||
vm: Arc<dyn hypervisor::Vm>,
|
vm: Arc<dyn hypervisor::Vm>,
|
||||||
) -> Result<Gic> {
|
) -> Result<Gic> {
|
||||||
|
|||||||
28
fuzz/Cargo.lock
generated
28
fuzz/Cargo.lock
generated
@@ -61,9 +61,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.95"
|
version = "1.0.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
|
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arbitrary"
|
name = "arbitrary"
|
||||||
@@ -93,7 +93,6 @@ dependencies = [
|
|||||||
"uuid",
|
"uuid",
|
||||||
"vm-fdt",
|
"vm-fdt",
|
||||||
"vm-memory",
|
"vm-memory",
|
||||||
"vm-migration",
|
|
||||||
"vmm-sys-util",
|
"vmm-sys-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -564,13 +563,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "landlock"
|
name = "landlock"
|
||||||
version = "0.4.1"
|
version = "0.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "18738c5d4c7fae6727a96adb94722ef7ce82f3eafea0a11777e258a93816537e"
|
checksum = "b3d2ef408b88e913bfc6594f5e693d57676f6463ded7d8bf994175364320c706"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
"libc",
|
"libc",
|
||||||
"thiserror 1.0.64",
|
"thiserror 2.0.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -936,9 +935,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_with"
|
name = "serde_with"
|
||||||
version = "3.9.0"
|
version = "3.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857"
|
checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
@@ -947,9 +946,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_with_macros"
|
name = "serde_with_macros"
|
||||||
version = "3.9.0"
|
version = "3.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350"
|
checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -1080,7 +1079,6 @@ name = "tpm"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"byteorder",
|
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"net_gen",
|
"net_gen",
|
||||||
@@ -1190,20 +1188,17 @@ name = "virtio-devices"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"arc-swap",
|
|
||||||
"block",
|
"block",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"epoll",
|
"epoll",
|
||||||
"event_monitor",
|
"event_monitor",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"net_gen",
|
|
||||||
"net_util",
|
"net_util",
|
||||||
"pci",
|
"pci",
|
||||||
"rate_limiter",
|
"rate_limiter",
|
||||||
"seccompiler",
|
"seccompiler",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"serial_buffer",
|
"serial_buffer",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
@@ -1243,12 +1238,10 @@ dependencies = [
|
|||||||
name = "vm-device"
|
name = "vm-device"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"hypervisor",
|
"hypervisor",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"vfio-ioctls",
|
"vfio-ioctls",
|
||||||
"vm-memory",
|
|
||||||
"vmm-sys-util",
|
"vmm-sys-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1284,7 +1277,6 @@ dependencies = [
|
|||||||
name = "vm-virtio"
|
name = "vm-virtio"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
|
||||||
"virtio-queue",
|
"virtio-queue",
|
||||||
"vm-memory",
|
"vm-memory",
|
||||||
]
|
]
|
||||||
@@ -1295,7 +1287,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"acpi_tables",
|
"acpi_tables",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"arc-swap",
|
|
||||||
"arch",
|
"arch",
|
||||||
"bitflags 2.9.0",
|
"bitflags 2.9.0",
|
||||||
"block",
|
"block",
|
||||||
@@ -1329,7 +1320,6 @@ dependencies = [
|
|||||||
"vfio_user",
|
"vfio_user",
|
||||||
"virtio-bindings",
|
"virtio-bindings",
|
||||||
"virtio-devices",
|
"virtio-devices",
|
||||||
"virtio-queue",
|
|
||||||
"vm-allocator",
|
"vm-allocator",
|
||||||
"vm-device",
|
"vm-device",
|
||||||
"vm-memory",
|
"vm-memory",
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ impl RequestHandler for StubApiRequestHandler {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vm_resize(&mut self, _: Option<u8>, _: Option<u64>, _: Option<u64>) -> Result<(), VmError> {
|
fn vm_resize(&mut self, _: Option<u32>, _: Option<u64>, _: Option<u64>) -> Result<(), VmError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ pub trait Vcpu: Send + Sync {
|
|||||||
&self,
|
&self,
|
||||||
vm: &Arc<dyn crate::Vm>,
|
vm: &Arc<dyn crate::Vm>,
|
||||||
kvi: &mut VcpuInit,
|
kvi: &mut VcpuInit,
|
||||||
id: u8,
|
id: u32,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
///
|
///
|
||||||
/// Returns VcpuInit with default value set
|
/// Returns VcpuInit with default value set
|
||||||
@@ -498,7 +498,7 @@ pub trait Vcpu: Send + Sync {
|
|||||||
/// Configure core registers for a given CPU.
|
/// Configure core registers for a given CPU.
|
||||||
///
|
///
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
fn setup_regs(&self, cpu_id: u8, boot_ip: u64, fdt_start: u64) -> Result<()>;
|
fn setup_regs(&self, cpu_id: u32, boot_ip: u64, fdt_start: u64) -> Result<()>;
|
||||||
///
|
///
|
||||||
/// Check if the CPU supports PMU
|
/// Check if the CPU supports PMU
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -559,7 +559,7 @@ impl vm::Vm for KvmVm {
|
|||||||
///
|
///
|
||||||
fn create_vcpu(
|
fn create_vcpu(
|
||||||
&self,
|
&self,
|
||||||
id: u8,
|
id: u32,
|
||||||
vm_ops: Option<Arc<dyn VmOps>>,
|
vm_ops: Option<Arc<dyn VmOps>>,
|
||||||
) -> vm::Result<Arc<dyn cpu::Vcpu>> {
|
) -> vm::Result<Arc<dyn cpu::Vcpu>> {
|
||||||
let fd = self
|
let fd = self
|
||||||
@@ -2150,7 +2150,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
&self,
|
&self,
|
||||||
vm: &Arc<dyn crate::Vm>,
|
vm: &Arc<dyn crate::Vm>,
|
||||||
kvi: &mut crate::VcpuInit,
|
kvi: &mut crate::VcpuInit,
|
||||||
id: u8,
|
id: u32,
|
||||||
) -> cpu::Result<()> {
|
) -> cpu::Result<()> {
|
||||||
use std::arch::is_aarch64_feature_detected;
|
use std::arch::is_aarch64_feature_detected;
|
||||||
#[allow(clippy::nonminimal_bool)]
|
#[allow(clippy::nonminimal_bool)]
|
||||||
@@ -2280,7 +2280,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
/// Configure core registers for a given CPU.
|
/// Configure core registers for a given CPU.
|
||||||
///
|
///
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn setup_regs(&self, cpu_id: u8, boot_ip: u64, fdt_start: u64) -> cpu::Result<()> {
|
fn setup_regs(&self, cpu_id: u32, boot_ip: u64, fdt_start: u64) -> cpu::Result<()> {
|
||||||
// Get the register index of the PSTATE (Processor State) register.
|
// Get the register index of the PSTATE (Processor State) register.
|
||||||
let pstate = offset_of!(kvm_regs, regs.pstate);
|
let pstate = offset_of!(kvm_regs, regs.pstate);
|
||||||
self.fd
|
self.fd
|
||||||
@@ -2326,7 +2326,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
///
|
///
|
||||||
/// Configure registers for a given RISC-V CPU.
|
/// Configure registers for a given RISC-V CPU.
|
||||||
///
|
///
|
||||||
fn setup_regs(&self, cpu_id: u8, boot_ip: u64, fdt_start: u64) -> cpu::Result<()> {
|
fn setup_regs(&self, cpu_id: u32, boot_ip: u64, fdt_start: u64) -> cpu::Result<()> {
|
||||||
// Setting the A0 () to the hartid of this CPU.
|
// Setting the A0 () to the hartid of this CPU.
|
||||||
let a0 = offset_of!(kvm_riscv_core, regs.a0);
|
let a0 = offset_of!(kvm_riscv_core, regs.a0);
|
||||||
self.fd
|
self.fd
|
||||||
|
|||||||
@@ -1262,7 +1262,7 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn setup_regs(&self, cpu_id: u8, boot_ip: u64, fdt_start: u64) -> cpu::Result<()> {
|
fn setup_regs(&self, cpu_id: u32, boot_ip: u64, fdt_start: u64) -> cpu::Result<()> {
|
||||||
let arr_reg_name_value = [(
|
let arr_reg_name_value = [(
|
||||||
hv_register_name_HV_ARM64_REGISTER_PSTATE,
|
hv_register_name_HV_ARM64_REGISTER_PSTATE,
|
||||||
regs::PSTATE_FAULT_BITS_64,
|
regs::PSTATE_FAULT_BITS_64,
|
||||||
@@ -1324,7 +1324,7 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
&self,
|
&self,
|
||||||
_vm: &Arc<dyn crate::Vm>,
|
_vm: &Arc<dyn crate::Vm>,
|
||||||
_kvi: &mut crate::VcpuInit,
|
_kvi: &mut crate::VcpuInit,
|
||||||
_id: u8,
|
_id: u32,
|
||||||
) -> cpu::Result<()> {
|
) -> cpu::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1834,9 +1834,10 @@ impl vm::Vm for MshvVm {
|
|||||||
///
|
///
|
||||||
fn create_vcpu(
|
fn create_vcpu(
|
||||||
&self,
|
&self,
|
||||||
id: u8,
|
id: u32,
|
||||||
vm_ops: Option<Arc<dyn VmOps>>,
|
vm_ops: Option<Arc<dyn VmOps>>,
|
||||||
) -> vm::Result<Arc<dyn cpu::Vcpu>> {
|
) -> vm::Result<Arc<dyn cpu::Vcpu>> {
|
||||||
|
let id: u8 = id.try_into().unwrap();
|
||||||
let vcpu_fd = self
|
let vcpu_fd = self
|
||||||
.fd
|
.fd
|
||||||
.create_vcpu(id)
|
.create_vcpu(id)
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ pub trait Vm: Send + Sync + Any {
|
|||||||
/// Unregister an event that will, when signaled, trigger the `gsi` IRQ.
|
/// Unregister an event that will, when signaled, trigger the `gsi` IRQ.
|
||||||
fn unregister_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>;
|
fn unregister_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>;
|
||||||
/// Creates a new KVM vCPU file descriptor and maps the memory corresponding
|
/// Creates a new KVM vCPU file descriptor and maps the memory corresponding
|
||||||
fn create_vcpu(&self, id: u8, vm_ops: Option<Arc<dyn VmOps>>) -> Result<Arc<dyn Vcpu>>;
|
fn create_vcpu(&self, id: u32, vm_ops: Option<Arc<dyn VmOps>>) -> Result<Arc<dyn Vcpu>>;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn create_vgic(&self, config: VgicConfig) -> Result<Arc<Mutex<dyn Vgic>>>;
|
fn create_vgic(&self, config: VgicConfig) -> Result<Arc<Mutex<dyn Vgic>>>;
|
||||||
#[cfg(target_arch = "riscv64")]
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
|||||||
@@ -725,7 +725,7 @@ fn resize_config(
|
|||||||
memory: Option<&str>,
|
memory: Option<&str>,
|
||||||
balloon: Option<&str>,
|
balloon: Option<&str>,
|
||||||
) -> Result<String, Error> {
|
) -> Result<String, Error> {
|
||||||
let desired_vcpus: Option<u8> = if let Some(cpus) = cpus {
|
let desired_vcpus: Option<u32> = if let Some(cpus) = cpus {
|
||||||
Some(cpus.parse().map_err(Error::InvalidCpuCount)?)
|
Some(cpus.parse().map_err(Error::InvalidCpuCount)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -326,9 +326,9 @@ fn create_srat_table(
|
|||||||
|
|
||||||
for cpu in &node.cpus {
|
for cpu in &node.cpus {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let x2apic_id = arch::x86_64::get_x2apic_id(*cpu as u32, topology);
|
let x2apic_id = arch::x86_64::get_x2apic_id(*cpu, topology);
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
let x2apic_id = *cpu as u32;
|
let x2apic_id = *cpu;
|
||||||
|
|
||||||
// Flags
|
// Flags
|
||||||
// - Enabled = 1 (bit 0)
|
// - Enabled = 1 (bit 0)
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ pub struct VmmPingResponse {
|
|||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize, Default, Debug)]
|
#[derive(Clone, Deserialize, Serialize, Default, Debug)]
|
||||||
pub struct VmResizeData {
|
pub struct VmResizeData {
|
||||||
pub desired_vcpus: Option<u8>,
|
pub desired_vcpus: Option<u32>,
|
||||||
pub desired_ram: Option<u64>,
|
pub desired_ram: Option<u64>,
|
||||||
pub desired_balloon: Option<u64>,
|
pub desired_balloon: Option<u64>,
|
||||||
}
|
}
|
||||||
@@ -307,7 +307,7 @@ pub trait RequestHandler {
|
|||||||
|
|
||||||
fn vm_resize(
|
fn vm_resize(
|
||||||
&mut self,
|
&mut self,
|
||||||
desired_vcpus: Option<u8>,
|
desired_vcpus: Option<u32>,
|
||||||
desired_ram: Option<u64>,
|
desired_ram: Option<u64>,
|
||||||
desired_balloon: Option<u64>,
|
desired_balloon: Option<u64>,
|
||||||
) -> Result<(), VmError>;
|
) -> Result<(), VmError>;
|
||||||
|
|||||||
117
vmm/src/cpu.rs
117
vmm/src/cpu.rs
@@ -338,7 +338,7 @@ macro_rules! round_up {
|
|||||||
pub struct Vcpu {
|
pub struct Vcpu {
|
||||||
// The hypervisor abstracted CPU.
|
// The hypervisor abstracted CPU.
|
||||||
vcpu: Arc<dyn hypervisor::Vcpu>,
|
vcpu: Arc<dyn hypervisor::Vcpu>,
|
||||||
id: u8,
|
id: u32,
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
mpidr: u64,
|
mpidr: u64,
|
||||||
saved_state: Option<CpuState>,
|
saved_state: Option<CpuState>,
|
||||||
@@ -356,8 +356,8 @@ impl Vcpu {
|
|||||||
/// * `vm_ops` - Optional object for exit handling.
|
/// * `vm_ops` - Optional object for exit handling.
|
||||||
/// * `cpu_vendor` - CPU vendor as reported by __cpuid(0x0)
|
/// * `cpu_vendor` - CPU vendor as reported by __cpuid(0x0)
|
||||||
pub fn new(
|
pub fn new(
|
||||||
id: u8,
|
id: u32,
|
||||||
apic_id: u8,
|
apic_id: u32,
|
||||||
vm: &Arc<dyn hypervisor::Vm>,
|
vm: &Arc<dyn hypervisor::Vm>,
|
||||||
vm_ops: Option<Arc<dyn VmOps>>,
|
vm_ops: Option<Arc<dyn VmOps>>,
|
||||||
#[cfg(target_arch = "x86_64")] cpu_vendor: CpuVendor,
|
#[cfg(target_arch = "x86_64")] cpu_vendor: CpuVendor,
|
||||||
@@ -532,8 +532,8 @@ pub struct CpuManager {
|
|||||||
vm_ops: Arc<dyn VmOps>,
|
vm_ops: Arc<dyn VmOps>,
|
||||||
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
|
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
|
||||||
acpi_address: Option<GuestAddress>,
|
acpi_address: Option<GuestAddress>,
|
||||||
proximity_domain_per_cpu: BTreeMap<u8, u32>,
|
proximity_domain_per_cpu: BTreeMap<u32, u32>,
|
||||||
affinity: BTreeMap<u8, Vec<usize>>,
|
affinity: BTreeMap<u32, Vec<usize>>,
|
||||||
dynamic: bool,
|
dynamic: bool,
|
||||||
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
#[cfg(feature = "sev_snp")]
|
#[cfg(feature = "sev_snp")]
|
||||||
@@ -558,7 +558,7 @@ impl BusDevice for CpuManager {
|
|||||||
data[0] = self.selected_cpu;
|
data[0] = self.selected_cpu;
|
||||||
}
|
}
|
||||||
CPU_STATUS_OFFSET => {
|
CPU_STATUS_OFFSET => {
|
||||||
if self.selected_cpu < self.max_vcpus() {
|
if (self.selected_cpu as u32) < self.max_vcpus() {
|
||||||
let state = &self.vcpu_states[usize::from(self.selected_cpu)];
|
let state = &self.vcpu_states[usize::from(self.selected_cpu)];
|
||||||
if state.active() {
|
if state.active() {
|
||||||
data[0] |= 1 << CPU_ENABLE_FLAG;
|
data[0] |= 1 << CPU_ENABLE_FLAG;
|
||||||
@@ -588,7 +588,7 @@ impl BusDevice for CpuManager {
|
|||||||
self.selected_cpu = data[0];
|
self.selected_cpu = data[0];
|
||||||
}
|
}
|
||||||
CPU_STATUS_OFFSET => {
|
CPU_STATUS_OFFSET => {
|
||||||
if self.selected_cpu < self.max_vcpus() {
|
if (self.selected_cpu as u32) < self.max_vcpus() {
|
||||||
let state = &mut self.vcpu_states[usize::from(self.selected_cpu)];
|
let state = &mut self.vcpu_states[usize::from(self.selected_cpu)];
|
||||||
// The ACPI code writes back a 1 to acknowledge the insertion
|
// The ACPI code writes back a 1 to acknowledge the insertion
|
||||||
if (data[0] & (1 << CPU_INSERTING_FLAG) == 1 << CPU_INSERTING_FLAG)
|
if (data[0] & (1 << CPU_INSERTING_FLAG) == 1 << CPU_INSERTING_FLAG)
|
||||||
@@ -604,7 +604,7 @@ impl BusDevice for CpuManager {
|
|||||||
}
|
}
|
||||||
// Trigger removal of vCPU
|
// Trigger removal of vCPU
|
||||||
if data[0] & (1 << CPU_EJECT_FLAG) == 1 << CPU_EJECT_FLAG {
|
if data[0] & (1 << CPU_EJECT_FLAG) == 1 << CPU_EJECT_FLAG {
|
||||||
if let Err(e) = self.remove_vcpu(self.selected_cpu) {
|
if let Err(e) = self.remove_vcpu(self.selected_cpu as u32) {
|
||||||
error!("Error removing vCPU: {:?}", e);
|
error!("Error removing vCPU: {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -730,7 +730,7 @@ impl CpuManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let proximity_domain_per_cpu: BTreeMap<u8, u32> = {
|
let proximity_domain_per_cpu: BTreeMap<u32, u32> = {
|
||||||
let mut cpu_list = Vec::new();
|
let mut cpu_list = Vec::new();
|
||||||
for (proximity_domain, numa_node) in numa_nodes.iter() {
|
for (proximity_domain, numa_node) in numa_nodes.iter() {
|
||||||
for cpu in numa_node.cpus.iter() {
|
for cpu in numa_node.cpus.iter() {
|
||||||
@@ -745,7 +745,7 @@ impl CpuManager {
|
|||||||
let affinity = if let Some(cpu_affinity) = config.affinity.as_ref() {
|
let affinity = if let Some(cpu_affinity) = config.affinity.as_ref() {
|
||||||
cpu_affinity
|
cpu_affinity
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| (a.vcpu, a.host_cpus.clone()))
|
.map(|a| (a.vcpu as u32, a.host_cpus.clone()))
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
BTreeMap::new()
|
BTreeMap::new()
|
||||||
@@ -817,19 +817,19 @@ impl CpuManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_vcpu(&mut self, cpu_id: u8, snapshot: Option<Snapshot>) -> Result<Arc<Mutex<Vcpu>>> {
|
fn create_vcpu(&mut self, cpu_id: u32, snapshot: Option<Snapshot>) -> Result<Arc<Mutex<Vcpu>>> {
|
||||||
info!("Creating vCPU: cpu_id = {}", cpu_id);
|
info!("Creating vCPU: cpu_id = {}", cpu_id);
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let topology = self.get_vcpu_topology();
|
let topology = self.get_vcpu_topology();
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let x2apic_id = arch::x86_64::get_x2apic_id(cpu_id as u32, topology);
|
let x2apic_id = arch::x86_64::get_x2apic_id(cpu_id, topology);
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
let x2apic_id = cpu_id as u32;
|
let x2apic_id = cpu_id;
|
||||||
|
|
||||||
let mut vcpu = Vcpu::new(
|
let mut vcpu = Vcpu::new(
|
||||||
cpu_id,
|
cpu_id,
|
||||||
x2apic_id as u8,
|
x2apic_id,
|
||||||
&self.vm,
|
&self.vm,
|
||||||
Some(self.vm_ops.clone()),
|
Some(self.vm_ops.clone()),
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@@ -884,7 +884,7 @@ impl CpuManager {
|
|||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let topology = self.config.topology.clone().map_or_else(
|
let topology = self.config.topology.clone().map_or_else(
|
||||||
|| Some((1, self.boot_vcpus(), 1)),
|
|| Some((1, self.boot_vcpus().try_into().unwrap(), 1)),
|
||||||
|t| Some((t.threads_per_core, t.cores_per_die, t.dies_per_package)),
|
|t| Some((t.threads_per_core, t.cores_per_die, t.dies_per_package)),
|
||||||
);
|
);
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@@ -907,7 +907,7 @@ impl CpuManager {
|
|||||||
/// Only create new vCPUs if there aren't any inactive ones to reuse
|
/// Only create new vCPUs if there aren't any inactive ones to reuse
|
||||||
fn create_vcpus(
|
fn create_vcpus(
|
||||||
&mut self,
|
&mut self,
|
||||||
desired_vcpus: u8,
|
desired_vcpus: u32,
|
||||||
snapshot: Option<Snapshot>,
|
snapshot: Option<Snapshot>,
|
||||||
) -> Result<Vec<Arc<Mutex<Vcpu>>>> {
|
) -> Result<Vec<Arc<Mutex<Vcpu>>>> {
|
||||||
let mut vcpus: Vec<Arc<Mutex<Vcpu>>> = vec![];
|
let mut vcpus: Vec<Arc<Mutex<Vcpu>>> = vec![];
|
||||||
@@ -919,12 +919,12 @@ impl CpuManager {
|
|||||||
self.present_vcpus()
|
self.present_vcpus()
|
||||||
);
|
);
|
||||||
|
|
||||||
if desired_vcpus > self.config.max_vcpus {
|
if desired_vcpus > self.config.max_vcpus as u32 {
|
||||||
return Err(Error::DesiredVCpuCountExceedsMax);
|
return Err(Error::DesiredVCpuCountExceedsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only create vCPUs in excess of all the allocated vCPUs.
|
// Only create vCPUs in excess of all the allocated vCPUs.
|
||||||
for cpu_id in self.vcpus.len() as u8..desired_vcpus {
|
for cpu_id in self.vcpus.len() as u32..desired_vcpus {
|
||||||
vcpus.push(self.create_vcpu(
|
vcpus.push(self.create_vcpu(
|
||||||
cpu_id,
|
cpu_id,
|
||||||
// TODO: The special format of the CPU id can be removed once
|
// TODO: The special format of the CPU id can be removed once
|
||||||
@@ -962,7 +962,7 @@ impl CpuManager {
|
|||||||
fn start_vcpu(
|
fn start_vcpu(
|
||||||
&mut self,
|
&mut self,
|
||||||
vcpu: Arc<Mutex<Vcpu>>,
|
vcpu: Arc<Mutex<Vcpu>>,
|
||||||
vcpu_id: u8,
|
vcpu_id: u32,
|
||||||
vcpu_thread_barrier: Arc<Barrier>,
|
vcpu_thread_barrier: Arc<Barrier>,
|
||||||
inserting: bool,
|
inserting: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@@ -977,12 +977,16 @@ impl CpuManager {
|
|||||||
let vcpu_pause_signalled = self.vcpus_pause_signalled.clone();
|
let vcpu_pause_signalled = self.vcpus_pause_signalled.clone();
|
||||||
let vcpu_kick_signalled = self.vcpus_kick_signalled.clone();
|
let vcpu_kick_signalled = self.vcpus_kick_signalled.clone();
|
||||||
|
|
||||||
let vcpu_kill = self.vcpu_states[usize::from(vcpu_id)].kill.clone();
|
let vcpu_kill = self.vcpu_states[usize::try_from(vcpu_id).unwrap()]
|
||||||
let vcpu_run_interrupted = self.vcpu_states[usize::from(vcpu_id)]
|
.kill
|
||||||
|
.clone();
|
||||||
|
let vcpu_run_interrupted = self.vcpu_states[usize::try_from(vcpu_id).unwrap()]
|
||||||
.vcpu_run_interrupted
|
.vcpu_run_interrupted
|
||||||
.clone();
|
.clone();
|
||||||
let panic_vcpu_run_interrupted = vcpu_run_interrupted.clone();
|
let panic_vcpu_run_interrupted = vcpu_run_interrupted.clone();
|
||||||
let vcpu_paused = self.vcpu_states[usize::from(vcpu_id)].paused.clone();
|
let vcpu_paused = self.vcpu_states[usize::try_from(vcpu_id).unwrap()]
|
||||||
|
.paused
|
||||||
|
.clone();
|
||||||
|
|
||||||
// Prepare the CPU set the current vCPU is expected to run onto.
|
// Prepare the CPU set the current vCPU is expected to run onto.
|
||||||
let cpuset = self.affinity.get(&vcpu_id).map(|host_cpus| {
|
let cpuset = self.affinity.get(&vcpu_id).map(|host_cpus| {
|
||||||
@@ -1213,8 +1217,8 @@ impl CpuManager {
|
|||||||
|
|
||||||
// On hot plug calls into this function entry_point is None. It is for
|
// On hot plug calls into this function entry_point is None. It is for
|
||||||
// those hotplug CPU additions that we need to set the inserting flag.
|
// those hotplug CPU additions that we need to set the inserting flag.
|
||||||
self.vcpu_states[usize::from(vcpu_id)].handle = handle;
|
self.vcpu_states[usize::try_from(vcpu_id).unwrap()].handle = handle;
|
||||||
self.vcpu_states[usize::from(vcpu_id)].inserting = inserting;
|
self.vcpu_states[usize::try_from(vcpu_id).unwrap()].inserting = inserting;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1222,11 +1226,11 @@ impl CpuManager {
|
|||||||
/// Start up as many vCPUs threads as needed to reach `desired_vcpus`
|
/// Start up as many vCPUs threads as needed to reach `desired_vcpus`
|
||||||
fn activate_vcpus(
|
fn activate_vcpus(
|
||||||
&mut self,
|
&mut self,
|
||||||
desired_vcpus: u8,
|
desired_vcpus: u32,
|
||||||
inserting: bool,
|
inserting: bool,
|
||||||
paused: Option<bool>,
|
paused: Option<bool>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if desired_vcpus > self.config.max_vcpus {
|
if desired_vcpus > self.config.max_vcpus as u32 {
|
||||||
return Err(Error::DesiredVCpuCountExceedsMax);
|
return Err(Error::DesiredVCpuCountExceedsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1257,11 +1261,11 @@ impl CpuManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mark_vcpus_for_removal(&mut self, desired_vcpus: u8) {
|
fn mark_vcpus_for_removal(&mut self, desired_vcpus: u32) {
|
||||||
// Mark vCPUs for removal, actual removal happens on ejection
|
// Mark vCPUs for removal, actual removal happens on ejection
|
||||||
for cpu_id in desired_vcpus..self.present_vcpus() {
|
for cpu_id in desired_vcpus..self.present_vcpus() {
|
||||||
self.vcpu_states[usize::from(cpu_id)].removing = true;
|
self.vcpu_states[usize::try_from(cpu_id).unwrap()].removing = true;
|
||||||
self.vcpu_states[usize::from(cpu_id)]
|
self.vcpu_states[usize::try_from(cpu_id).unwrap()]
|
||||||
.pending_removal
|
.pending_removal
|
||||||
.store(true, Ordering::SeqCst);
|
.store(true, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
@@ -1276,9 +1280,9 @@ impl CpuManager {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_vcpu(&mut self, cpu_id: u8) -> Result<()> {
|
fn remove_vcpu(&mut self, cpu_id: u32) -> Result<()> {
|
||||||
info!("Removing vCPU: cpu_id = {}", cpu_id);
|
info!("Removing vCPU: cpu_id = {}", cpu_id);
|
||||||
let state = &mut self.vcpu_states[usize::from(cpu_id)];
|
let state = &mut self.vcpu_states[usize::try_from(cpu_id).unwrap()];
|
||||||
state.kill.store(true, Ordering::SeqCst);
|
state.kill.store(true, Ordering::SeqCst);
|
||||||
state.signal_thread();
|
state.signal_thread();
|
||||||
state.join_thread()?;
|
state.join_thread()?;
|
||||||
@@ -1306,7 +1310,7 @@ impl CpuManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_restored_vcpus(&mut self) -> Result<()> {
|
pub fn start_restored_vcpus(&mut self) -> Result<()> {
|
||||||
self.activate_vcpus(self.vcpus.len() as u8, false, Some(true))
|
self.activate_vcpus(self.vcpus.len() as u32, false, Some(true))
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Error::StartRestoreVcpu(anyhow!("Failed to start restored vCPUs: {:#?}", e))
|
Error::StartRestoreVcpu(anyhow!("Failed to start restored vCPUs: {:#?}", e))
|
||||||
})?;
|
})?;
|
||||||
@@ -1314,7 +1318,7 @@ impl CpuManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, desired_vcpus: u8) -> Result<bool> {
|
pub fn resize(&mut self, desired_vcpus: u32) -> Result<bool> {
|
||||||
if desired_vcpus.cmp(&self.present_vcpus()) == cmp::Ordering::Equal {
|
if desired_vcpus.cmp(&self.present_vcpus()) == cmp::Ordering::Equal {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
@@ -1387,12 +1391,12 @@ impl CpuManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn boot_vcpus(&self) -> u8 {
|
pub fn boot_vcpus(&self) -> u32 {
|
||||||
self.config.boot_vcpus
|
self.config.boot_vcpus as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn max_vcpus(&self) -> u8 {
|
pub fn max_vcpus(&self) -> u32 {
|
||||||
self.config.max_vcpus
|
self.config.max_vcpus as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@@ -1401,10 +1405,10 @@ impl CpuManager {
|
|||||||
self.cpuid.clone()
|
self.cpuid.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn present_vcpus(&self) -> u8 {
|
fn present_vcpus(&self) -> u32 {
|
||||||
self.vcpu_states
|
self.vcpu_states
|
||||||
.iter()
|
.iter()
|
||||||
.fold(0, |acc, state| acc + state.active() as u8)
|
.fold(0, |acc, state| acc + state.active() as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
@@ -1441,15 +1445,15 @@ impl CpuManager {
|
|||||||
{
|
{
|
||||||
madt.write(36, arch::layout::APIC_START.0);
|
madt.write(36, arch::layout::APIC_START.0);
|
||||||
|
|
||||||
for cpu in 0..self.config.max_vcpus {
|
for cpu in 0..self.config.max_vcpus as u32 {
|
||||||
let x2apic_id = get_x2apic_id(cpu.into(), self.get_vcpu_topology());
|
let x2apic_id = get_x2apic_id(cpu, self.get_vcpu_topology());
|
||||||
|
|
||||||
let lapic = LocalX2Apic {
|
let lapic = LocalX2Apic {
|
||||||
r#type: acpi::ACPI_X2APIC_PROCESSOR,
|
r#type: acpi::ACPI_X2APIC_PROCESSOR,
|
||||||
length: 16,
|
length: 16,
|
||||||
processor_id: cpu.into(),
|
processor_id: cpu,
|
||||||
apic_id: x2apic_id,
|
apic_id: x2apic_id,
|
||||||
flags: if cpu < self.config.boot_vcpus {
|
flags: if cpu < self.config.boot_vcpus as u32 {
|
||||||
1 << MADT_CPU_ENABLE_FLAG
|
1 << MADT_CPU_ENABLE_FLAG
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
@@ -1571,7 +1575,8 @@ impl CpuManager {
|
|||||||
// 1 package, multiple cores, 1 thread per core
|
// 1 package, multiple cores, 1 thread per core
|
||||||
// This is also the behavior when PPTT is missing.
|
// This is also the behavior when PPTT is missing.
|
||||||
let (threads_per_core, cores_per_package, packages) =
|
let (threads_per_core, cores_per_package, packages) =
|
||||||
self.get_vcpu_topology().unwrap_or((1, self.max_vcpus(), 1));
|
self.get_vcpu_topology()
|
||||||
|
.unwrap_or((1, self.max_vcpus().try_into().unwrap(), 1));
|
||||||
|
|
||||||
let mut pptt = Sdt::new(*b"PPTT", 36, 2, *b"CLOUDH", *b"CHPPTT ", 1);
|
let mut pptt = Sdt::new(*b"PPTT", 36, 2, *b"CLOUDH", *b"CHPPTT ", 1);
|
||||||
|
|
||||||
@@ -1922,7 +1927,7 @@ impl CpuManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Cpu {
|
struct Cpu {
|
||||||
cpu_id: u8,
|
cpu_id: u32,
|
||||||
proximity_domain: u32,
|
proximity_domain: u32,
|
||||||
dynamic: bool,
|
dynamic: bool,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@@ -1938,12 +1943,12 @@ const MADT_CPU_ONLINE_CAPABLE_FLAG: usize = 1;
|
|||||||
impl Cpu {
|
impl Cpu {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn generate_mat(&self) -> Vec<u8> {
|
fn generate_mat(&self) -> Vec<u8> {
|
||||||
let x2apic_id = arch::x86_64::get_x2apic_id(self.cpu_id.into(), self.topology);
|
let x2apic_id = arch::x86_64::get_x2apic_id(self.cpu_id, self.topology);
|
||||||
|
|
||||||
let lapic = LocalX2Apic {
|
let lapic = LocalX2Apic {
|
||||||
r#type: crate::acpi::ACPI_X2APIC_PROCESSOR,
|
r#type: crate::acpi::ACPI_X2APIC_PROCESSOR,
|
||||||
length: 16,
|
length: 16,
|
||||||
processor_id: self.cpu_id.into(),
|
processor_id: self.cpu_id,
|
||||||
apic_id: x2apic_id,
|
apic_id: x2apic_id,
|
||||||
flags: 1 << MADT_CPU_ENABLE_FLAG,
|
flags: 1 << MADT_CPU_ENABLE_FLAG,
|
||||||
_reserved: 0,
|
_reserved: 0,
|
||||||
@@ -2045,7 +2050,7 @@ impl Aml for Cpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct CpuNotify {
|
struct CpuNotify {
|
||||||
cpu_id: u8,
|
cpu_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Aml for CpuNotify {
|
impl Aml for CpuNotify {
|
||||||
@@ -2060,7 +2065,7 @@ impl Aml for CpuNotify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct CpuMethods {
|
struct CpuMethods {
|
||||||
max_vcpus: u8,
|
max_vcpus: u32,
|
||||||
dynamic: bool,
|
dynamic: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2098,7 +2103,7 @@ impl Aml for CpuMethods {
|
|||||||
|
|
||||||
let mut cpu_notifies_refs: Vec<&dyn Aml> = Vec::new();
|
let mut cpu_notifies_refs: Vec<&dyn Aml> = Vec::new();
|
||||||
for cpu_id in 0..self.max_vcpus {
|
for cpu_id in 0..self.max_vcpus {
|
||||||
cpu_notifies_refs.push(&cpu_notifies[usize::from(cpu_id)]);
|
cpu_notifies_refs.push(&cpu_notifies[usize::try_from(cpu_id).unwrap()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
aml::Method::new("CTFY".into(), 2, true, cpu_notifies_refs).to_aml_bytes(sink);
|
aml::Method::new("CTFY".into(), 2, true, cpu_notifies_refs).to_aml_bytes(sink);
|
||||||
@@ -2242,7 +2247,7 @@ impl Aml for CpuManager {
|
|||||||
let uid = aml::Name::new("_CID".into(), &aml::EISAName::new("PNP0A05"));
|
let uid = aml::Name::new("_CID".into(), &aml::EISAName::new("PNP0A05"));
|
||||||
// Bundle methods together under a common object
|
// Bundle methods together under a common object
|
||||||
let methods = CpuMethods {
|
let methods = CpuMethods {
|
||||||
max_vcpus: self.config.max_vcpus,
|
max_vcpus: self.config.max_vcpus as u32,
|
||||||
dynamic: self.dynamic,
|
dynamic: self.dynamic,
|
||||||
};
|
};
|
||||||
let mut cpu_data_inner: Vec<&dyn Aml> = vec![&hid, &uid, &methods];
|
let mut cpu_data_inner: Vec<&dyn Aml> = vec![&hid, &uid, &methods];
|
||||||
@@ -2250,7 +2255,7 @@ impl Aml for CpuManager {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let topology = self.get_vcpu_topology();
|
let topology = self.get_vcpu_topology();
|
||||||
let mut cpu_devices = Vec::new();
|
let mut cpu_devices = Vec::new();
|
||||||
for cpu_id in 0..self.config.max_vcpus {
|
for cpu_id in 0..(self.config.max_vcpus as u32) {
|
||||||
let proximity_domain = *self.proximity_domain_per_cpu.get(&cpu_id).unwrap_or(&0);
|
let proximity_domain = *self.proximity_domain_per_cpu.get(&cpu_id).unwrap_or(&0);
|
||||||
let cpu_device = Cpu {
|
let cpu_device = Cpu {
|
||||||
cpu_id,
|
cpu_id,
|
||||||
@@ -2624,7 +2629,7 @@ impl CpuElf64Writable for CpuManager {
|
|||||||
pos += descsz - size_of::<X86_64UserRegs>() - size_of::<u64>();
|
pos += descsz - size_of::<X86_64UserRegs>() - size_of::<u64>();
|
||||||
|
|
||||||
let orig_rax: u64 = 0;
|
let orig_rax: u64 = 0;
|
||||||
let gregs = self.vcpus[usize::from(vcpu_id)]
|
let gregs = self.vcpus[usize::try_from(vcpu_id).unwrap()]
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.vcpu
|
.vcpu
|
||||||
@@ -2652,7 +2657,7 @@ impl CpuElf64Writable for CpuManager {
|
|||||||
orig_rax,
|
orig_rax,
|
||||||
];
|
];
|
||||||
|
|
||||||
let sregs = self.vcpus[usize::from(vcpu_id)]
|
let sregs = self.vcpus[usize::try_from(vcpu_id).unwrap()]
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.vcpu
|
.vcpu
|
||||||
@@ -2726,7 +2731,7 @@ impl CpuElf64Writable for CpuManager {
|
|||||||
|
|
||||||
pos += round_up!(COREDUMP_NAME_SIZE as usize, 4);
|
pos += round_up!(COREDUMP_NAME_SIZE as usize, 4);
|
||||||
|
|
||||||
let gregs = self.vcpus[usize::from(vcpu_id)]
|
let gregs = self.vcpus[usize::try_from(vcpu_id).unwrap()]
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.vcpu
|
.vcpu
|
||||||
@@ -2755,7 +2760,7 @@ impl CpuElf64Writable for CpuManager {
|
|||||||
gregs.get_r15(),
|
gregs.get_r15(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let sregs = self.vcpus[usize::from(vcpu_id)]
|
let sregs = self.vcpus[usize::try_from(vcpu_id).unwrap()]
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.vcpu
|
.vcpu
|
||||||
|
|||||||
@@ -1672,7 +1672,7 @@ impl DeviceManager {
|
|||||||
) -> DeviceManagerResult<Arc<Mutex<dyn InterruptController>>> {
|
) -> DeviceManagerResult<Arc<Mutex<dyn InterruptController>>> {
|
||||||
let interrupt_controller: Arc<Mutex<gic::Gic>> = Arc::new(Mutex::new(
|
let interrupt_controller: Arc<Mutex<gic::Gic>> = Arc::new(Mutex::new(
|
||||||
gic::Gic::new(
|
gic::Gic::new(
|
||||||
self.config.lock().unwrap().cpus.boot_vcpus,
|
self.config.lock().unwrap().cpus.boot_vcpus as u32,
|
||||||
Arc::clone(&self.msi_interrupt_manager),
|
Arc::clone(&self.msi_interrupt_manager),
|
||||||
self.address_manager.vm.clone(),
|
self.address_manager.vm.clone(),
|
||||||
)
|
)
|
||||||
@@ -1725,7 +1725,7 @@ impl DeviceManager {
|
|||||||
) -> DeviceManagerResult<Arc<Mutex<dyn InterruptController>>> {
|
) -> DeviceManagerResult<Arc<Mutex<dyn InterruptController>>> {
|
||||||
let interrupt_controller: Arc<Mutex<aia::Aia>> = Arc::new(Mutex::new(
|
let interrupt_controller: Arc<Mutex<aia::Aia>> = Arc::new(Mutex::new(
|
||||||
aia::Aia::new(
|
aia::Aia::new(
|
||||||
self.config.lock().unwrap().cpus.boot_vcpus,
|
self.config.lock().unwrap().cpus.boot_vcpus as u32,
|
||||||
Arc::clone(&self.msi_interrupt_manager),
|
Arc::clone(&self.msi_interrupt_manager),
|
||||||
self.address_manager.vm.clone(),
|
self.address_manager.vm.clone(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1808,7 +1808,7 @@ impl RequestHandler for Vmm {
|
|||||||
|
|
||||||
fn vm_resize(
|
fn vm_resize(
|
||||||
&mut self,
|
&mut self,
|
||||||
desired_vcpus: Option<u8>,
|
desired_vcpus: Option<u32>,
|
||||||
desired_ram: Option<u64>,
|
desired_ram: Option<u64>,
|
||||||
desired_balloon: Option<u64>,
|
desired_balloon: Option<u64>,
|
||||||
) -> result::Result<(), VmError> {
|
) -> result::Result<(), VmError> {
|
||||||
@@ -1824,7 +1824,7 @@ impl RequestHandler for Vmm {
|
|||||||
} else {
|
} else {
|
||||||
let mut config = self.vm_config.as_ref().unwrap().lock().unwrap();
|
let mut config = self.vm_config.as_ref().unwrap().lock().unwrap();
|
||||||
if let Some(desired_vcpus) = desired_vcpus {
|
if let Some(desired_vcpus) = desired_vcpus {
|
||||||
config.cpus.boot_vcpus = desired_vcpus;
|
config.cpus.boot_vcpus = desired_vcpus.try_into().unwrap();
|
||||||
}
|
}
|
||||||
if let Some(desired_ram) = desired_ram {
|
if let Some(desired_ram) = desired_ram {
|
||||||
config.memory.size = desired_ram;
|
config.memory.size = desired_ram;
|
||||||
|
|||||||
@@ -621,7 +621,7 @@ impl Vm {
|
|||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
if tdx_enabled {
|
if tdx_enabled {
|
||||||
let cpuid = cpu_manager.lock().unwrap().common_cpuid();
|
let cpuid = cpu_manager.lock().unwrap().common_cpuid();
|
||||||
let max_vcpus = cpu_manager.lock().unwrap().max_vcpus() as u32;
|
let max_vcpus = cpu_manager.lock().unwrap().max_vcpus();
|
||||||
vm.tdx_init(&cpuid, max_vcpus)
|
vm.tdx_init(&cpuid, max_vcpus)
|
||||||
.map_err(Error::InitializeTdxVm)?;
|
.map_err(Error::InitializeTdxVm)?;
|
||||||
}
|
}
|
||||||
@@ -948,7 +948,7 @@ impl Vm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(cpus) = &config.cpus {
|
if let Some(cpus) = &config.cpus {
|
||||||
node.cpus.extend(cpus);
|
node.cpus.extend(cpus.iter().map(|cpu| *cpu as u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(pci_segments) = &config.pci_segments {
|
if let Some(pci_segments) = &config.pci_segments {
|
||||||
@@ -1719,7 +1719,7 @@ impl Vm {
|
|||||||
|
|
||||||
pub fn resize(
|
pub fn resize(
|
||||||
&mut self,
|
&mut self,
|
||||||
desired_vcpus: Option<u8>,
|
desired_vcpus: Option<u32>,
|
||||||
desired_memory: Option<u64>,
|
desired_memory: Option<u64>,
|
||||||
desired_balloon: Option<u64>,
|
desired_balloon: Option<u64>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@@ -1739,7 +1739,7 @@ impl Vm {
|
|||||||
.notify_hotplug(AcpiNotificationFlags::CPU_DEVICES_CHANGED)
|
.notify_hotplug(AcpiNotificationFlags::CPU_DEVICES_CHANGED)
|
||||||
.map_err(Error::DeviceManager)?;
|
.map_err(Error::DeviceManager)?;
|
||||||
}
|
}
|
||||||
self.config.lock().unwrap().cpus.boot_vcpus = desired_vcpus;
|
self.config.lock().unwrap().cpus.boot_vcpus = desired_vcpus.try_into().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(desired_memory) = desired_memory {
|
if let Some(desired_memory) = desired_memory {
|
||||||
|
|||||||
Reference in New Issue
Block a user