qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

arm/aspeed: Compute the number of CPUs from the SoC definition

Commit ece09beec457 ("aspeed: introduce a configurable number of CPU
per machine") was a convient change during bringup but the Aspeed SoCs
have a fixed number of CPUs : one for the AST2400 and AST2500, and two
for the AST2600.

When the number of CPUs configured with -smp is less than the SoC's
fixed number, the "unconfigured" CPUs are left unrealized. This can
happen for machines ast2600-evb and tacoma-bmc, where the SoC's fixed
number is 2. To get virtual hardware that matches the physical
hardware, you have to pass -smp cpus=2 (or its sugared form -smp 2).

We normally reject -smp cpus=N when N exceeds the machine's limit.
Except we ignore cpus=2 (and only cpus=2) with a warning for machines
ast2500-evb, palmetto-bmc, romulus-bmc, sonorapass-bmc, swift-bmc, and
witherspoon-bmc.

Remove the "num-cpu" property from the SoC state and use the fixed
number of CPUs defined in the SoC class instead. Compute the default,
min, max number of CPUs of the machine directly from the SoC class
definition.

Machines ast2600-evb and tacoma-bmc now always get their second CPU as
they should. Visible in "info qom-tree"; here's the change for
ast2600-evb:

/machine (ast2600-evb-machine)
/peripheral (container)
/peripheral-anon (container)
/soc (ast2600-a1)
/a7mpcore (a15mpcore_priv)
/a15mp-priv-container[0] (qemu:memory-region)
/gic (arm_gic)
/gic_cpu[0] (qemu:memory-region)
/gic_cpu[1] (qemu:memory-region)
+ /gic_cpu[2] (qemu:memory-region)
/gic_dist[0] (qemu:memory-region)
/gic_vcpu[0] (qemu:memory-region)
/gic_viface[0] (qemu:memory-region)
/gic_viface[1] (qemu:memory-region)
+ /gic_viface[2] (qemu:memory-region)
/unnamed-gpio-in[0] (irq)
[...]
+ /unnamed-gpio-in[160] (irq)
[same for 161 to 190...]
+ /unnamed-gpio-in[191] (irq)

Also visible in "info qtree"; here's the change for ast2600-evb:

bus: main-system-bus
type System
dev: a15mpcore_priv, id ""
gpio-in "" 128
- gpio-out "sysbus-irq" 5
- num-cpu = 1 (0x1)
+ gpio-out "sysbus-irq" 10
+ num-cpu = 2 (0x2)
num-irq = 160 (0xa0)
mmio 0000000040460000/0000000000008000
dev: arm_gic, id ""
- gpio-in "" 160
- num-cpu = 1 (0x1)
+ gpio-in "" 192
+ num-cpu = 2 (0x2)
num-irq = 160 (0xa0)
revision = 2 (0x2)
has-security-extensions = true
has-virtualization-extensions = true
num-priority-bits = 8 (0x8)
mmio ffffffffffffffff/0000000000001000
mmio ffffffffffffffff/0000000000002000
mmio ffffffffffffffff/0000000000001000
mmio ffffffffffffffff/0000000000002000
mmio ffffffffffffffff/0000000000000100
+ mmio ffffffffffffffff/0000000000000100
+ mmio ffffffffffffffff/0000000000000200
mmio ffffffffffffffff/0000000000000200

The other machines now reject -smp cpus=2 just like -smp cpus=3 and up.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Commit message expanded]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20200609122339.937862-5-armbru@redhat.com>

authored by

Cédric Le Goater and committed by
Markus Armbruster
b7f1a0cb 71e5770b

