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:
Peter Oskolkov
2025-07-29 19:02:20 +00:00
committed by Bo Chen
parent 5d478c534e
commit aa8e9cd91a
21 changed files with 116 additions and 123 deletions

View File

@@ -370,7 +370,7 @@ fn create_cpu_nodes(
if numa_nodes.len() > 1 {
for numa_node_idx in 0..numa_nodes.len() {
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)?;
}
}

View File

@@ -67,7 +67,7 @@ pub struct EntryPoint {
/// Configure the specified VCPU, and return its MPIDR.
pub fn configure_vcpu(
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
id: u32,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
) -> super::Result<u64> {
if let Some((kernel_entry_point, _guest_memory)) = boot_setup {

View File

@@ -123,7 +123,7 @@ fn pagesize() -> usize {
pub struct NumaNode {
pub memory_regions: Vec<Arc<GuestRegionMmap>>,
pub hotplug_regions: Vec<Arc<GuestRegionMmap>>,
pub cpus: Vec<u8>,
pub cpus: Vec<u32>,
pub pci_segments: Vec<u16>,
pub distances: BTreeMap<u32, u8>,
pub memory_zones: Vec<String>,

View File

@@ -59,7 +59,7 @@ pub struct EntryPoint {
/// Configure the specified VCPU, and return its MPIDR.
pub fn configure_vcpu(
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
id: u32,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
) -> super::Result<()> {
if let Some((kernel_entry_point, _guest_memory)) = boot_setup {

View File

@@ -820,14 +820,14 @@ pub fn generate_common_cpuid(
pub fn configure_vcpu(
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
id: u32,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
cpuid: Vec<CpuIdEntry>,
kvm_hyperv: bool,
cpu_vendor: CpuVendor,
topology: Option<(u8, u8, u8)>,
) -> 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()
let mut cpuid = cpuid;
@@ -946,7 +946,7 @@ pub fn configure_system(
cmdline_addr: GuestAddress,
cmdline_size: usize,
initramfs: &Option<InitramfsConfig>,
_num_cpus: u8,
_num_cpus: u32,
setup_header: Option<setup_header>,
rsdp_addr: Option<GuestAddress>,
sgx_epc_region: Option<SgxEpcRegion>,
@@ -1365,10 +1365,10 @@ fn update_cpuid_topology(
cores_per_die: u8,
dies_per_package: u8,
cpu_vendor: CpuVendor,
id: u8,
id: u32,
) {
let x2apic_id = get_x2apic_id(
id as u32,
id,
Some((threads_per_core, cores_per_die, dies_per_package)),
);

View File

@@ -121,7 +121,7 @@ fn mpf_intel_compute_checksum(v: &mpspec::mpf_intel) -> u8 {
(!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::<MpcTableWrapper>()
+ mem::size_of::<MpcCpuWrapper>() * (num_cpus as usize)
@@ -135,12 +135,12 @@ fn compute_mp_size(num_cpus: u8) -> usize {
pub fn setup_mptable(
offset: GuestAddress,
mem: &GuestMemoryMmap,
num_cpus: u8,
num_cpus: u32,
topology: Option<(u8, u8, u8)>,
) -> Result<()> {
if num_cpus > 0 {
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 {
return Err(Error::TooManyCpus);
}
@@ -195,7 +195,7 @@ pub fn setup_mptable(
for cpu_id in 0..num_cpus {
let mut mpc_cpu = MpcCpuWrapper(mpspec::mpc_cpu::default());
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.cpuflag = mpspec::CPU_ENABLED as u8
| if cpu_id == 0 {
@@ -392,13 +392,11 @@ mod tests {
#[test]
fn cpu_entry_count() {
let mem = GuestMemoryMmap::from_ranges(&[(
MPTABLE_START,
compute_mp_size(MAX_SUPPORTED_CPUS as u8),
)])
.unwrap();
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(MAX_SUPPORTED_CPUS))])
.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();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
@@ -429,10 +427,9 @@ mod tests {
#[test]
fn cpu_entry_count_max() {
let cpus = MAX_SUPPORTED_CPUS + 1;
let mem =
GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(cpus as u8))]).unwrap();
let mem = GuestMemoryMmap::from_ranges(&[(MPTABLE_START, compute_mp_size(cpus))]).unwrap();
let result = setup_mptable(MPTABLE_START, &mem, cpus as u8, None);
let result = setup_mptable(MPTABLE_START, &mem, cpus, None);
result.unwrap_err();
}
}