Hi, This one introduces a -maxcpus setting, allowing the user to specify the maximum number of vCPUs the system can have, as discussed with Gleb earlier in the week. Cheers, Jes
Introduce -maxcpus flag to QEMU and pass the value to the BIOS through FW_CFG. Follow on patch will use it to determine the size of the MADT. Signed-off-by: Jes Sorensen <jes@xxxxxxx> --- hw/fw_cfg.c | 1 + hw/fw_cfg.h | 1 + kvm/bios/rombios32.c | 16 ++++++++++++++++ qemu-options.hx | 9 +++++++++ sysemu.h | 1 + vl.c | 8 ++++++++ 6 files changed, 36 insertions(+) Index: qemu-kvm/hw/fw_cfg.c =================================================================== --- qemu-kvm.orig/hw/fw_cfg.c +++ qemu-kvm/hw/fw_cfg.c @@ -279,6 +279,7 @@ void *fw_cfg_init(uint32_t ctl_port, uin fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16); fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC)); fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); + fw_cfg_add_i16(s, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); register_savevm("fw_cfg", -1, 1, fw_cfg_save, fw_cfg_load, s); qemu_register_reset(fw_cfg_reset, 0, s); Index: qemu-kvm/hw/fw_cfg.h =================================================================== --- qemu-kvm.orig/hw/fw_cfg.h +++ qemu-kvm/hw/fw_cfg.h @@ -15,6 +15,7 @@ #define FW_CFG_INITRD_SIZE 0x0b #define FW_CFG_BOOT_DEVICE 0x0c #define FW_CFG_NUMA 0x0d +#define FW_CFG_MAX_CPUS 0x0e #define FW_CFG_MAX_ENTRY 0x10 #define FW_CFG_WRITE_CHANNEL 0x4000 Index: qemu-kvm/kvm/bios/rombios32.c =================================================================== --- qemu-kvm.orig/kvm/bios/rombios32.c +++ qemu-kvm/kvm/bios/rombios32.c @@ -441,6 +441,7 @@ void delay_ms(int n) } uint16_t smp_cpus; +uint16_t max_cpus = MAX_CPUS; uint32_t cpuid_signature; uint32_t cpuid_features; uint32_t cpuid_ext_features; @@ -484,6 +485,7 @@ void wrmsr_smp(uint32_t index, uint64_t #define QEMU_CFG_ID 0x01 #define QEMU_CFG_UUID 0x02 #define QEMU_CFG_NUMA 0x0D +#define QEMU_CFG_MAX_CPUS 0x0E #define QEMU_CFG_ARCH_LOCAL 0x8000 #define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0) #define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1) @@ -546,6 +548,19 @@ static uint16_t smbios_entries(void) return cnt; } +static uint16_t get_max_cpus(void) +{ + uint16_t cnt; + + qemu_cfg_select(QEMU_CFG_MAX_CPUS); + qemu_cfg_read((uint8_t*)&cnt, sizeof(cnt)); + + if (!cnt) + cnt = MAX_CPUS; + + return cnt; +} + uint64_t qemu_cfg_get64 (void) { uint64_t ret; @@ -1655,6 +1670,7 @@ void acpi_bios_init(void) addr += sizeof(SSDTCode); #ifdef BX_QEMU + max_cpus = get_max_cpus(); qemu_cfg_select(QEMU_CFG_NUMA); nb_numa_nodes = qemu_cfg_get64(); #else Index: qemu-kvm/qemu-options.hx =================================================================== --- qemu-kvm.orig/qemu-options.hx +++ qemu-kvm/qemu-options.hx @@ -47,6 +47,15 @@ CPUs are supported. On Sparc32 target, L to 4. ETEXI +DEF("maxcpus", HAS_ARG, QEMU_OPTION_maxcpus, + "-maxcpus n set maximumthe number of possibly CPUs to 'n'\n") +STEXI +@item -maxcpus @var{n} +Set the maximum number of possible CPUs to @var(n). @var(n) has to be +bigger or equal to the value of -smp. If @var(n) is equal to -smp, +there will be no space for hotplug cpus to be added later. +ETEXI + DEF("numa", HAS_ARG, QEMU_OPTION_numa, "-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node]\n") STEXI Index: qemu-kvm/sysemu.h =================================================================== --- qemu-kvm.orig/sysemu.h +++ qemu-kvm/sysemu.h @@ -119,6 +119,7 @@ extern int alt_grab; extern int usb_enabled; extern int no_virtio_balloon; extern int smp_cpus; +extern int max_cpus; extern int cursor_hide; extern int graphic_rotate; extern int no_quit; Index: qemu-kvm/vl.c =================================================================== --- qemu-kvm.orig/vl.c +++ qemu-kvm/vl.c @@ -246,6 +246,7 @@ int singlestep = 0; const char *assigned_devices[MAX_DEV_ASSIGN_CMDLINE]; int assigned_devices_index; int smp_cpus = 1; +int max_cpus = 16; const char *vnc_display; int acpi_enabled = 1; int no_hpet = 0; @@ -5666,6 +5667,13 @@ int main(int argc, char **argv, char **e exit(1); } break; + case QEMU_OPTION_maxcpus: + max_cpus = atoi(optarg); + if ((max_cpus < 1) || (max_cpus > machine->max_cpus)) { + fprintf(stderr, "Invalid number of CPUs\n"); + exit(1); + } + break; case QEMU_OPTION_vnc: display_type = DT_VNC; vnc_display = optarg;