+32 -27
+24 -5
hw/arm/aspeed.c
··· 283 283 &error_abort); 284 284 object_property_set_int(OBJECT(&bmc->soc), amc->num_cs, "num-cs", 285 285 &error_abort); 286 - object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus", 287 - &error_abort); 288 286 object_property_set_link(OBJECT(&bmc->soc), OBJECT(&bmc->ram_container), 289 287 "dram", &error_abort); 290 288 if (machine->kernel_filename) { ··· 337 335 } 338 336 } 339 337 340 - if (machine->kernel_filename && bmc->soc.num_cpus > 1) { 338 + if (machine->kernel_filename && sc->num_cpus > 1) { 341 339 /* With no u-boot we must set up a boot stub for the secondary CPU */ 342 340 MemoryRegion *smpboot = g_new(MemoryRegion, 1); 343 341 memory_region_init_ram(smpboot, OBJECT(bmc), "aspeed.smpboot", ··· 352 350 353 351 aspeed_board_binfo.ram_size = ram_size; 354 352 aspeed_board_binfo.loader_start = sc->memmap[ASPEED_SDRAM]; 355 - aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus; 353 + aspeed_board_binfo.nb_cpus = sc->num_cpus; 356 354 357 355 if (amc->i2c_init) { 358 356 amc->i2c_init(bmc); ··· 549 547 "boot directly from CE0 flash device"); 550 548 } 551 549 550 + static int aspeed_soc_num_cpus(const char *soc_name) 551 + { 552 + AspeedSoCClass *sc = ASPEED_SOC_CLASS(object_class_by_name(soc_name)); 553 + return sc->num_cpus; 554 + } 555 + 552 556 static void aspeed_machine_class_init(ObjectClass *oc, void *data) 553 557 { 554 558 MachineClass *mc = MACHINE_CLASS(oc); 555 559 556 560 mc->init = aspeed_machine_init; 557 - mc->max_cpus = ASPEED_CPUS_NUM; 558 561 mc->no_floppy = 1; 559 562 mc->no_cdrom = 1; 560 563 mc->no_parallel = 1; ··· 576 579 amc->num_cs = 1; 577 580 amc->i2c_init = palmetto_bmc_i2c_init; 578 581 mc->default_ram_size = 256 * MiB; 582 + mc->default_cpus = mc->min_cpus = mc->max_cpus = 583 + aspeed_soc_num_cpus(amc->soc_name); 579 584 }; 580 585 581 586 static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data) ··· 591 596 amc->num_cs = 1; 592 597 amc->i2c_init = ast2500_evb_i2c_init; 593 598 mc->default_ram_size = 512 * MiB; 599 + mc->default_cpus = mc->min_cpus = mc->max_cpus = 600 + aspeed_soc_num_cpus(amc->soc_name); 594 601 }; 595 602 596 603 static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data) ··· 606 613 amc->num_cs = 2; 607 614 amc->i2c_init = romulus_bmc_i2c_init; 608 615 mc->default_ram_size = 512 * MiB; 616 + mc->default_cpus = mc->min_cpus = mc->max_cpus = 617 + aspeed_soc_num_cpus(amc->soc_name); 609 618 }; 610 619 611 620 static void aspeed_machine_sonorapass_class_init(ObjectClass *oc, void *data) ··· 621 630 amc->num_cs = 2; 622 631 amc->i2c_init = sonorapass_bmc_i2c_init; 623 632 mc->default_ram_size = 512 * MiB; 633 + mc->default_cpus = mc->min_cpus = mc->max_cpus = 634 + aspeed_soc_num_cpus(amc->soc_name); 624 635 }; 625 636 626 637 static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data) ··· 636 647 amc->num_cs = 2; 637 648 amc->i2c_init = swift_bmc_i2c_init; 638 649 mc->default_ram_size = 512 * MiB; 650 + mc->default_cpus = mc->min_cpus = mc->max_cpus = 651 + aspeed_soc_num_cpus(amc->soc_name); 639 652 }; 640 653 641 654 static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data) ··· 651 664 amc->num_cs = 2; 652 665 amc->i2c_init = witherspoon_bmc_i2c_init; 653 666 mc->default_ram_size = 512 * MiB; 667 + mc->default_cpus = mc->min_cpus = mc->max_cpus = 668 + aspeed_soc_num_cpus(amc->soc_name); 654 669 }; 655 670 656 671 static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data) ··· 667 682 amc->num_cs = 1; 668 683 amc->i2c_init = ast2600_evb_i2c_init; 669 684 mc->default_ram_size = 1 * GiB; 685 + mc->default_cpus = mc->min_cpus = mc->max_cpus = 686 + aspeed_soc_num_cpus(amc->soc_name); 670 687 }; 671 688 672 689 static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data) ··· 683 700 amc->num_cs = 2; 684 701 amc->i2c_init = witherspoon_bmc_i2c_init; /* Same board layout */ 685 702 mc->default_ram_size = 1 * GiB; 703 + mc->default_cpus = mc->min_cpus = mc->max_cpus = 704 + aspeed_soc_num_cpus(amc->soc_name); 686 705 }; 687 706 688 707 static const TypeInfo aspeed_machine_types[] = {
+7 -13
hw/arm/aspeed_ast2600.c
··· 255 255 create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_VIDEO], 256 256 0x1000); 257 257 258 - if (s->num_cpus > sc->num_cpus) { 259 - warn_report("%s: invalid number of CPUs %d, using default %d", 260 - sc->name, s->num_cpus, sc->num_cpus); 261 - s->num_cpus = sc->num_cpus; 262 - } 263 - 264 258 /* CPU */ 265 - for (i = 0; i < s->num_cpus; i++) { 259 + for (i = 0; i < sc->num_cpus; i++) { 266 260 object_property_set_int(OBJECT(&s->cpu[i]), QEMU_PSCI_CONDUIT_SMC, 267 261 "psci-conduit", &error_abort); 268 - if (s->num_cpus > 1) { 262 + if (sc->num_cpus > 1) { 269 263 object_property_set_int(OBJECT(&s->cpu[i]), 270 264 ASPEED_A7MPCORE_ADDR, 271 265 "reset-cbar", &error_abort); ··· 289 283 } 290 284 291 285 /* A7MPCORE */ 292 - object_property_set_int(OBJECT(&s->a7mpcore), s->num_cpus, "num-cpu", 286 + object_property_set_int(OBJECT(&s->a7mpcore), sc->num_cpus, "num-cpu", 293 287 &error_abort); 294 288 object_property_set_int(OBJECT(&s->a7mpcore), 295 289 ASPEED_SOC_AST2600_MAX_IRQ + GIC_INTERNAL, ··· 299 293 &error_abort); 300 294 sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, ASPEED_A7MPCORE_ADDR); 301 295 302 - for (i = 0; i < s->num_cpus; i++) { 296 + for (i = 0; i < sc->num_cpus; i++) { 303 297 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore); 304 298 DeviceState *d = DEVICE(qemu_get_cpu(i)); 305 299 306 300 irq = qdev_get_gpio_in(d, ARM_CPU_IRQ); 307 301 sysbus_connect_irq(sbd, i, irq); 308 302 irq = qdev_get_gpio_in(d, ARM_CPU_FIQ); 309 - sysbus_connect_irq(sbd, i + s->num_cpus, irq); 303 + sysbus_connect_irq(sbd, i + sc->num_cpus, irq); 310 304 irq = qdev_get_gpio_in(d, ARM_CPU_VIRQ); 311 - sysbus_connect_irq(sbd, i + 2 * s->num_cpus, irq); 305 + sysbus_connect_irq(sbd, i + 2 * sc->num_cpus, irq); 312 306 irq = qdev_get_gpio_in(d, ARM_CPU_VFIQ); 313 - sysbus_connect_irq(sbd, i + 3 * s->num_cpus, irq); 307 + sysbus_connect_irq(sbd, i + 3 * sc->num_cpus, irq); 314 308 } 315 309 316 310 /* SRAM */
+1 -8
hw/arm/aspeed_soc.c
··· 242 242 create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_VIDEO], 243 243 0x1000); 244 244 245 - if (s->num_cpus > sc->num_cpus) { 246 - warn_report("%s: invalid number of CPUs %d, using default %d", 247 - sc->name, s->num_cpus, sc->num_cpus); 248 - s->num_cpus = sc->num_cpus; 249 - } 250 - 251 245 /* CPU */ 252 - for (i = 0; i < s->num_cpus; i++) { 246 + for (i = 0; i < sc->num_cpus; i++) { 253 247 object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); 254 248 if (err) { 255 249 error_propagate(errp, err); ··· 460 454 aspeed_soc_get_irq(s, ASPEED_SDHCI)); 461 455 } 462 456 static Property aspeed_soc_properties[] = { 463 - DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0), 464 457 DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION, 465 458 MemoryRegion *), 466 459 DEFINE_PROP_END_OF_LIST(),
-1
include/hw/arm/aspeed_soc.h
··· 40 40 41 41 /*< public >*/ 42 42 ARMCPU cpu[ASPEED_CPUS_NUM]; 43 - uint32_t num_cpus; 44 43 A15MPPrivState a7mpcore; 45 44 MemoryRegion *dram_mr; 46 45 MemoryRegion sram;