From 14a25a511b36806f6cb8c30987850a7280235caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 11 Jul 2019 14:05:46 +0100 Subject: [PATCH 01/13] includes: remove stale [smp|max]_cpus externs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit a5e0b3311 removed these in favour of querying machine properties. Remove the extern declarations as well. Signed-off-by: Alex Bennée Cc: Like Xu Message-Id: <20190711130546.18578-1-alex.bennee@linaro.org> Reviewed-by: Richard Henderson Reviewed-by: Like Xu Fixes: a5e0b331193a ("vl.c: Replace smp global variables with smp machine properties") Signed-off-by: Eduardo Habkost --- include/sysemu/sysemu.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index d2c38f611a..44f18eb739 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -42,8 +42,6 @@ extern const char *keyboard_layout; extern int win2k_install_hack; extern int alt_grab; extern int ctrl_grab; -extern int smp_cpus; -extern unsigned int max_cpus; extern int cursor_hide; extern int graphic_rotate; extern int no_quit; From 2744ece8095b8cdb0d667654debc1d80dd57bbd3 Mon Sep 17 00:00:00 2001 From: Tao Xu Date: Fri, 9 Aug 2019 14:57:21 +0800 Subject: [PATCH 02/13] hw/arm: simplify arm_load_dtb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In struct arm_boot_info, kernel_filename, initrd_filename and kernel_cmdline are copied from from MachineState. This patch add MachineState as a parameter into arm_load_dtb() and move the copy chunk of kernel_filename, initrd_filename and kernel_cmdline into arm_load_kernel(). Reviewed-by: Igor Mammedov Reviewed-by: Liu Jingqi Suggested-by: Igor Mammedov Signed-off-by: Tao Xu Message-Id: <20190809065731.9097-2-tao3.xu@intel.com> Reviewed-by: Alistair Francis Acked-by: Andrew Jeffery Acked-by: Cédric Le Goater [ehabkost: include hw/boards.h again to fix build failures] Signed-off-by: Eduardo Habkost --- hw/arm/aspeed.c | 5 +---- hw/arm/boot.c | 15 +++++++++------ hw/arm/collie.c | 8 +------- hw/arm/cubieboard.c | 5 +---- hw/arm/exynos4_boards.c | 7 ++----- hw/arm/highbank.c | 8 +------- hw/arm/imx25_pdk.c | 5 +---- hw/arm/integratorcp.c | 8 +------- hw/arm/kzm.c | 5 +---- hw/arm/mainstone.c | 5 +---- hw/arm/mcimx6ul-evk.c | 5 +---- hw/arm/mcimx7d-sabre.c | 5 +---- hw/arm/musicpal.c | 8 +------- hw/arm/nseries.c | 5 +---- hw/arm/omap_sx1.c | 5 +---- hw/arm/palm.c | 10 ++-------- hw/arm/raspi.c | 6 +----- hw/arm/realview.c | 5 +---- hw/arm/sabrelite.c | 5 +---- hw/arm/sbsa-ref.c | 3 +-- hw/arm/spitz.c | 5 +---- hw/arm/tosa.c | 8 +------- hw/arm/versatilepb.c | 5 +---- hw/arm/vexpress.c | 5 +---- hw/arm/virt.c | 8 +++----- hw/arm/xilinx_zynq.c | 8 +------- hw/arm/xlnx-versal-virt.c | 7 ++----- hw/arm/xlnx-zcu102.c | 5 +---- hw/arm/z2.c | 8 +------- include/hw/arm/boot.h | 4 ++-- 30 files changed, 44 insertions(+), 147 deletions(-) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index 7a2e885e0b..13e208c78c 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -242,9 +242,6 @@ static void aspeed_board_init(MachineState *machine, write_boot_rom(drive0, FIRMWARE_ADDR, fl->size, &error_abort); } - aspeed_board_binfo.kernel_filename = machine->kernel_filename; - aspeed_board_binfo.initrd_filename = machine->initrd_filename; - aspeed_board_binfo.kernel_cmdline = machine->kernel_cmdline; aspeed_board_binfo.ram_size = ram_size; aspeed_board_binfo.loader_start = sc->info->memmap[ASPEED_SDRAM]; aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus; @@ -253,7 +250,7 @@ static void aspeed_board_init(MachineState *machine, cfg->i2c_init(bmc); } - arm_load_kernel(ARM_CPU(first_cpu), &aspeed_board_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo); } static void palmetto_bmc_i2c_init(AspeedBoardState *bmc) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index eff89ab80e..b46eaefa2d 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -17,6 +17,7 @@ #include "sysemu/kvm.h" #include "sysemu/sysemu.h" #include "sysemu/numa.h" +#include "hw/boards.h" #include "sysemu/reset.h" #include "hw/loader.h" #include "elf.h" @@ -523,7 +524,7 @@ static void fdt_add_psci_node(void *fdt) } int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, - hwaddr addr_limit, AddressSpace *as) + hwaddr addr_limit, AddressSpace *as, MachineState *ms) { void *fdt = NULL; int size, rc, n = 0; @@ -626,9 +627,9 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, qemu_fdt_add_subnode(fdt, "/chosen"); } - if (binfo->kernel_cmdline && *binfo->kernel_cmdline) { + if (ms->kernel_cmdline && *ms->kernel_cmdline) { rc = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", - binfo->kernel_cmdline); + ms->kernel_cmdline); if (rc < 0) { fprintf(stderr, "couldn't set /chosen/bootargs\n"); goto fail; @@ -1260,7 +1261,7 @@ static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info) */ } -void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) +void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) { CPUState *cs; AddressSpace *as = arm_boot_address_space(cpu, info); @@ -1281,7 +1282,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) * doesn't support secure. */ assert(!(info->secure_board_setup && kvm_enabled())); - + info->kernel_filename = ms->kernel_filename; + info->kernel_cmdline = ms->kernel_cmdline; + info->initrd_filename = ms->initrd_filename; info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb"); info->dtb_limit = 0; @@ -1293,7 +1296,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) } if (!info->skip_dtb_autoload && have_dtb(info)) { - if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) { + if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms) < 0) { exit(1); } } diff --git a/hw/arm/collie.c b/hw/arm/collie.c index 219643c633..b1288ccea8 100644 --- a/hw/arm/collie.c +++ b/hw/arm/collie.c @@ -25,9 +25,6 @@ static struct arm_boot_info collie_binfo = { static void collie_init(MachineState *machine) { - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; StrongARMState *s; DriveInfo *dinfo; MemoryRegion *sysmem = get_system_memory(); @@ -46,11 +43,8 @@ static void collie_init(MachineState *machine) sysbus_create_simple("scoop", 0x40800000, NULL); - collie_binfo.kernel_filename = kernel_filename; - collie_binfo.kernel_cmdline = kernel_cmdline; - collie_binfo.initrd_filename = initrd_filename; collie_binfo.board_id = 0x208; - arm_load_kernel(s->cpu, &collie_binfo); + arm_load_kernel(s->cpu, machine, &collie_binfo); } static void collie_machine_init(MachineClass *mc) diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c index 38e0ca0f53..1bef3cb9af 100644 --- a/hw/arm/cubieboard.c +++ b/hw/arm/cubieboard.c @@ -73,10 +73,7 @@ static void cubieboard_init(MachineState *machine) /* TODO create and connect IDE devices for ide_drive_get() */ cubieboard_binfo.ram_size = machine->ram_size; - cubieboard_binfo.kernel_filename = machine->kernel_filename; - cubieboard_binfo.kernel_cmdline = machine->kernel_cmdline; - cubieboard_binfo.initrd_filename = machine->initrd_filename; - arm_load_kernel(&s->a10->cpu, &cubieboard_binfo); + arm_load_kernel(&s->a10->cpu, machine, &cubieboard_binfo); } static void cubieboard_machine_init(MachineClass *mc) diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c index f69358a5ba..be21f50387 100644 --- a/hw/arm/exynos4_boards.c +++ b/hw/arm/exynos4_boards.c @@ -122,9 +122,6 @@ exynos4_boards_init_common(MachineState *machine, exynos4_board_binfo.board_id = exynos4_board_id[board_type]; exynos4_board_binfo.smp_bootreg_addr = exynos4_board_smp_bootreg_addr[board_type]; - exynos4_board_binfo.kernel_filename = machine->kernel_filename; - exynos4_board_binfo.initrd_filename = machine->initrd_filename; - exynos4_board_binfo.kernel_cmdline = machine->kernel_cmdline; exynos4_board_binfo.gic_cpu_if_addr = EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100; @@ -143,7 +140,7 @@ static void nuri_init(MachineState *machine) { exynos4_boards_init_common(machine, EXYNOS4_BOARD_NURI); - arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &exynos4_board_binfo); } static void smdkc210_init(MachineState *machine) @@ -153,7 +150,7 @@ static void smdkc210_init(MachineState *machine) lan9215_init(SMDK_LAN9118_BASE_ADDR, qemu_irq_invert(s->soc.irq_table[exynos4210_get_irq(37, 1)])); - arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &exynos4_board_binfo); } static void nuri_class_init(ObjectClass *oc, void *data) diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c index 362e5ba044..f1724d6929 100644 --- a/hw/arm/highbank.c +++ b/hw/arm/highbank.c @@ -236,9 +236,6 @@ enum cxmachines { static void calxeda_init(MachineState *machine, enum cxmachines machine_id) { ram_addr_t ram_size = machine->ram_size; - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; DeviceState *dev = NULL; SysBusDevice *busdev; qemu_irq pic[128]; @@ -390,9 +387,6 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) /* TODO create and connect IDE devices for ide_drive_get() */ highbank_binfo.ram_size = ram_size; - highbank_binfo.kernel_filename = kernel_filename; - highbank_binfo.kernel_cmdline = kernel_cmdline; - highbank_binfo.initrd_filename = initrd_filename; /* highbank requires a dtb in order to boot, and the dtb will override * the board ID. The following value is ignored, so set it to -1 to be * clear that the value is meaningless. @@ -412,7 +406,7 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) "may not boot."); } - arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &highbank_binfo); } static void highbank_init(MachineState *machine) diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c index 5d673e47bc..c76fc2bd94 100644 --- a/hw/arm/imx25_pdk.c +++ b/hw/arm/imx25_pdk.c @@ -116,9 +116,6 @@ static void imx25_pdk_init(MachineState *machine) } imx25_pdk_binfo.ram_size = machine->ram_size; - imx25_pdk_binfo.kernel_filename = machine->kernel_filename; - imx25_pdk_binfo.kernel_cmdline = machine->kernel_cmdline; - imx25_pdk_binfo.initrd_filename = machine->initrd_filename; imx25_pdk_binfo.loader_start = FSL_IMX25_SDRAM0_ADDR; imx25_pdk_binfo.board_id = 1771, imx25_pdk_binfo.nb_cpus = 1; @@ -129,7 +126,7 @@ static void imx25_pdk_init(MachineState *machine) * fail. */ if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu, &imx25_pdk_binfo); + arm_load_kernel(&s->soc.cpu, machine, &imx25_pdk_binfo); } } diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index 200568b42a..524970840d 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -582,9 +582,6 @@ static struct arm_boot_info integrator_binfo = { static void integratorcp_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; Object *cpuobj; ARMCPU *cpu; MemoryRegion *address_space_mem = get_system_memory(); @@ -654,10 +651,7 @@ static void integratorcp_init(MachineState *machine) sysbus_create_simple("pl110", 0xc0000000, pic[22]); integrator_binfo.ram_size = ram_size; - integrator_binfo.kernel_filename = kernel_filename; - integrator_binfo.kernel_cmdline = kernel_cmdline; - integrator_binfo.initrd_filename = initrd_filename; - arm_load_kernel(cpu, &integrator_binfo); + arm_load_kernel(cpu, machine, &integrator_binfo); } static void integratorcp_machine_init(MachineClass *mc) diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c index 2f052e1f8c..1d5ef289d5 100644 --- a/hw/arm/kzm.c +++ b/hw/arm/kzm.c @@ -127,13 +127,10 @@ static void kzm_init(MachineState *machine) } kzm_binfo.ram_size = machine->ram_size; - kzm_binfo.kernel_filename = machine->kernel_filename; - kzm_binfo.kernel_cmdline = machine->kernel_cmdline; - kzm_binfo.initrd_filename = machine->initrd_filename; kzm_binfo.nb_cpus = 1; if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu, &kzm_binfo); + arm_load_kernel(&s->soc.cpu, machine, &kzm_binfo); } } diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c index 1bad1aea76..b01ce3ce08 100644 --- a/hw/arm/mainstone.c +++ b/hw/arm/mainstone.c @@ -176,11 +176,8 @@ static void mainstone_common_init(MemoryRegion *address_space_mem, smc91c111_init(&nd_table[0], MST_ETH_PHYS, qdev_get_gpio_in(mst_irq, ETHERNET_IRQ)); - mainstone_binfo.kernel_filename = machine->kernel_filename; - mainstone_binfo.kernel_cmdline = machine->kernel_cmdline; - mainstone_binfo.initrd_filename = machine->initrd_filename; mainstone_binfo.board_id = arm_id; - arm_load_kernel(mpu->cpu, &mainstone_binfo); + arm_load_kernel(mpu->cpu, machine, &mainstone_binfo); } static void mainstone_init(MachineState *machine) diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c index 0276875f02..e90b393a44 100644 --- a/hw/arm/mcimx6ul-evk.c +++ b/hw/arm/mcimx6ul-evk.c @@ -40,9 +40,6 @@ static void mcimx6ul_evk_init(MachineState *machine) .loader_start = FSL_IMX6UL_MMDC_ADDR, .board_id = -1, .ram_size = machine->ram_size, - .kernel_filename = machine->kernel_filename, - .kernel_cmdline = machine->kernel_cmdline, - .initrd_filename = machine->initrd_filename, .nb_cpus = machine->smp.cpus, }; @@ -72,7 +69,7 @@ static void mcimx6ul_evk_init(MachineState *machine) } if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu, &boot_info); + arm_load_kernel(&s->soc.cpu, machine, &boot_info); } } diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c index 97b8bb788a..2df2223611 100644 --- a/hw/arm/mcimx7d-sabre.c +++ b/hw/arm/mcimx7d-sabre.c @@ -43,9 +43,6 @@ static void mcimx7d_sabre_init(MachineState *machine) .loader_start = FSL_IMX7_MMDC_ADDR, .board_id = -1, .ram_size = machine->ram_size, - .kernel_filename = machine->kernel_filename, - .kernel_cmdline = machine->kernel_cmdline, - .initrd_filename = machine->initrd_filename, .nb_cpus = machine->smp.cpus, }; @@ -75,7 +72,7 @@ static void mcimx7d_sabre_init(MachineState *machine) } if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu[0], &boot_info); + arm_load_kernel(&s->soc.cpu[0], machine, &boot_info); } } diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index 8ae4751d75..246cbb1336 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -1573,9 +1573,6 @@ static struct arm_boot_info musicpal_binfo = { static void musicpal_init(MachineState *machine) { - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; ARMCPU *cpu; qemu_irq pic[32]; DeviceState *dev; @@ -1704,10 +1701,7 @@ static void musicpal_init(MachineState *machine) sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]); musicpal_binfo.ram_size = MP_RAM_DEFAULT_SIZE; - musicpal_binfo.kernel_filename = kernel_filename; - musicpal_binfo.kernel_cmdline = kernel_cmdline; - musicpal_binfo.initrd_filename = initrd_filename; - arm_load_kernel(cpu, &musicpal_binfo); + arm_load_kernel(cpu, machine, &musicpal_binfo); } static void musicpal_machine_init(MachineClass *mc) diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c index a6c4085337..a36971d39a 100644 --- a/hw/arm/nseries.c +++ b/hw/arm/nseries.c @@ -1361,10 +1361,7 @@ static void n8x0_init(MachineState *machine, if (machine->kernel_filename) { /* Or at the linux loader. */ - binfo->kernel_filename = machine->kernel_filename; - binfo->kernel_cmdline = machine->kernel_cmdline; - binfo->initrd_filename = machine->initrd_filename; - arm_load_kernel(s->mpu->cpu, binfo); + arm_load_kernel(s->mpu->cpu, machine, binfo); qemu_register_reset(n8x0_boot_init, s); } diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c index 75a05c36b0..c071197be7 100644 --- a/hw/arm/omap_sx1.c +++ b/hw/arm/omap_sx1.c @@ -195,10 +195,7 @@ static void sx1_init(MachineState *machine, const int version) } /* Load the kernel. */ - sx1_binfo.kernel_filename = machine->kernel_filename; - sx1_binfo.kernel_cmdline = machine->kernel_cmdline; - sx1_binfo.initrd_filename = machine->initrd_filename; - arm_load_kernel(mpu->cpu, &sx1_binfo); + arm_load_kernel(mpu->cpu, machine, &sx1_binfo); /* TODO: fix next line */ //~ qemu_console_resize(ds, 640, 480); diff --git a/hw/arm/palm.c b/hw/arm/palm.c index bea47b917d..02a3a82b9b 100644 --- a/hw/arm/palm.c +++ b/hw/arm/palm.c @@ -187,9 +187,6 @@ static struct arm_boot_info palmte_binfo = { static void palmte_init(MachineState *machine) { - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; MemoryRegion *address_space_mem = get_system_memory(); struct omap_mpu_state_s *mpu; int flash_size = 0x00800000; @@ -249,16 +246,13 @@ static void palmte_init(MachineState *machine) } } - if (!rom_loaded && !kernel_filename && !qtest_enabled()) { + if (!rom_loaded && !machine->kernel_filename && !qtest_enabled()) { fprintf(stderr, "Kernel or ROM image must be specified\n"); exit(1); } /* Load the kernel. */ - palmte_binfo.kernel_filename = kernel_filename; - palmte_binfo.kernel_cmdline = kernel_cmdline; - palmte_binfo.initrd_filename = initrd_filename; - arm_load_kernel(mpu->cpu, &palmte_binfo); + arm_load_kernel(mpu->cpu, machine, &palmte_binfo); } static void palmte_machine_init(MachineClass *mc) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 5b2620acb4..74c062d05e 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -157,13 +157,9 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) binfo.entry = firmware_addr; binfo.firmware_loaded = true; - } else { - binfo.kernel_filename = machine->kernel_filename; - binfo.kernel_cmdline = machine->kernel_cmdline; - binfo.initrd_filename = machine->initrd_filename; } - arm_load_kernel(ARM_CPU(first_cpu), &binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo); } static void raspi_init(MachineState *machine, int version) diff --git a/hw/arm/realview.c b/hw/arm/realview.c index b108a9ab26..8fcdf75a2b 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -351,13 +351,10 @@ static void realview_init(MachineState *machine, memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack); realview_binfo.ram_size = ram_size; - realview_binfo.kernel_filename = machine->kernel_filename; - realview_binfo.kernel_cmdline = machine->kernel_cmdline; - realview_binfo.initrd_filename = machine->initrd_filename; realview_binfo.nb_cpus = smp_cpus; realview_binfo.board_id = realview_board_id[board_type]; realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0); - arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &realview_binfo); } static void realview_eb_init(MachineState *machine) diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c index a6185c169e..96cc455c5c 100644 --- a/hw/arm/sabrelite.c +++ b/hw/arm/sabrelite.c @@ -103,16 +103,13 @@ static void sabrelite_init(MachineState *machine) } sabrelite_binfo.ram_size = machine->ram_size; - sabrelite_binfo.kernel_filename = machine->kernel_filename; - sabrelite_binfo.kernel_cmdline = machine->kernel_cmdline; - sabrelite_binfo.initrd_filename = machine->initrd_filename; sabrelite_binfo.nb_cpus = machine->smp.cpus; sabrelite_binfo.secure_boot = true; sabrelite_binfo.write_secondary_boot = sabrelite_write_secondary; sabrelite_binfo.secondary_cpu_reset_hook = sabrelite_reset_secondary; if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu[0], &sabrelite_binfo); + arm_load_kernel(&s->soc.cpu[0], machine, &sabrelite_binfo); } } diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index e98e9a5170..1c1a2b662d 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -711,13 +711,12 @@ static void sbsa_ref_init(MachineState *machine) create_pcie(sms, pic); sms->bootinfo.ram_size = machine->ram_size; - sms->bootinfo.kernel_filename = machine->kernel_filename; sms->bootinfo.nb_cpus = smp_cpus; sms->bootinfo.board_id = -1; sms->bootinfo.loader_start = sbsa_ref_memmap[SBSA_MEM].base; sms->bootinfo.get_dtb = sbsa_ref_dtb; sms->bootinfo.firmware_loaded = firmware_loaded; - arm_load_kernel(ARM_CPU(first_cpu), &sms->bootinfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &sms->bootinfo); } static uint64_t sbsa_ref_cpu_mp_affinity(SBSAMachineState *sms, int idx) diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c index 59348123b5..25bd0f5d9d 100644 --- a/hw/arm/spitz.c +++ b/hw/arm/spitz.c @@ -954,11 +954,8 @@ static void spitz_common_init(MachineState *machine, /* A 4.0 GB microdrive is permanently sitting in CF slot 0. */ spitz_microdrive_attach(mpu, 0); - spitz_binfo.kernel_filename = machine->kernel_filename; - spitz_binfo.kernel_cmdline = machine->kernel_cmdline; - spitz_binfo.initrd_filename = machine->initrd_filename; spitz_binfo.board_id = arm_id; - arm_load_kernel(mpu->cpu, &spitz_binfo); + arm_load_kernel(mpu->cpu, machine, &spitz_binfo); sl_bootparam_write(SL_PXA_PARAM_BASE); } diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c index e9627e356e..4d95a1f3e2 100644 --- a/hw/arm/tosa.c +++ b/hw/arm/tosa.c @@ -218,9 +218,6 @@ static struct arm_boot_info tosa_binfo = { static void tosa_init(MachineState *machine) { - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *rom = g_new(MemoryRegion, 1); PXA2xxState *mpu; @@ -245,11 +242,8 @@ static void tosa_init(MachineState *machine) tosa_tg_init(mpu); - tosa_binfo.kernel_filename = kernel_filename; - tosa_binfo.kernel_cmdline = kernel_cmdline; - tosa_binfo.initrd_filename = initrd_filename; tosa_binfo.board_id = 0x208; - arm_load_kernel(mpu->cpu, &tosa_binfo); + arm_load_kernel(mpu->cpu, machine, &tosa_binfo); sl_bootparam_write(SL_PXA_PARAM_BASE); } diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index e25561705f..e86af01537 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -375,11 +375,8 @@ static void versatile_init(MachineState *machine, int board_id) } versatile_binfo.ram_size = machine->ram_size; - versatile_binfo.kernel_filename = machine->kernel_filename; - versatile_binfo.kernel_cmdline = machine->kernel_cmdline; - versatile_binfo.initrd_filename = machine->initrd_filename; versatile_binfo.board_id = board_id; - arm_load_kernel(cpu, &versatile_binfo); + arm_load_kernel(cpu, machine, &versatile_binfo); } static void vpb_init(MachineState *machine) diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 5d932c27c0..4673a88a8d 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -707,9 +707,6 @@ static void vexpress_common_init(MachineState *machine) } daughterboard->bootinfo.ram_size = machine->ram_size; - daughterboard->bootinfo.kernel_filename = machine->kernel_filename; - daughterboard->bootinfo.kernel_cmdline = machine->kernel_cmdline; - daughterboard->bootinfo.initrd_filename = machine->initrd_filename; daughterboard->bootinfo.nb_cpus = machine->smp.cpus; daughterboard->bootinfo.board_id = VEXPRESS_BOARD_ID; daughterboard->bootinfo.loader_start = daughterboard->loader_start; @@ -719,7 +716,7 @@ static void vexpress_common_init(MachineState *machine) daughterboard->bootinfo.modify_dtb = vexpress_modify_dtb; /* When booting Linux we should be in secure state if the CPU has one. */ daughterboard->bootinfo.secure_boot = vms->secure; - arm_load_kernel(ARM_CPU(first_cpu), &daughterboard->bootinfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &daughterboard->bootinfo); } static bool vexpress_get_secure(Object *obj, Error **errp) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 0d1629ccb3..3796aa70f8 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1368,6 +1368,7 @@ void virt_machine_done(Notifier *notifier, void *data) { VirtMachineState *vms = container_of(notifier, VirtMachineState, machine_done); + MachineState *ms = MACHINE(vms); ARMCPU *cpu = ARM_CPU(first_cpu); struct arm_boot_info *info = &vms->bootinfo; AddressSpace *as = arm_boot_address_space(cpu, info); @@ -1385,7 +1386,7 @@ void virt_machine_done(Notifier *notifier, void *data) vms->memmap[VIRT_PLATFORM_BUS].size, vms->irqmap[VIRT_PLATFORM_BUS]); } - if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) { + if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms) < 0) { exit(1); } @@ -1711,16 +1712,13 @@ static void machvirt_init(MachineState *machine) create_platform_bus(vms, pic); vms->bootinfo.ram_size = machine->ram_size; - vms->bootinfo.kernel_filename = machine->kernel_filename; - vms->bootinfo.kernel_cmdline = machine->kernel_cmdline; - vms->bootinfo.initrd_filename = machine->initrd_filename; vms->bootinfo.nb_cpus = smp_cpus; vms->bootinfo.board_id = -1; vms->bootinfo.loader_start = vms->memmap[VIRT_MEM].base; vms->bootinfo.get_dtb = machvirt_dtb; vms->bootinfo.skip_dtb_autoload = true; vms->bootinfo.firmware_loaded = firmware_loaded; - arm_load_kernel(ARM_CPU(first_cpu), &vms->bootinfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &vms->bootinfo); vms->machine_done.notify = virt_machine_done; qemu_add_machine_init_done_notifier(&vms->machine_done); diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index 89da34808b..c14774e542 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -158,9 +158,6 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq, static void zynq_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; ARMCPU *cpu; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ext_ram = g_new(MemoryRegion, 1); @@ -303,16 +300,13 @@ static void zynq_init(MachineState *machine) sysbus_mmio_map(busdev, 0, 0xF8007000); zynq_binfo.ram_size = ram_size; - zynq_binfo.kernel_filename = kernel_filename; - zynq_binfo.kernel_cmdline = kernel_cmdline; - zynq_binfo.initrd_filename = initrd_filename; zynq_binfo.nb_cpus = 1; zynq_binfo.board_id = 0xd32; zynq_binfo.loader_start = 0; zynq_binfo.board_setup_addr = BOARD_SETUP_ADDR; zynq_binfo.write_board_setup = zynq_write_board_setup; - arm_load_kernel(ARM_CPU(first_cpu), &zynq_binfo); + arm_load_kernel(ARM_CPU(first_cpu), machine, &zynq_binfo); } static void zynq_machine_init(MachineClass *mc) diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c index f95fde2309..462493c467 100644 --- a/hw/arm/xlnx-versal-virt.c +++ b/hw/arm/xlnx-versal-virt.c @@ -441,14 +441,11 @@ static void versal_virt_init(MachineState *machine) 0, &s->soc.fpd.apu.mr, 0); s->binfo.ram_size = machine->ram_size; - s->binfo.kernel_filename = machine->kernel_filename; - s->binfo.kernel_cmdline = machine->kernel_cmdline; - s->binfo.initrd_filename = machine->initrd_filename; s->binfo.loader_start = 0x0; s->binfo.get_dtb = versal_virt_get_dtb; s->binfo.modify_dtb = versal_virt_modify_dtb; if (machine->kernel_filename) { - arm_load_kernel(s->soc.fpd.apu.cpu[0], &s->binfo); + arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo); } else { AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0], &s->binfo); @@ -457,7 +454,7 @@ static void versal_virt_init(MachineState *machine) s->binfo.loader_start = 0x1000; s->binfo.dtb_limit = 0x1000000; if (arm_load_dtb(s->binfo.loader_start, - &s->binfo, s->binfo.dtb_limit, as) < 0) { + &s->binfo, s->binfo.dtb_limit, as, machine) < 0) { exit(EXIT_FAILURE); } } diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c index 044d3394c0..53cfe7c1f1 100644 --- a/hw/arm/xlnx-zcu102.c +++ b/hw/arm/xlnx-zcu102.c @@ -171,11 +171,8 @@ static void xlnx_zcu102_init(MachineState *machine) /* TODO create and connect IDE devices for ide_drive_get() */ xlnx_zcu102_binfo.ram_size = ram_size; - xlnx_zcu102_binfo.kernel_filename = machine->kernel_filename; - xlnx_zcu102_binfo.kernel_cmdline = machine->kernel_cmdline; - xlnx_zcu102_binfo.initrd_filename = machine->initrd_filename; xlnx_zcu102_binfo.loader_start = 0; - arm_load_kernel(s->soc.boot_cpu_ptr, &xlnx_zcu102_binfo); + arm_load_kernel(s->soc.boot_cpu_ptr, machine, &xlnx_zcu102_binfo); } static void xlnx_zcu102_machine_instance_init(Object *obj) diff --git a/hw/arm/z2.c b/hw/arm/z2.c index 3923b87e4c..34794fe3ae 100644 --- a/hw/arm/z2.c +++ b/hw/arm/z2.c @@ -296,9 +296,6 @@ static const TypeInfo aer915_info = { static void z2_init(MachineState *machine) { - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; MemoryRegion *address_space_mem = get_system_memory(); uint32_t sector_len = 0x10000; PXA2xxState *mpu; @@ -352,11 +349,8 @@ static void z2_init(MachineState *machine) qdev_connect_gpio_out(mpu->gpio, Z2_GPIO_LCD_CS, qemu_allocate_irq(z2_lcd_cs, z2_lcd, 0)); - z2_binfo.kernel_filename = kernel_filename; - z2_binfo.kernel_cmdline = kernel_cmdline; - z2_binfo.initrd_filename = initrd_filename; z2_binfo.board_id = 0x6dd; - arm_load_kernel(mpu->cpu, &z2_binfo); + arm_load_kernel(mpu->cpu, machine, &z2_binfo); } static void z2_machine_init(MachineClass *mc) diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index 5714dea1a2..7f4d0ca7cd 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -131,7 +131,7 @@ struct arm_boot_info { * before sysbus-fdt arm_register_platform_bus_fdt_creator. Indeed the * machine init done notifiers are called in registration reverse order. */ -void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info); +void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info); AddressSpace *arm_boot_address_space(ARMCPU *cpu, const struct arm_boot_info *info); @@ -158,7 +158,7 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu, * Note: Must not be called unless have_dtb(binfo) is true. */ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, - hwaddr addr_limit, AddressSpace *as); + hwaddr addr_limit, AddressSpace *as, MachineState *ms); /* Write a secure board setup routine with a dummy handler for SMCs */ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu, From aa57020774b690a22be72453b8e91c9b5a68c516 Mon Sep 17 00:00:00 2001 From: Tao Xu Date: Fri, 9 Aug 2019 14:57:22 +0800 Subject: [PATCH 03/13] numa: move numa global variable nb_numa_nodes into MachineState Add struct NumaState in MachineState and move existing numa global nb_numa_nodes(renamed as "num_nodes") into NumaState. And add variable numa_support into MachineClass to decide which submachines support NUMA. Reviewed-by: Igor Mammedov Suggested-by: Igor Mammedov Suggested-by: Eduardo Habkost Signed-off-by: Tao Xu Message-Id: <20190809065731.9097-3-tao3.xu@intel.com> [ehabkost: include hw/boards.h again to fix build failures] Signed-off-by: Eduardo Habkost --- exec.c | 5 ++- hw/acpi/aml-build.c | 4 +- hw/arm/boot.c | 4 +- hw/arm/sbsa-ref.c | 4 +- hw/arm/virt-acpi-build.c | 10 +++-- hw/arm/virt.c | 4 +- hw/core/machine-hmp-cmds.c | 13 +++++-- hw/core/machine.c | 14 +++++-- hw/core/numa.c | 60 +++++++++++++++++------------ hw/i386/acpi-build.c | 2 +- hw/i386/pc.c | 9 +++-- hw/mem/pc-dimm.c | 2 + hw/pci-bridge/pci_expander_bridge.c | 9 ++++- hw/ppc/spapr.c | 19 ++++----- include/hw/acpi/aml-build.h | 2 +- include/hw/boards.h | 1 + include/sysemu/numa.h | 10 ++++- 17 files changed, 113 insertions(+), 59 deletions(-) diff --git a/exec.c b/exec.c index 1df966d17a..e813058b05 100644 --- a/exec.c +++ b/exec.c @@ -1750,6 +1750,7 @@ long qemu_minrampagesize(void) long hpsize = LONG_MAX; long mainrampagesize; Object *memdev_root; + MachineState *ms = MACHINE(qdev_get_machine()); mainrampagesize = qemu_mempath_getpagesize(mem_path); @@ -1777,7 +1778,9 @@ long qemu_minrampagesize(void) * so if its page size is smaller we have got to report that size instead. */ if (hpsize > mainrampagesize && - (nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL)) { + (ms->numa_state == NULL || + ms->numa_state->num_nodes == 0 || + numa_info[0].node_memdev == NULL)) { static bool warned; if (!warned) { error_report("Huge page support disabled (n/a for main memory)."); diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 555c24f21d..043b47694c 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -25,6 +25,7 @@ #include "qemu/bswap.h" #include "qemu/bitops.h" #include "sysemu/numa.h" +#include "hw/boards.h" static GArray *build_alloc_array(void) { @@ -1726,10 +1727,11 @@ void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base, * ACPI spec 5.2.17 System Locality Distance Information Table * (Revision 2.0 or later) */ -void build_slit(GArray *table_data, BIOSLinker *linker) +void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms) { int slit_start, i, j; slit_start = table_data->len; + int nb_numa_nodes = ms->numa_state->num_nodes; acpi_data_push(table_data, sizeof(AcpiTableHeader)); diff --git a/hw/arm/boot.c b/hw/arm/boot.c index b46eaefa2d..d3e88626c4 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -598,9 +598,9 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, } g_strfreev(node_path); - if (nb_numa_nodes > 0) { + if (ms->numa_state != NULL && ms->numa_state->num_nodes > 0) { mem_base = binfo->loader_start; - for (i = 0; i < nb_numa_nodes; i++) { + for (i = 0; i < ms->numa_state->num_nodes; i++) { mem_len = numa_info[i].node_mem; rc = fdt_add_memory_node(fdt, acells, mem_base, scells, mem_len, i); diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 1c1a2b662d..d15e5aebbd 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -146,6 +146,7 @@ static void create_fdt(SBSAMachineState *sms) { void *fdt = create_device_tree(&sms->fdt_size); const MachineState *ms = MACHINE(sms); + int nb_numa_nodes = ms->numa_state->num_nodes; int cpu; if (!fdt) { @@ -762,7 +763,7 @@ sbsa_ref_cpu_index_to_props(MachineState *ms, unsigned cpu_index) static int64_t sbsa_ref_get_default_cpu_node_id(const MachineState *ms, int idx) { - return idx % nb_numa_nodes; + return idx % ms->numa_state->num_nodes; } static void sbsa_ref_instance_init(Object *obj) @@ -789,6 +790,7 @@ static void sbsa_ref_class_init(ObjectClass *oc, void *data) mc->possible_cpu_arch_ids = sbsa_ref_possible_cpu_arch_ids; mc->cpu_index_to_instance_props = sbsa_ref_cpu_index_to_props; mc->get_default_cpu_node_id = sbsa_ref_get_default_cpu_node_id; + mc->numa_mem_supported = true; } static const TypeInfo sbsa_ref_info = { diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index a8b2d97fe9..9e6cfe65b5 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -517,7 +517,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) int i, srat_start; uint64_t mem_base; MachineClass *mc = MACHINE_GET_CLASS(vms); - const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(MACHINE(vms)); + MachineState *ms = MACHINE(vms); + const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(ms); srat_start = table_data->len; srat = acpi_data_push(table_data, sizeof(*srat)); @@ -533,7 +534,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) } mem_base = vms->memmap[VIRT_MEM].base; - for (i = 0; i < nb_numa_nodes; ++i) { + for (i = 0; i < ms->numa_state->num_nodes; ++i) { if (numa_info[i].node_mem > 0) { numamem = acpi_data_push(table_data, sizeof(*numamem)); build_srat_memory(numamem, mem_base, numa_info[i].node_mem, i, @@ -759,6 +760,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) GArray *table_offsets; unsigned dsdt, xsdt; GArray *tables_blob = tables->table_data; + MachineState *ms = MACHINE(vms); table_offsets = g_array_new(false, true /* clear */, sizeof(uint32_t)); @@ -793,12 +795,12 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_spcr(tables_blob, tables->linker, vms); - if (nb_numa_nodes > 0) { + if (ms->numa_state->num_nodes > 0) { acpi_add_table(table_offsets, tables_blob); build_srat(tables_blob, tables->linker, vms); if (have_numa_distance) { acpi_add_table(table_offsets, tables_blob); - build_slit(tables_blob, tables->linker); + build_slit(tables_blob, tables->linker, ms); } } diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 3796aa70f8..8d36b37f8e 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -203,6 +203,8 @@ static bool cpu_type_valid(const char *cpu) static void create_fdt(VirtMachineState *vms) { + MachineState *ms = MACHINE(vms); + int nb_numa_nodes = ms->numa_state->num_nodes; void *fdt = create_device_tree(&vms->fdt_size); if (!fdt) { @@ -1846,7 +1848,7 @@ virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index) static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx) { - return idx % nb_numa_nodes; + return idx % ms->numa_state->num_nodes; } static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c index 1f66bda346..cd970cc4c5 100644 --- a/hw/core/machine-hmp-cmds.c +++ b/hw/core/machine-hmp-cmds.c @@ -23,6 +23,7 @@ #include "qapi/string-output-visitor.h" #include "qemu/error-report.h" #include "sysemu/numa.h" +#include "hw/boards.h" void hmp_info_cpus(Monitor *mon, const QDict *qdict) { @@ -139,15 +140,21 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) void hmp_info_numa(Monitor *mon, const QDict *qdict) { - int i; + int i, nb_numa_nodes; NumaNodeMem *node_mem; CpuInfoList *cpu_list, *cpu; + MachineState *ms = MACHINE(qdev_get_machine()); + + nb_numa_nodes = ms->numa_state ? ms->numa_state->num_nodes : 0; + monitor_printf(mon, "%d nodes\n", nb_numa_nodes); + if (!nb_numa_nodes) { + return; + } cpu_list = qmp_query_cpus(&error_abort); node_mem = g_new0(NumaNodeMem, nb_numa_nodes); - query_numa_node_mem(node_mem); - monitor_printf(mon, "%d nodes\n", nb_numa_nodes); + query_numa_node_mem(node_mem, ms); for (i = 0; i < nb_numa_nodes; i++) { monitor_printf(mon, "node %d cpus:", i); for (cpu = cpu_list; cpu; cpu = cpu->next) { diff --git a/hw/core/machine.c b/hw/core/machine.c index 83cd1bfeec..c5e0d52fbc 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -956,6 +956,9 @@ static void machine_initfn(Object *obj) NULL); } + if (mc->numa_mem_supported) { + ms->numa_state = g_new0(NumaState, 1); + } /* Register notifier when init is done for sysbus sanity checks */ ms->sysbus_notifier.notify = machine_init_notify; @@ -976,6 +979,7 @@ static void machine_finalize(Object *obj) g_free(ms->firmware); g_free(ms->device_memory); g_free(ms->nvdimms_state); + g_free(ms->numa_state); } bool machine_usb(MachineState *machine) @@ -1050,7 +1054,7 @@ static void machine_numa_finish_cpu_init(MachineState *machine) MachineClass *mc = MACHINE_GET_CLASS(machine); const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(machine); - assert(nb_numa_nodes); + assert(machine->numa_state->num_nodes); for (i = 0; i < possible_cpus->len; i++) { if (possible_cpus->cpus[i].props.has_node_id) { break; @@ -1096,9 +1100,11 @@ void machine_run_board_init(MachineState *machine) { MachineClass *machine_class = MACHINE_GET_CLASS(machine); - numa_complete_configuration(machine); - if (nb_numa_nodes) { - machine_numa_finish_cpu_init(machine); + if (machine_class->numa_mem_supported) { + numa_complete_configuration(machine); + if (machine->numa_state->num_nodes) { + machine_numa_finish_cpu_init(machine); + } } /* If the machine supports the valid_cpu_types check and the user diff --git a/hw/core/numa.c b/hw/core/numa.c index 4f7e4628a0..2712c78adb 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -55,7 +55,6 @@ static int have_mem; static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one. * For all nodes, nodeid < max_numa_nodeid */ -int nb_numa_nodes; bool have_numa_distance; NodeInfo numa_info[MAX_NODES]; @@ -72,7 +71,7 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, if (node->has_nodeid) { nodenr = node->nodeid; } else { - nodenr = nb_numa_nodes; + nodenr = ms->numa_state->num_nodes; } if (nodenr >= MAX_NODES) { @@ -138,10 +137,11 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, } numa_info[nodenr].present = true; max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1); - nb_numa_nodes++; + ms->numa_state->num_nodes++; } -static void parse_numa_distance(NumaDistOptions *dist, Error **errp) +static +void parse_numa_distance(MachineState *ms, NumaDistOptions *dist, Error **errp) { uint16_t src = dist->src; uint16_t dst = dist->dst; @@ -179,6 +179,12 @@ static void parse_numa_distance(NumaDistOptions *dist, Error **errp) void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp) { Error *err = NULL; + MachineClass *mc = MACHINE_GET_CLASS(ms); + + if (!mc->numa_mem_supported) { + error_setg(errp, "NUMA is not supported by this machine-type"); + goto end; + } switch (object->type) { case NUMA_OPTIONS_TYPE_NODE: @@ -188,7 +194,7 @@ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp) } break; case NUMA_OPTIONS_TYPE_DIST: - parse_numa_distance(&object->u.dist, &err); + parse_numa_distance(ms, &object->u.dist, &err); if (err) { goto end; } @@ -253,10 +259,11 @@ end: * distance from a node to itself is always NUMA_DISTANCE_MIN, * so providing it is never necessary. */ -static void validate_numa_distance(void) +static void validate_numa_distance(MachineState *ms) { int src, dst; bool is_asymmetrical = false; + int nb_numa_nodes = ms->numa_state->num_nodes; for (src = 0; src < nb_numa_nodes; src++) { for (dst = src; dst < nb_numa_nodes; dst++) { @@ -294,7 +301,7 @@ static void validate_numa_distance(void) } } -static void complete_init_numa_distance(void) +static void complete_init_numa_distance(MachineState *ms) { int src, dst; @@ -303,8 +310,8 @@ static void complete_init_numa_distance(void) * there would not be any missing distance except local node, which * is verified by validate_numa_distance above. */ - for (src = 0; src < nb_numa_nodes; src++) { - for (dst = 0; dst < nb_numa_nodes; dst++) { + for (src = 0; src < ms->numa_state->num_nodes; src++) { + for (dst = 0; dst < ms->numa_state->num_nodes; dst++) { if (numa_info[src].distance[dst] == 0) { if (src == dst) { numa_info[src].distance[dst] = NUMA_DISTANCE_MIN; @@ -370,7 +377,7 @@ void numa_complete_configuration(MachineState *ms) * * Enable NUMA implicitly by adding a new NUMA node automatically. */ - if (ms->ram_slots > 0 && nb_numa_nodes == 0 && + if (ms->ram_slots > 0 && ms->numa_state->num_nodes == 0 && mc->auto_enable_numa_with_memhp) { NumaNodeOptions node = { }; parse_numa_node(ms, &node, &error_abort); @@ -388,26 +395,27 @@ void numa_complete_configuration(MachineState *ms) } /* This must be always true if all nodes are present: */ - assert(nb_numa_nodes == max_numa_nodeid); + assert(ms->numa_state->num_nodes == max_numa_nodeid); - if (nb_numa_nodes > 0) { + if (ms->numa_state->num_nodes > 0) { uint64_t numa_total; - if (nb_numa_nodes > MAX_NODES) { - nb_numa_nodes = MAX_NODES; + if (ms->numa_state->num_nodes > MAX_NODES) { + ms->numa_state->num_nodes = MAX_NODES; } /* If no memory size is given for any node, assume the default case * and distribute the available memory equally across all nodes */ - for (i = 0; i < nb_numa_nodes; i++) { + for (i = 0; i < ms->numa_state->num_nodes; i++) { if (numa_info[i].node_mem != 0) { break; } } - if (i == nb_numa_nodes) { + if (i == ms->numa_state->num_nodes) { assert(mc->numa_auto_assign_ram); - mc->numa_auto_assign_ram(mc, numa_info, nb_numa_nodes, ram_size); + mc->numa_auto_assign_ram(mc, numa_info, + ms->numa_state->num_nodes, ram_size); if (!qtest_enabled()) { warn_report("Default splitting of RAM between nodes is deprecated," " Use '-numa node,memdev' to explictly define RAM" @@ -416,7 +424,7 @@ void numa_complete_configuration(MachineState *ms) } numa_total = 0; - for (i = 0; i < nb_numa_nodes; i++) { + for (i = 0; i < ms->numa_state->num_nodes; i++) { numa_total += numa_info[i].node_mem; } if (numa_total != ram_size) { @@ -440,10 +448,10 @@ void numa_complete_configuration(MachineState *ms) */ if (have_numa_distance) { /* Validate enough NUMA distance information was provided. */ - validate_numa_distance(); + validate_numa_distance(ms); /* Validation succeeded, now fill in any missing distances. */ - complete_init_numa_distance(); + complete_init_numa_distance(ms); } } } @@ -510,14 +518,16 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, { uint64_t addr = 0; int i; + MachineState *ms = MACHINE(qdev_get_machine()); - if (nb_numa_nodes == 0 || !have_memdevs) { + if (ms->numa_state == NULL || + ms->numa_state->num_nodes == 0 || !have_memdevs) { allocate_system_memory_nonnuma(mr, owner, name, ram_size); return; } memory_region_init(mr, owner, name, ram_size); - for (i = 0; i < nb_numa_nodes; i++) { + for (i = 0; i < ms->numa_state->num_nodes; i++) { uint64_t size = numa_info[i].node_mem; HostMemoryBackend *backend = numa_info[i].node_memdev; if (!backend) { @@ -575,16 +585,16 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[]) qapi_free_MemoryDeviceInfoList(info_list); } -void query_numa_node_mem(NumaNodeMem node_mem[]) +void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms) { int i; - if (nb_numa_nodes <= 0) { + if (ms->numa_state == NULL || ms->numa_state->num_nodes <= 0) { return; } numa_stat_memory_devices(node_mem); - for (i = 0; i < nb_numa_nodes; i++) { + for (i = 0; i < ms->numa_state->num_nodes; i++) { node_mem[i].node_mem += numa_info[i].node_mem; } } diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 034e413fd0..3c5868322b 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2696,7 +2696,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) build_srat(tables_blob, tables->linker, machine); if (have_numa_distance) { acpi_add_table(table_offsets, tables_blob); - build_slit(tables_blob, tables->linker); + build_slit(tables_blob, tables->linker, machine); } } if (acpi_get_mcfg(&mcfg)) { diff --git a/hw/i386/pc.c b/hw/i386/pc.c index c14ed86439..5fba29c10b 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1002,6 +1002,8 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms) int i; const CPUArchIdList *cpus; MachineClass *mc = MACHINE_GET_CLASS(pcms); + MachineState *ms = MACHINE(pcms); + int nb_numa_nodes = ms->numa_state->num_nodes; fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as); fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus); @@ -1774,12 +1776,13 @@ void pc_machine_done(Notifier *notifier, void *data) void pc_guest_info_init(PCMachineState *pcms) { int i; + MachineState *ms = MACHINE(pcms); pcms->apic_xrupt_override = kvm_allows_irq0_override(); - pcms->numa_nodes = nb_numa_nodes; + pcms->numa_nodes = ms->numa_state->num_nodes; pcms->node_mem = g_malloc0(pcms->numa_nodes * sizeof *pcms->node_mem); - for (i = 0; i < nb_numa_nodes; i++) { + for (i = 0; i < ms->numa_state->num_nodes; i++) { pcms->node_mem[i] = numa_info[i].node_mem; } @@ -2869,7 +2872,7 @@ static int64_t pc_get_default_cpu_node_id(const MachineState *ms, int idx) x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, pcms->smp_dies, ms->smp.cores, ms->smp.threads, &topo); - return topo.pkg_id % nb_numa_nodes; + return topo.pkg_id % ms->numa_state->num_nodes; } static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms) diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 7c324a1329..99e2faf01b 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -172,6 +172,8 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp) { PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); + MachineState *ms = MACHINE(qdev_get_machine()); + int nb_numa_nodes = ms->numa_state->num_nodes; if (!dimm->hostmem) { error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set"); diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index 06a7c018d7..0592818447 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -21,6 +21,7 @@ #include "qemu/error-report.h" #include "qemu/module.h" #include "sysemu/numa.h" +#include "hw/boards.h" #define TYPE_PXB_BUS "pxb-bus" #define PXB_BUS(obj) OBJECT_CHECK(PXBBus, (obj), TYPE_PXB_BUS) @@ -213,9 +214,15 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp) PCIBus *bus; const char *dev_name = NULL; Error *local_err = NULL; + MachineState *ms = MACHINE(qdev_get_machine()); + + if (ms->numa_state == NULL) { + error_setg(errp, "NUMA is not supported by this machine-type"); + return; + } if (pxb->numa_node != NUMA_NODE_UNASSIGNED && - pxb->numa_node >= nb_numa_nodes) { + pxb->numa_node >= ms->numa_state->num_nodes) { error_setg(errp, "Illegal numa node %d", pxb->numa_node); return; } diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index baedadf20b..a7eb87feb6 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -336,7 +336,7 @@ static int spapr_fixup_cpu_dt(void *fdt, SpaprMachineState *spapr) return ret; } - if (nb_numa_nodes > 1) { + if (ms->numa_state->num_nodes > 1) { ret = spapr_fixup_cpu_numa_dt(fdt, offset, cpu); if (ret < 0) { return ret; @@ -356,9 +356,9 @@ static int spapr_fixup_cpu_dt(void *fdt, SpaprMachineState *spapr) static hwaddr spapr_node0_size(MachineState *machine) { - if (nb_numa_nodes) { + if (machine->numa_state->num_nodes) { int i; - for (i = 0; i < nb_numa_nodes; ++i) { + for (i = 0; i < machine->numa_state->num_nodes; ++i) { if (numa_info[i].node_mem) { return MIN(pow2floor(numa_info[i].node_mem), machine->ram_size); @@ -403,12 +403,12 @@ static int spapr_populate_memory(SpaprMachineState *spapr, void *fdt) { MachineState *machine = MACHINE(spapr); hwaddr mem_start, node_size; - int i, nb_nodes = nb_numa_nodes; + int i, nb_nodes = machine->numa_state->num_nodes; NodeInfo *nodes = numa_info; NodeInfo ramnode; /* No NUMA nodes, assume there is just one node with whole RAM */ - if (!nb_numa_nodes) { + if (!nb_nodes) { nb_nodes = 1; ramnode.node_mem = machine->ram_size; nodes = &ramnode; @@ -559,7 +559,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, _FDT((fdt_setprop(fdt, offset, "ibm,pft-size", pft_size_prop, sizeof(pft_size_prop)))); - if (nb_numa_nodes > 1) { + if (ms->numa_state->num_nodes > 1) { _FDT(spapr_fixup_cpu_numa_dt(fdt, offset, cpu)); } @@ -866,6 +866,7 @@ static int spapr_populate_drmem_v1(SpaprMachineState *spapr, void *fdt, static int spapr_populate_drconf_memory(SpaprMachineState *spapr, void *fdt) { MachineState *machine = MACHINE(spapr); + int nb_numa_nodes = machine->numa_state->num_nodes; int ret, i, offset; uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; uint32_t prop_lmb_size[] = {0, cpu_to_be32(lmb_size)}; @@ -1741,7 +1742,7 @@ static void spapr_machine_reset(MachineState *machine) * The final value of spapr->gpu_numa_id is going to be written to * max-associativity-domains in spapr_build_fdt(). */ - spapr->gpu_numa_id = MAX(1, nb_numa_nodes); + spapr->gpu_numa_id = MAX(1, machine->numa_state->num_nodes); qemu_devices_reset(); /* @@ -2539,7 +2540,7 @@ static void spapr_validate_node_memory(MachineState *machine, Error **errp) return; } - for (i = 0; i < nb_numa_nodes; i++) { + for (i = 0; i < machine->numa_state->num_nodes; i++) { if (numa_info[i].node_mem % SPAPR_MEMORY_BLOCK_SIZE) { error_setg(errp, "Node %d memory size 0x%" PRIx64 @@ -4178,7 +4179,7 @@ spapr_cpu_index_to_props(MachineState *machine, unsigned cpu_index) static int64_t spapr_get_default_cpu_node_id(const MachineState *ms, int idx) { - return idx / ms->smp.cores % nb_numa_nodes; + return idx / ms->smp.cores % ms->numa_state->num_nodes; } static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine) diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 1a563ad756..991cf05134 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -414,7 +414,7 @@ build_append_gas_from_struct(GArray *table, const struct AcpiGenericAddress *s) void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base, uint64_t len, int node, MemoryAffinityFlags flags); -void build_slit(GArray *table_data, BIOSLinker *linker); +void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms); void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f, const char *oem_id, const char *oem_table_id); diff --git a/include/hw/boards.h b/include/hw/boards.h index ced86109ec..2289536e48 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -299,6 +299,7 @@ struct MachineState { CPUArchIdList *possible_cpus; CpuTopology smp; struct NVDIMMState *nvdimms_state; + struct NumaState *numa_state; }; #define DEFINE_MACHINE(namestr, machine_initfn) \ diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h index 7a4ce89765..1786e861d0 100644 --- a/include/sysemu/numa.h +++ b/include/sysemu/numa.h @@ -14,7 +14,6 @@ struct CPUArchId; #define NUMA_DISTANCE_MAX 254 #define NUMA_DISTANCE_UNREACHABLE 255 -extern int nb_numa_nodes; /* Number of NUMA nodes */ extern bool have_numa_distance; struct NodeInfo { @@ -31,10 +30,17 @@ struct NumaNodeMem { extern NodeInfo numa_info[MAX_NODES]; +struct NumaState { + /* Number of NUMA nodes */ + int num_nodes; + +}; +typedef struct NumaState NumaState; + void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp); void parse_numa_opts(MachineState *ms); void numa_complete_configuration(MachineState *ms); -void query_numa_node_mem(NumaNodeMem node_mem[]); +void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms); extern QemuOptsList qemu_numa_opts; void numa_legacy_auto_assign_ram(MachineClass *mc, NodeInfo *nodes, int nb_nodes, ram_addr_t size); From 118154b7674b85827f272332efe86fc58cb76249 Mon Sep 17 00:00:00 2001 From: Tao Xu Date: Fri, 9 Aug 2019 14:57:23 +0800 Subject: [PATCH 04/13] numa: move numa global variable have_numa_distance into MachineState Move existing numa global have_numa_distance into NumaState. Reviewed-by: Igor Mammedov Reviewed-by: Liu Jingqi Suggested-by: Igor Mammedov Suggested-by: Eduardo Habkost Signed-off-by: Tao Xu Message-Id: <20190809065731.9097-4-tao3.xu@intel.com> Signed-off-by: Eduardo Habkost --- hw/arm/sbsa-ref.c | 2 +- hw/arm/virt-acpi-build.c | 2 +- hw/arm/virt.c | 2 +- hw/core/numa.c | 5 ++--- hw/i386/acpi-build.c | 2 +- include/sysemu/numa.h | 4 ++-- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index d15e5aebbd..7d7bb9fd96 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -160,7 +160,7 @@ static void create_fdt(SBSAMachineState *sms) qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2); qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2); - if (have_numa_distance) { + if (ms->numa_state->have_numa_distance) { int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t); uint32_t *matrix = g_malloc0(size); int idx, i, j; diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 9e6cfe65b5..b1deb76a53 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -798,7 +798,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) if (ms->numa_state->num_nodes > 0) { acpi_add_table(table_offsets, tables_blob); build_srat(tables_blob, tables->linker, vms); - if (have_numa_distance) { + if (ms->numa_state->have_numa_distance) { acpi_add_table(table_offsets, tables_blob); build_slit(tables_blob, tables->linker, ms); } diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 8d36b37f8e..414f7ecd02 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -236,7 +236,7 @@ static void create_fdt(VirtMachineState *vms) "clk24mhz"); qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", vms->clock_phandle); - if (have_numa_distance) { + if (nb_numa_nodes > 0 && ms->numa_state->have_numa_distance) { int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t); uint32_t *matrix = g_malloc0(size); int idx, i, j; diff --git a/hw/core/numa.c b/hw/core/numa.c index 2712c78adb..4a7adc9b98 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -55,7 +55,6 @@ static int have_mem; static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one. * For all nodes, nodeid < max_numa_nodeid */ -bool have_numa_distance; NodeInfo numa_info[MAX_NODES]; @@ -173,7 +172,7 @@ void parse_numa_distance(MachineState *ms, NumaDistOptions *dist, Error **errp) } numa_info[src].distance[dst] = val; - have_numa_distance = true; + ms->numa_state->have_numa_distance = true; } void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp) @@ -446,7 +445,7 @@ void numa_complete_configuration(MachineState *ms) * asymmetric. In this case, the distances for both directions * of all node pairs are required. */ - if (have_numa_distance) { + if (ms->numa_state->have_numa_distance) { /* Validate enough NUMA distance information was provided. */ validate_numa_distance(ms); diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 3c5868322b..e54e571a75 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2694,7 +2694,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) if (pcms->numa_nodes) { acpi_add_table(table_offsets, tables_blob); build_srat(tables_blob, tables->linker, machine); - if (have_numa_distance) { + if (machine->numa_state->have_numa_distance) { acpi_add_table(table_offsets, tables_blob); build_slit(tables_blob, tables->linker, machine); } diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h index 1786e861d0..bfe04b514c 100644 --- a/include/sysemu/numa.h +++ b/include/sysemu/numa.h @@ -14,8 +14,6 @@ struct CPUArchId; #define NUMA_DISTANCE_MAX 254 #define NUMA_DISTANCE_UNREACHABLE 255 -extern bool have_numa_distance; - struct NodeInfo { uint64_t node_mem; struct HostMemoryBackend *node_memdev; @@ -34,6 +32,8 @@ struct NumaState { /* Number of NUMA nodes */ int num_nodes; + /* Allow setting NUMA distance for different NUMA nodes */ + bool have_numa_distance; }; typedef struct NumaState NumaState; From 7e721e7b10e166003d4fdcfab90a72c93d4df839 Mon Sep 17 00:00:00 2001 From: Tao Xu Date: Fri, 9 Aug 2019 14:57:24 +0800 Subject: [PATCH 05/13] numa: move numa global variable numa_info into MachineState Move existing numa global numa_info (renamed as "nodes") into NumaState. Reviewed-by: Igor Mammedov Suggested-by: Igor Mammedov Suggested-by: Eduardo Habkost Signed-off-by: Tao Xu Message-Id: <20190809065731.9097-5-tao3.xu@intel.com> Signed-off-by: Eduardo Habkost --- exec.c | 2 +- hw/acpi/aml-build.c | 6 ++++-- hw/arm/boot.c | 2 +- hw/arm/sbsa-ref.c | 3 ++- hw/arm/virt-acpi-build.c | 7 ++++--- hw/arm/virt.c | 3 ++- hw/core/numa.c | 15 +++++++++------ hw/i386/pc.c | 4 ++-- hw/ppc/spapr.c | 10 +++++----- hw/ppc/spapr_pci.c | 4 +++- include/sysemu/numa.h | 5 +++-- 11 files changed, 36 insertions(+), 25 deletions(-) diff --git a/exec.c b/exec.c index e813058b05..0d47788f5f 100644 --- a/exec.c +++ b/exec.c @@ -1780,7 +1780,7 @@ long qemu_minrampagesize(void) if (hpsize > mainrampagesize && (ms->numa_state == NULL || ms->numa_state->num_nodes == 0 || - numa_info[0].node_memdev == NULL)) { + ms->numa_state->nodes[0].node_memdev == NULL)) { static bool warned; if (!warned) { error_report("Huge page support disabled (n/a for main memory)."); diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 043b47694c..78aee1a2f9 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -1738,8 +1738,10 @@ void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms) build_append_int_noprefix(table_data, nb_numa_nodes, 8); for (i = 0; i < nb_numa_nodes; i++) { for (j = 0; j < nb_numa_nodes; j++) { - assert(numa_info[i].distance[j]); - build_append_int_noprefix(table_data, numa_info[i].distance[j], 1); + assert(ms->numa_state->nodes[i].distance[j]); + build_append_int_noprefix(table_data, + ms->numa_state->nodes[i].distance[j], + 1); } } diff --git a/hw/arm/boot.c b/hw/arm/boot.c index d3e88626c4..bf97ef3e33 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -601,7 +601,7 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, if (ms->numa_state != NULL && ms->numa_state->num_nodes > 0) { mem_base = binfo->loader_start; for (i = 0; i < ms->numa_state->num_nodes; i++) { - mem_len = numa_info[i].node_mem; + mem_len = ms->numa_state->nodes[i].node_mem; rc = fdt_add_memory_node(fdt, acells, mem_base, scells, mem_len, i); if (rc < 0) { diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 7d7bb9fd96..27046cc284 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -170,7 +170,8 @@ static void create_fdt(SBSAMachineState *sms) idx = (i * nb_numa_nodes + j) * 3; matrix[idx + 0] = cpu_to_be32(i); matrix[idx + 1] = cpu_to_be32(j); - matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]); + matrix[idx + 2] = + cpu_to_be32(ms->numa_state->nodes[i].distance[j]); } } diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index b1deb76a53..6cdf156cf5 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -535,11 +535,12 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) mem_base = vms->memmap[VIRT_MEM].base; for (i = 0; i < ms->numa_state->num_nodes; ++i) { - if (numa_info[i].node_mem > 0) { + if (ms->numa_state->nodes[i].node_mem > 0) { numamem = acpi_data_push(table_data, sizeof(*numamem)); - build_srat_memory(numamem, mem_base, numa_info[i].node_mem, i, + build_srat_memory(numamem, mem_base, + ms->numa_state->nodes[i].node_mem, i, MEM_AFFINITY_ENABLED); - mem_base += numa_info[i].node_mem; + mem_base += ms->numa_state->nodes[i].node_mem; } } diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 414f7ecd02..d74538b021 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -246,7 +246,8 @@ static void create_fdt(VirtMachineState *vms) idx = (i * nb_numa_nodes + j) * 3; matrix[idx + 0] = cpu_to_be32(i); matrix[idx + 1] = cpu_to_be32(j); - matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]); + matrix[idx + 2] = + cpu_to_be32(ms->numa_state->nodes[i].distance[j]); } } diff --git a/hw/core/numa.c b/hw/core/numa.c index 4a7adc9b98..4dfec5c95b 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -55,8 +55,6 @@ static int have_mem; static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one. * For all nodes, nodeid < max_numa_nodeid */ -NodeInfo numa_info[MAX_NODES]; - static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, Error **errp) @@ -66,6 +64,7 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, uint16List *cpus = NULL; MachineClass *mc = MACHINE_GET_CLASS(ms); unsigned int max_cpus = ms->smp.max_cpus; + NodeInfo *numa_info = ms->numa_state->nodes; if (node->has_nodeid) { nodenr = node->nodeid; @@ -145,6 +144,7 @@ void parse_numa_distance(MachineState *ms, NumaDistOptions *dist, Error **errp) uint16_t src = dist->src; uint16_t dst = dist->dst; uint8_t val = dist->val; + NodeInfo *numa_info = ms->numa_state->nodes; if (src >= MAX_NODES || dst >= MAX_NODES) { error_setg(errp, "Parameter '%s' expects an integer between 0 and %d", @@ -203,7 +203,7 @@ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp) error_setg(&err, "Missing mandatory node-id property"); goto end; } - if (!numa_info[object->u.cpu.node_id].present) { + if (!ms->numa_state->nodes[object->u.cpu.node_id].present) { error_setg(&err, "Invalid node-id=%" PRId64 ", NUMA node must be " "defined with -numa node,nodeid=ID before it's used with " "-numa cpu,node-id=ID", object->u.cpu.node_id); @@ -263,6 +263,7 @@ static void validate_numa_distance(MachineState *ms) int src, dst; bool is_asymmetrical = false; int nb_numa_nodes = ms->numa_state->num_nodes; + NodeInfo *numa_info = ms->numa_state->nodes; for (src = 0; src < nb_numa_nodes; src++) { for (dst = src; dst < nb_numa_nodes; dst++) { @@ -303,6 +304,7 @@ static void validate_numa_distance(MachineState *ms) static void complete_init_numa_distance(MachineState *ms) { int src, dst; + NodeInfo *numa_info = ms->numa_state->nodes; /* Fixup NUMA distance by symmetric policy because if it is an * asymmetric distance table, it should be a complete table and @@ -362,6 +364,7 @@ void numa_complete_configuration(MachineState *ms) { int i; MachineClass *mc = MACHINE_GET_CLASS(ms); + NodeInfo *numa_info = ms->numa_state->nodes; /* * If memory hotplug is enabled (slots > 0) but without '-numa' @@ -527,8 +530,8 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, memory_region_init(mr, owner, name, ram_size); for (i = 0; i < ms->numa_state->num_nodes; i++) { - uint64_t size = numa_info[i].node_mem; - HostMemoryBackend *backend = numa_info[i].node_memdev; + uint64_t size = ms->numa_state->nodes[i].node_mem; + HostMemoryBackend *backend = ms->numa_state->nodes[i].node_memdev; if (!backend) { continue; } @@ -594,7 +597,7 @@ void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms) numa_stat_memory_devices(node_mem); for (i = 0; i < ms->numa_state->num_nodes; i++) { - node_mem[i].node_mem += numa_info[i].node_mem; + node_mem[i].node_mem += ms->numa_state->nodes[i].node_mem; } } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 5fba29c10b..985e9261b0 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1046,7 +1046,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms) } for (i = 0; i < nb_numa_nodes; i++) { numa_fw_cfg[pcms->apic_id_limit + 1 + i] = - cpu_to_le64(numa_info[i].node_mem); + cpu_to_le64(ms->numa_state->nodes[i].node_mem); } fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg, (1 + pcms->apic_id_limit + nb_numa_nodes) * @@ -1783,7 +1783,7 @@ void pc_guest_info_init(PCMachineState *pcms) pcms->node_mem = g_malloc0(pcms->numa_nodes * sizeof *pcms->node_mem); for (i = 0; i < ms->numa_state->num_nodes; i++) { - pcms->node_mem[i] = numa_info[i].node_mem; + pcms->node_mem[i] = ms->numa_state->nodes[i].node_mem; } pcms->machine_done.notify = pc_machine_done; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index a7eb87feb6..a9cd350f0d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -359,8 +359,8 @@ static hwaddr spapr_node0_size(MachineState *machine) if (machine->numa_state->num_nodes) { int i; for (i = 0; i < machine->numa_state->num_nodes; ++i) { - if (numa_info[i].node_mem) { - return MIN(pow2floor(numa_info[i].node_mem), + if (machine->numa_state->nodes[i].node_mem) { + return MIN(pow2floor(machine->numa_state->nodes[i].node_mem), machine->ram_size); } } @@ -404,7 +404,7 @@ static int spapr_populate_memory(SpaprMachineState *spapr, void *fdt) MachineState *machine = MACHINE(spapr); hwaddr mem_start, node_size; int i, nb_nodes = machine->numa_state->num_nodes; - NodeInfo *nodes = numa_info; + NodeInfo *nodes = machine->numa_state->nodes; NodeInfo ramnode; /* No NUMA nodes, assume there is just one node with whole RAM */ @@ -2541,11 +2541,11 @@ static void spapr_validate_node_memory(MachineState *machine, Error **errp) } for (i = 0; i < machine->numa_state->num_nodes; i++) { - if (numa_info[i].node_mem % SPAPR_MEMORY_BLOCK_SIZE) { + if (machine->numa_state->nodes[i].node_mem % SPAPR_MEMORY_BLOCK_SIZE) { error_setg(errp, "Node %d memory size 0x%" PRIx64 " is not aligned to %" PRIu64 " MiB", - i, numa_info[i].node_mem, + i, machine->numa_state->nodes[i].node_mem, SPAPR_MEMORY_BLOCK_SIZE / MiB); return; } diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index deb0b0c80c..210abc67c3 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1825,6 +1825,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) SysBusDevice *s = SYS_BUS_DEVICE(dev); SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(s); PCIHostState *phb = PCI_HOST_BRIDGE(s); + MachineState *ms = MACHINE(spapr); char *namebuf; int i; PCIBus *bus; @@ -1877,7 +1878,8 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) } if (sphb->numa_node != -1 && - (sphb->numa_node >= MAX_NODES || !numa_info[sphb->numa_node].present)) { + (sphb->numa_node >= MAX_NODES || + !ms->numa_state->nodes[sphb->numa_node].present)) { error_setg(errp, "Invalid NUMA node ID for PCI host bridge"); return; } diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h index bfe04b514c..ae9c41d02b 100644 --- a/include/sysemu/numa.h +++ b/include/sysemu/numa.h @@ -26,14 +26,15 @@ struct NumaNodeMem { uint64_t node_plugged_mem; }; -extern NodeInfo numa_info[MAX_NODES]; - struct NumaState { /* Number of NUMA nodes */ int num_nodes; /* Allow setting NUMA distance for different NUMA nodes */ bool have_numa_distance; + + /* NUMA nodes information */ + NodeInfo nodes[MAX_NODES]; }; typedef struct NumaState NumaState; From 2a0585e183d0b7c628638fa07a3ffee8db852d69 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 15 Aug 2019 15:38:01 -0300 Subject: [PATCH 06/13] pc: Fix error message on die-id validation The error message for die-id range validation is incorrect. Example: $ qemu-system-x86_64 -smp 1,sockets=6,maxcpus=6 \ -device qemu64-x86_64-cpu,socket-id=1,die-id=1,core-id=0,thread-id=0 qemu-system-x86_64: -device qemu64-x86_64-cpu,socket-id=1,die-id=1,core-id=0,thread-id=0: \ Invalid CPU die-id: 1 must be in range 0:5 The actual range for die-id in this example is 0:0. Fix the error message to use smp_dies and print the correct range. Signed-off-by: Eduardo Habkost Message-Id: <20190815183803.13346-2-ehabkost@redhat.com> Reviewed-by: Igor Mammedov Reviewed-by: Vanderson M. do Rosario Reviewed-by: Michael S. Tsirkin Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 985e9261b0..584cd3ed0a 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2430,7 +2430,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, return; } else if (cpu->die_id > pcms->smp_dies - 1) { error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u", - cpu->die_id, max_socket); + cpu->die_id, pcms->smp_dies - 1); return; } if (cpu->core_id < 0) { From 23d9cff4897cf983b0570b8676a093d829da019d Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 15 Aug 2019 15:38:02 -0300 Subject: [PATCH 07/13] pc: Improve error message when die-id is omitted The error message when die-id is omitted doesn't make sense: $ qemu-system-x86_64 -smp 1,sockets=6,maxcpus=6 \ -device qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0 qemu-system-x86_64: -device qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0: \ Invalid CPU die-id: 4294967295 must be in range 0:0 Fix it, so it will now read: qemu-system-x86_64: -device qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0: \ CPU die-id is not set Signed-off-by: Eduardo Habkost Message-Id: <20190815183803.13346-3-ehabkost@redhat.com> Reviewed-by: Igor Mammedov Reviewed-by: Vanderson M. do Rosario Reviewed-by: Michael S. Tsirkin Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 584cd3ed0a..3494423d63 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2428,6 +2428,10 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u", cpu->socket_id, max_socket); return; + } + if (cpu->die_id < 0) { + error_setg(errp, "CPU die-id is not set"); + return; } else if (cpu->die_id > pcms->smp_dies - 1) { error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u", cpu->die_id, pcms->smp_dies - 1); From fea374e7c8079563bca7c8fac895c6a880f76adc Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 16 Aug 2019 14:07:50 -0300 Subject: [PATCH 08/13] pc: Don't make die-id mandatory unless necessary We have this issue reported when using libvirt to hotplug CPUs: https://bugzilla.redhat.com/show_bug.cgi?id=1741451 Basically, libvirt is not copying die-id from query-hotpluggable-cpus, but die-id is now mandatory. We could blame libvirt and say it is not following the documented interface, because we have this buried in the QAPI schema documentation: > Note: currently there are 5 properties that could be present > but management should be prepared to pass through other > properties with device_add command to allow for future > interface extension. This also requires the filed names to be kept in > sync with the properties passed to -device/device_add. But I don't think this would be reasonable from us. We can just make QEMU more flexible and let die-id to be omitted when there's no ambiguity. This will allow us to keep compatibility with existing libvirt versions. Test case included to ensure we don't break this again. Fixes: commit 176d2cda0dee ("i386/cpu: Consolidate die-id validity in smp context") Signed-off-by: Eduardo Habkost Message-Id: <20190816170750.23910-1-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 8 ++++++ tests/acceptance/pc_cpu_hotplug_props.py | 35 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/acceptance/pc_cpu_hotplug_props.py diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 3494423d63..c7200b0b54 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2421,6 +2421,14 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, int max_socket = (ms->smp.max_cpus - 1) / smp_threads / smp_cores / pcms->smp_dies; + /* + * die-id was optional in QEMU 4.0 and older, so keep it optional + * if there's only one die per socket. + */ + if (cpu->die_id < 0 && pcms->smp_dies == 1) { + cpu->die_id = 0; + } + if (cpu->socket_id < 0) { error_setg(errp, "CPU socket-id is not set"); return; diff --git a/tests/acceptance/pc_cpu_hotplug_props.py b/tests/acceptance/pc_cpu_hotplug_props.py new file mode 100644 index 0000000000..08b7e632c6 --- /dev/null +++ b/tests/acceptance/pc_cpu_hotplug_props.py @@ -0,0 +1,35 @@ +# +# Ensure CPU die-id can be omitted on -device +# +# Copyright (c) 2019 Red Hat Inc +# +# Author: +# Eduardo Habkost +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see . +# + +from avocado_qemu import Test + +class OmittedCPUProps(Test): + """ + :avocado: tags=arch:x86_64 + """ + def test_no_die_id(self): + self.vm.add_args('-nodefaults', '-S') + self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8') + self.vm.add_args('-cpu', 'qemu64') + self.vm.add_args('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0') + self.vm.launch() + self.assertEquals(len(self.vm.command('query-cpus')), 2) From 04109957d47307cdedd19afc3687bd6307466b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 22 Aug 2019 11:04:12 +0100 Subject: [PATCH 09/13] qapi: report the default CPU type for each machine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When user doesn't request any explicit CPU model with libvirt or QEMU, a machine type specific CPU model is picked. Currently there is no way to determine what this QEMU built-in default is, so libvirt cannot report this back to the user in the XML config. This extends the "query-machines" QMP command so that it reports the default CPU model typename for each machine. Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrangé Message-Id: <20190822100412.23746-1-berrange@redhat.com> Signed-off-by: Eduardo Habkost --- hw/core/machine-qmp-cmds.c | 4 ++++ qapi/machine.json | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index 15cf7c62e3..eed5aeb2f7 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -230,6 +230,10 @@ MachineInfoList *qmp_query_machines(Error **errp) info->hotpluggable_cpus = mc->has_hotpluggable_cpus; info->numa_mem_supported = mc->numa_mem_supported; info->deprecated = !!mc->deprecation_reason; + if (mc->default_cpu_type) { + info->default_cpu_type = g_strdup(mc->default_cpu_type); + info->has_default_cpu_type = true; + } entry = g_malloc0(sizeof(*entry)); entry->value = info; diff --git a/qapi/machine.json b/qapi/machine.json index de5c742d72..ca26779f1a 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -348,13 +348,16 @@ # in future versions of QEMU according to the QEMU deprecation # policy (since 4.1.0) # +# @default-cpu-type: default CPU model typename if none is requested via +# the -cpu argument. (since 4.2) +# # Since: 1.2.0 ## { 'struct': 'MachineInfo', 'data': { 'name': 'str', '*alias': 'str', '*is-default': 'bool', 'cpu-max': 'int', 'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool', - 'deprecated': 'bool' } } + 'deprecated': 'bool', '*default-cpu-type': 'str' } } ## # @query-machines: From 7faae95ebc966c2981b78cf7c25009dfa32d4b72 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Fri, 23 Aug 2019 14:56:32 +0100 Subject: [PATCH 10/13] hostmem-file: fix pmem file size check Commit 314aec4a6e06844937f1677f6cba21981005f389 ("hostmem-file: reject invalid pmem file sizes") added a file size check that verifies the hostmem object's size parameter against the actual devdax pmem file. This is useful because getting the size wrong results in confusing errors inside the guest. However, the code doesn't work properly for files where struct stat::st_size is zero. Hostmem-file's ->alloc() function returns early without setting an Error, causing the following assertion failure: qemu/memory.c:2215: memory_region_get_ram_ptr: Assertion `mr->ram_block' failed. This patch handles the case where qemu_get_pmem_size() returns 0 but there is no error. Fixes: 314aec4a6e06844937f1677f6cba21981005f389 Signed-off-by: Stefan Hajnoczi Message-Id: <20190823135632.25010-1-stefanha@redhat.com> Signed-off-by: Eduardo Habkost --- backends/hostmem-file.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c index 29e55c9195..ecc15e3eb0 100644 --- a/backends/hostmem-file.c +++ b/backends/hostmem-file.c @@ -67,12 +67,12 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) uint64_t size; size = qemu_get_pmem_size(fb->mem_path, &local_err); - if (!size) { + if (local_err) { error_propagate(errp, local_err); return; } - if (backend->size > size) { + if (size && backend->size > size) { error_setg(errp, "size property %" PRIu64 " is larger than " "pmem file \"%s\" size %" PRIu64, backend->size, fb->mem_path, size); From f685f451578e5231bc899c48911cf7b98cad47f6 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sun, 21 Jul 2019 10:58:56 +0200 Subject: [PATCH 11/13] i386/vmmouse: Properly reset state nb_queue was not zeroed so that we no longer delivered events if a previous guest left the device in an overflow state. The state of absolute does not matter as the next vmmouse_update_handler call will align it again. Signed-off-by: Jan Kiszka Message-Id: Reviewed-by: Eduardo Habkost Signed-off-by: Eduardo Habkost --- hw/i386/vmmouse.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/i386/vmmouse.c b/hw/i386/vmmouse.c index 012ab90396..41ad91ad53 100644 --- a/hw/i386/vmmouse.c +++ b/hw/i386/vmmouse.c @@ -258,6 +258,7 @@ static void vmmouse_reset(DeviceState *d) VMMouseState *s = VMMOUSE(d); s->queue_size = VMMOUSE_QUEUE_SIZE; + s->nb_queue = 0; vmmouse_disable(s); } From c6c1bb89fb46f3b88f832e654cf5a6f7941aac51 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 2 Sep 2019 08:02:22 -0400 Subject: [PATCH 12/13] x86: do not advertise die-id in query-hotpluggbale-cpus if '-smp dies' is not set Commit 176d2cda0 (i386/cpu: Consolidate die-id validity in smp context) added new 'die-id' topology property to CPUs and exposed it via QMP command query-hotpluggable-cpus, which broke -device/device_add cpu-foo for existing users that do not support die-id/dies yet. That's would be fine if it happened to new machine type only but it also happened to old machine types, which breaks migration from old QEMU to the new one, for example following CLI: OLD-QEMU -M pc-i440fx-4.0 -smp 1,max_cpus=2 \ -device qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id is not able to start with new QEMU, complaining about invalid die-id. After discovering regression, the patch "pc: Don't make die-id mandatory unless necessary" makes die-id optional so old CLI would work. However it's not enough as new QEMU still exposes die-id via query-hotpluggbale-cpus QMP command, so the users that started old machine type on new QEMU, using all properties (including die-id) received from QMP command (as required), won't be able to start old QEMU using the same properties since it doesn't support die-id. Fix it by hiding die-id in query-hotpluggbale-cpus for all machine types in case '-smp dies' is not provided on CLI or -smp dies = 1', in which case smp_dies == 1 and APIC ID is calculated in default way (as it was before DIE support) so we won't need compat code as in both cases the topology provided to guest via CPUID is the same. Signed-off-by: Igor Mammedov Message-Id: <20190902120222.6179-1-imammedo@redhat.com> Reviewed-by: Eduardo Habkost Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index c7200b0b54..bad866fe44 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2916,8 +2916,10 @@ static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms) ms->smp.threads, &topo); ms->possible_cpus->cpus[i].props.has_socket_id = true; ms->possible_cpus->cpus[i].props.socket_id = topo.pkg_id; - ms->possible_cpus->cpus[i].props.has_die_id = true; - ms->possible_cpus->cpus[i].props.die_id = topo.die_id; + if (pcms->smp_dies > 1) { + ms->possible_cpus->cpus[i].props.has_die_id = true; + ms->possible_cpus->cpus[i].props.die_id = topo.die_id; + } ms->possible_cpus->cpus[i].props.has_core_id = true; ms->possible_cpus->cpus[i].props.core_id = topo.core_id; ms->possible_cpus->cpus[i].props.has_thread_id = true; From 417332494602e3edadfae3b759a29fa0bb96223f Mon Sep 17 00:00:00 2001 From: "Maxiwell S. Garcia" Date: Thu, 29 Aug 2019 18:07:11 -0300 Subject: [PATCH 13/13] migration: Do not re-read the clock on pre_save in case of paused guest The clock move makes the guest knows about the paused time between the 'stop' and 'migrate' commands. This is an issue in an already-paused VM because some side effects, like process stalls, could happen after migration. So, this patch checks the runstate of guest in the pre_save handler and do not re-reads the clock in case of paused state (cold migration). Signed-off-by: Maxiwell S. Garcia Message-Id: <20190829210711.6570-1-maxiwell@linux.ibm.com> Reviewed-by: Marcelo Tosatti Signed-off-by: Eduardo Habkost --- hw/i386/kvm/clock.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index 80c133a724..2c59b6894b 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -41,6 +41,9 @@ typedef struct KVMClockState { uint64_t clock; bool clock_valid; + /* whether the 'clock' value was obtained in the 'paused' state */ + bool runstate_paused; + /* whether machine type supports reliable KVM_GET_CLOCK */ bool mach_use_reliable_get_clock; @@ -202,6 +205,8 @@ static void kvmclock_vm_state_change(void *opaque, int running, return; } + s->runstate_paused = runstate_check(RUN_STATE_PAUSED); + kvm_synchronize_all_tsc(); kvm_update_clock(s); @@ -260,9 +265,9 @@ static int kvmclock_pre_load(void *opaque) } /* - * When migrating, read the clock just before migration, - * so that the guest clock counts during the events - * between: + * When migrating a running guest, read the clock just + * before migration, so that the guest clock counts + * during the events between: * * * vm_stop() * * @@ -277,7 +282,9 @@ static int kvmclock_pre_save(void *opaque) { KVMClockState *s = opaque; - kvm_update_clock(s); + if (!s->runstate_paused) { + kvm_update_clock(s); + } return 0; }