aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2024-03-09 20:12:21 +0000
committerPeter Maydell <peter.maydell@linaro.org>2024-03-09 20:12:21 +0000
commit7489f7f3f81dcb776df8c1b9a9db281fc21bf05f (patch)
treeeb7054dfadaf2f7738a664ceb9789c2d1db3200e
parent89126b6dca5a66fb459a6189018c3dabe51d8745 (diff)
parentd3c79c397484ad117063702e6246e39f22f020f6 (diff)
Merge tag 'hw-misc-20240309' of https://github.com/philmd/qemu into stagingHEADmaster
Misc HW patch queue - hmp: Shorter 'info qtree' output (Zoltan) - qdev: Add a granule_mode property (Eric) - Some ERRP_GUARD() fixes (Zhao) - Doc & style fixes in docs/interop/firmware.json (Thomas) - hw/xen: Housekeeping (Phil) - hw/ppc/mac99: Change timebase frequency 25 -> 100 MHz (Mark) - hw/intc/apic: Memory leak fix (Paolo) - hw/intc/grlib_irqmp: Ensure ncpus value is in range (Clément) - hw/m68k/mcf5208: Add support for reset (Angelo) - hw/i386/pc: Housekeeping (Phil) - hw/core/smp: Remove/deprecate parameter=0,1 adapting test-smp-parse (Zhao) # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmXstpMACgkQ4+MsLN6t # wN6XBw//dNItFhf1YX+Au4cNoQVDgHE9RtzEIGOnwcL1CgrA9rAQQfLRE5KWM6sN # 1qiPh+T6SPxtiQ2rw4AIpsI7TXjO72b/RDWpUUSwnfH39eC77pijkxIK+i9mYI9r # p0sPjuP6OfolUFYeSbYX+DmNZh1ONPf27JATJQEf0st8dyswn7lTQvJEaQ97kwxv # UKA0JD5l9LZV8Zr92cgCzlrfLcbVblJGux9GYIL09yN78yqBuvTm77GBC/rvC+5Q # fQC5PQswJZ0+v32AXIfSysMp2R6veo4By7VH9Lp51E/u9jpc4ZbcDzxzaJWE6zOR # fZ01nFzou1qtUfZi+MxNiDR96LP6YoT9xFdGYfNS6AowZn8kymCs3eo7M9uvb+rN # A2Sgis9rXcjsR4e+w1YPBXwpalJnLwB0QYhEOStR8wo1ceg7GBG6zHUJV89OGzsA # KS8X0aV1Ulkdm/2H6goEhzrcC6FWLg8pBJpfKK8JFWxXNrj661xM0AAFVL9we356 # +ymthS2x/RTABSI+1Lfsoo6/SyXoimFXJJWA82q9Yzoaoq2gGMWnfwqxfix6JrrA # PuMnNP5WNvh04iWcNz380P0psLVteHWcVfTRN3JvcJ9iJ2bpjcU1mQMJtvSF9wBn # Y8kiJTUmZCu3br2e5EfxmypM/h8y29VD/1mxPk8Dtcq3gjx9AU4= # =juZH # -----END PGP SIGNATURE----- # gpg: Signature made Sat 09 Mar 2024 19:20:51 GMT # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'hw-misc-20240309' of https://github.com/philmd/qemu: (43 commits) hw/m68k/mcf5208: add support for reset tests/unit/test-smp-parse: Test "parameter=0" SMP configurations tests/unit/test-smp-parse: Test smp_props.has_clusters tests/unit/test-smp-parse: Test the full 7-levels topology hierarchy tests/unit/test-smp-parse: Test "drawers" and "books" combination case tests/unit/test-smp-parse: Test "drawers" parameter in -smp tests/unit/test-smp-parse: Test "books" parameter in -smp tests/unit/test-smp-parse: Make test cases aware of the book/drawer tests/unit/test-smp-parse: Bump max_cpus to 4096 tests/unit/test-smp-parse: Use CPU number macros in invalid topology case tests/unit/test-smp-parse: Drop the unsupported "dies=1" case hw/core/machine-smp: Calculate total CPUs once in machine_parse_smp_config() hw/core/machine-smp: Deprecate unsupported "parameter=1" SMP configurations hw/core/machine-smp: Remove deprecated "parameter=0" SMP configurations docs/interop/firmware.json: Fix doc for FirmwareFlashMode docs/interop/firmware.json: Align examples hw/intc/grlib_irqmp: abort realize when ncpus value is out of range mac_newworld: change timebase frequency from 100MHz to 25MHz for mac99 machine hmp: Add option to info qtree to omit details qdev: Add a granule_mode property ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--accel/xen/xen-all.c1
-rw-r--r--docs/about/deprecated.rst30
-rw-r--r--docs/about/removed-features.rst15
-rw-r--r--docs/interop/firmware.json386
-rw-r--r--hmp-commands-info.hx6
-rw-r--r--hw/arm/xen_arm.c6
-rw-r--r--hw/char/xen_console.c1
-rw-r--r--hw/core/machine-smp.c76
-rw-r--r--hw/core/qdev-properties-system.c14
-rw-r--r--hw/i386/meson.build2
-rw-r--r--hw/i386/pc_piix.c19
-rw-r--r--hw/i386/vapic.c (renamed from hw/i386/kvmvapic.c)5
-rw-r--r--hw/i386/xen/meson.build4
-rw-r--r--hw/i386/xen/xen-hvm.c82
-rw-r--r--hw/intc/grlib_irqmp.c1
-rw-r--r--hw/m68k/mcf5208.c44
-rw-r--r--hw/net/xen_nic.c1
-rw-r--r--hw/pci/msi.c3
-rw-r--r--hw/ppc/mac_newworld.c2
-rw-r--r--hw/remote/remote-obj.c1
-rw-r--r--hw/xen/xen-hvm-common.c12
-rw-r--r--hw/xen/xen_pt.c3
-rw-r--r--hw/xen/xen_pt.h24
-rw-r--r--hw/xen/xen_pt_config_init.c3
-rw-r--r--hw/xen/xen_pt_graphics.c3
-rw-r--r--hw/xen/xen_pt_stub.c2
-rw-r--r--include/hw/i386/pc.h12
-rw-r--r--include/hw/qdev-properties-system.h3
-rw-r--r--include/hw/xen/xen-hvm-common.h2
-rw-r--r--include/hw/xen/xen_igd.h33
-rw-r--r--include/sysemu/xen-mapcache.h3
-rw-r--r--include/sysemu/xen.h8
-rw-r--r--qapi/virtio.json18
-rw-r--r--stubs/xen-hw-stub.c4
-rw-r--r--system/physmem.c2
-rw-r--r--system/qdev-monitor.c27
-rw-r--r--target/i386/sev.c1
-rw-r--r--tests/unit/test-smp-parse.c612
38 files changed, 1097 insertions, 374 deletions
diff --git a/accel/xen/xen-all.c b/accel/xen/xen-all.c
index 5ff0cb8bd9..0bdefce537 100644
--- a/accel/xen/xen-all.c
+++ b/accel/xen/xen-all.c
@@ -15,6 +15,7 @@
#include "hw/xen/xen_native.h"
#include "hw/xen/xen-legacy-backend.h"
#include "hw/xen/xen_pt.h"
+#include "hw/xen/xen_igd.h"
#include "chardev/char.h"
#include "qemu/accel.h"
#include "sysemu/cpus.h"
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 8565644da6..dfd681cd02 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -36,22 +36,6 @@ and will cause a warning.
The replacement for the ``nodelay`` short-form boolean option is ``nodelay=on``
rather than ``delay=off``.
-``-smp`` ("parameter=0" SMP configurations) (since 6.2)
-'''''''''''''''''''''''''''''''''''''''''''''''''''''''
-
-Specified CPU topology parameters must be greater than zero.
-
-In the SMP configuration, users should either provide a CPU topology
-parameter with a reasonable value (greater than zero) or just omit it
-and QEMU will compute the missing value.
-
-However, historically it was implicitly allowed for users to provide
-a parameter with zero value, which is meaningless and could also possibly
-cause unexpected results in the -smp parsing. So support for this kind of
-configurations (e.g. -smp 8,sockets=0) is deprecated since 6.2 and will
-be removed in the near future, users have to ensure that all the topology
-members described with -smp are greater than zero.
-
Plugin argument passing through ``arg=<string>`` (since 6.1)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
@@ -73,6 +57,20 @@ The ``-p`` option pretends to control the host page size. However,
it is not possible to change the host page size, and using the
option only causes failures.
+``-smp`` (Unsupported "parameter=1" SMP configurations) (since 9.0)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+Specified CPU topology parameters must be supported by the machine.
+
+In the SMP configuration, users should provide the CPU topology parameters that
+are supported by the target machine.
+
+However, historically it was allowed for users to specify the unsupported
+topology parameter as "1", which is meaningless. So support for this kind of
+configurations (e.g. -smp drawers=1,books=1,clusters=1 for x86 PC machine) is
+marked deprecated since 9.0, users have to ensure that all the topology members
+described with -smp are supported by the target machine.
+
QEMU Machine Protocol (QMP) commands
------------------------------------
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
index 417a0e4fa1..f9cf874f7b 100644
--- a/docs/about/removed-features.rst
+++ b/docs/about/removed-features.rst
@@ -489,6 +489,21 @@ The ``-singlestep`` option has been turned into an accelerator property,
and given a name that better reflects what it actually does.
Use ``-accel tcg,one-insn-per-tb=on`` instead.
+``-smp`` ("parameter=0" SMP configurations) (removed in 9.0)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+Specified CPU topology parameters must be greater than zero.
+
+In the SMP configuration, users should either provide a CPU topology
+parameter with a reasonable value (greater than zero) or just omit it
+and QEMU will compute the missing value.
+
+However, historically it was implicitly allowed for users to provide
+a parameter with zero value, which is meaningless and could also possibly
+cause unexpected results in the -smp parsing. So support for this kind of
+configurations (e.g. -smp 8,sockets=0) is removed since 9.0, users have
+to ensure that all the topology members described with -smp are greater
+than zero.
User-mode emulator command line arguments
-----------------------------------------
diff --git a/docs/interop/firmware.json b/docs/interop/firmware.json
index cc8f869186..54a1fc6c10 100644
--- a/docs/interop/firmware.json
+++ b/docs/interop/firmware.json
@@ -223,7 +223,7 @@
##
-# @FirmwareFlashType:
+# @FirmwareFlashMode:
#
# Describes how the firmware build handles code versus variable
# persistence.
@@ -435,203 +435,203 @@
#
# Examples:
#
-# {
-# "description": "SeaBIOS",
-# "interface-types": [
-# "bios"
-# ],
-# "mapping": {
-# "device": "memory",
-# "filename": "/usr/share/seabios/bios-256k.bin"
-# },
-# "targets": [
-# {
-# "architecture": "i386",
-# "machines": [
-# "pc-i440fx-*",
-# "pc-q35-*"
-# ]
+# {
+# "description": "SeaBIOS",
+# "interface-types": [
+# "bios"
+# ],
+# "mapping": {
+# "device": "memory",
+# "filename": "/usr/share/seabios/bios-256k.bin"
# },
-# {
-# "architecture": "x86_64",
-# "machines": [
-# "pc-i440fx-*",
-# "pc-q35-*"
-# ]
-# }
-# ],
-# "features": [
-# "acpi-s3",
-# "acpi-s4"
-# ],
-# "tags": [
-# "CONFIG_BOOTSPLASH=n",
-# "CONFIG_ROM_SIZE=256",
-# "CONFIG_USE_SMM=n"
-# ]
-# }
-#
-# {
-# "description": "OVMF with SB+SMM, empty varstore",
-# "interface-types": [
-# "uefi"
-# ],
-# "mapping": {
-# "device": "flash",
-# "executable": {
-# "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
-# "format": "raw"
+# "targets": [
+# {
+# "architecture": "i386",
+# "machines": [
+# "pc-i440fx-*",
+# "pc-q35-*"
+# ]
+# },
+# {
+# "architecture": "x86_64",
+# "machines": [
+# "pc-i440fx-*",
+# "pc-q35-*"
+# ]
+# }
+# ],
+# "features": [
+# "acpi-s3",
+# "acpi-s4"
+# ],
+# "tags": [
+# "CONFIG_BOOTSPLASH=n",
+# "CONFIG_ROM_SIZE=256",
+# "CONFIG_USE_SMM=n"
+# ]
+# }
+#
+# {
+# "description": "OVMF with SB+SMM, empty varstore",
+# "interface-types": [
+# "uefi"
+# ],
+# "mapping": {
+# "device": "flash",
+# "executable": {
+# "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
+# "format": "raw"
+# },
+# "nvram-template": {
+# "filename": "/usr/share/OVMF/OVMF_VARS.fd",
+# "format": "raw"
+# }
# },
-# "nvram-template": {
-# "filename": "/usr/share/OVMF/OVMF_VARS.fd",
-# "format": "raw"
-# }
-# },
-# "targets": [
-# {
-# "architecture": "x86_64",
-# "machines": [
-# "pc-q35-*"
-# ]
-# }
-# ],
-# "features": [
-# "acpi-s3",
-# "amd-sev",
-# "requires-smm",
-# "secure-boot",
-# "verbose-dynamic"
-# ],
-# "tags": [
-# "-a IA32",
-# "-a X64",
-# "-p OvmfPkg/OvmfPkgIa32X64.dsc",
-# "-t GCC48",
-# "-b DEBUG",
-# "-D SMM_REQUIRE",
-# "-D SECURE_BOOT_ENABLE",
-# "-D FD_SIZE_4MB"
-# ]
-# }
-#
-# {
-# "description": "OVMF with SB+SMM, SB enabled, MS certs enrolled",
-# "interface-types": [
-# "uefi"
-# ],
-# "mapping": {
-# "device": "flash",
-# "executable": {
-# "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
-# "format": "raw"
+# "targets": [
+# {
+# "architecture": "x86_64",
+# "machines": [
+# "pc-q35-*"
+# ]
+# }
+# ],
+# "features": [
+# "acpi-s3",
+# "amd-sev",
+# "requires-smm",
+# "secure-boot",
+# "verbose-dynamic"
+# ],
+# "tags": [
+# "-a IA32",
+# "-a X64",
+# "-p OvmfPkg/OvmfPkgIa32X64.dsc",
+# "-t GCC48",
+# "-b DEBUG",
+# "-D SMM_REQUIRE",
+# "-D SECURE_BOOT_ENABLE",
+# "-D FD_SIZE_4MB"
+# ]
+# }
+#
+# {
+# "description": "OVMF with SB+SMM, SB enabled, MS certs enrolled",
+# "interface-types": [
+# "uefi"
+# ],
+# "mapping": {
+# "device": "flash",
+# "executable": {
+# "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
+# "format": "raw"
+# },
+# "nvram-template": {
+# "filename": "/usr/share/OVMF/OVMF_VARS.secboot.fd",
+# "format": "raw"
+# }
# },
-# "nvram-template": {
-# "filename": "/usr/share/OVMF/OVMF_VARS.secboot.fd",
-# "format": "raw"
-# }
-# },
-# "targets": [
-# {
-# "architecture": "x86_64",
-# "machines": [
-# "pc-q35-*"
-# ]
-# }
-# ],
-# "features": [
-# "acpi-s3",
-# "amd-sev",
-# "enrolled-keys",
-# "requires-smm",
-# "secure-boot",
-# "verbose-dynamic"
-# ],
-# "tags": [
-# "-a IA32",
-# "-a X64",
-# "-p OvmfPkg/OvmfPkgIa32X64.dsc",
-# "-t GCC48",
-# "-b DEBUG",
-# "-D SMM_REQUIRE",
-# "-D SECURE_BOOT_ENABLE",
-# "-D FD_SIZE_4MB"
-# ]
-# }
-#
-# {
-# "description": "OVMF with SEV-ES support",
-# "interface-types": [
-# "uefi"
-# ],
-# "mapping": {
-# "device": "flash",
-# "executable": {
-# "filename": "/usr/share/OVMF/OVMF_CODE.fd",
-# "format": "raw"
+# "targets": [
+# {
+# "architecture": "x86_64",
+# "machines": [
+# "pc-q35-*"
+# ]
+# }
+# ],
+# "features": [
+# "acpi-s3",
+# "amd-sev",
+# "enrolled-keys",
+# "requires-smm",
+# "secure-boot",
+# "verbose-dynamic"
+# ],
+# "tags": [
+# "-a IA32",
+# "-a X64",
+# "-p OvmfPkg/OvmfPkgIa32X64.dsc",
+# "-t GCC48",
+# "-b DEBUG",
+# "-D SMM_REQUIRE",
+# "-D SECURE_BOOT_ENABLE",
+# "-D FD_SIZE_4MB"
+# ]
+# }
+#
+# {
+# "description": "OVMF with SEV-ES support",
+# "interface-types": [
+# "uefi"
+# ],
+# "mapping": {
+# "device": "flash",
+# "executable": {
+# "filename": "/usr/share/OVMF/OVMF_CODE.fd",
+# "format": "raw"
+# },
+# "nvram-template": {
+# "filename": "/usr/share/OVMF/OVMF_VARS.fd",
+# "format": "raw"
+# }
# },
-# "nvram-template": {
-# "filename": "/usr/share/OVMF/OVMF_VARS.fd",
-# "format": "raw"
-# }
-# },
-# "targets": [
-# {
-# "architecture": "x86_64",
-# "machines": [
-# "pc-q35-*"
-# ]
-# }
-# ],
-# "features": [
-# "acpi-s3",
-# "amd-sev",
-# "amd-sev-es",
-# "verbose-dynamic"
-# ],
-# "tags": [
-# "-a X64",
-# "-p OvmfPkg/OvmfPkgX64.dsc",
-# "-t GCC48",
-# "-b DEBUG",
-# "-D FD_SIZE_4MB"
-# ]
-# }
-#
-# {
-# "description": "UEFI firmware for ARM64 virtual machines",
-# "interface-types": [
-# "uefi"
-# ],
-# "mapping": {
-# "device": "flash",
-# "executable": {
-# "filename": "/usr/share/AAVMF/AAVMF_CODE.fd",
-# "format": "raw"
+# "targets": [
+# {
+# "architecture": "x86_64",
+# "machines": [
+# "pc-q35-*"
+# ]
+# }
+# ],
+# "features": [
+# "acpi-s3",
+# "amd-sev",
+# "amd-sev-es",
+# "verbose-dynamic"
+# ],
+# "tags": [
+# "-a X64",
+# "-p OvmfPkg/OvmfPkgX64.dsc",
+# "-t GCC48",
+# "-b DEBUG",
+# "-D FD_SIZE_4MB"
+# ]
+# }
+#
+# {
+# "description": "UEFI firmware for ARM64 virtual machines",
+# "interface-types": [
+# "uefi"
+# ],
+# "mapping": {
+# "device": "flash",
+# "executable": {
+# "filename": "/usr/share/AAVMF/AAVMF_CODE.fd",
+# "format": "raw"
+# },
+# "nvram-template": {
+# "filename": "/usr/share/AAVMF/AAVMF_VARS.fd",
+# "format": "raw"
+# }
# },
-# "nvram-template": {
-# "filename": "/usr/share/AAVMF/AAVMF_VARS.fd",
-# "format": "raw"
-# }
-# },
-# "targets": [
-# {
-# "architecture": "aarch64",
-# "machines": [
-# "virt-*"
-# ]
-# }
-# ],
-# "features": [
-#
-# ],
-# "tags": [
-# "-a AARCH64",
-# "-p ArmVirtPkg/ArmVirtQemu.dsc",
-# "-t GCC48",
-# "-b DEBUG",
-# "-D DEBUG_PRINT_ERROR_LEVEL=0x80000000"
-# ]
-# }
+# "targets": [
+# {
+# "architecture": "aarch64",
+# "machines": [
+# "virt-*"
+# ]
+# }
+# ],
+# "features": [
+#
+# ],
+# "tags": [
+# "-a AARCH64",
+# "-p ArmVirtPkg/ArmVirtQemu.dsc",
+# "-t GCC48",
+# "-b DEBUG",
+# "-D DEBUG_PRINT_ERROR_LEVEL=0x80000000"
+# ]
+# }
##
{ 'struct' : 'Firmware',
'data' : { 'description' : 'str',
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index da120f82a3..ad1b1306e3 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -540,9 +540,9 @@ ERST
{
.name = "qtree",
- .args_type = "",
- .params = "",
- .help = "show device tree",
+ .args_type = "brief:-b",
+ .params = "[-b]",
+ .help = "show device tree (-b: brief, omit properties)",
.cmd = hmp_info_qtree,
},
diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
index 32776d94df..15fa7dfa84 100644
--- a/hw/arm/xen_arm.c
+++ b/hw/arm/xen_arm.c
@@ -114,14 +114,14 @@ static void xen_init_ram(MachineState *machine)
block_len = GUEST_RAM1_BASE + ram_size[1];
}
- memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len,
+ memory_region_init_ram(&xen_memory, NULL, "xen.ram", block_len,
&error_fatal);
- memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo", &ram_memory,
+ memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo", &xen_memory,
GUEST_RAM0_BASE, ram_size[0]);
memory_region_add_subregion(sysmem, GUEST_RAM0_BASE, &ram_lo);
if (ram_size[1] > 0) {
- memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi", &ram_memory,
+ memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi", &xen_memory,
GUEST_RAM1_BASE, ram_size[1]);
memory_region_add_subregion(sysmem, GUEST_RAM1_BASE, &ram_hi);
}
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index 5cbee2f184..683c92aca1 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -206,6 +206,7 @@ static bool con_event(void *_xendev)
static bool xen_console_connect(XenDevice *xendev, Error **errp)
{
+ ERRP_GUARD();
XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
unsigned int port, limit;
diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c
index 25019c91ee..27864c9507 100644
--- a/hw/core/machine-smp.c
+++ b/hw/core/machine-smp.c
@@ -91,6 +91,7 @@ void machine_parse_smp_config(MachineState *ms,
unsigned cores = config->has_cores ? config->cores : 0;
unsigned threads = config->has_threads ? config->threads : 0;
unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
+ unsigned total_cpus;
/*
* Specified CPU topology parameters must be greater than zero,
@@ -105,36 +106,68 @@ void machine_parse_smp_config(MachineState *ms,
(config->has_cores && config->cores == 0) ||
(config->has_threads && config->threads == 0) ||
(config->has_maxcpus && config->maxcpus == 0)) {
- warn_report("Deprecated CPU topology (considered invalid): "
- "CPU topology parameters must be greater than zero");
+ error_setg(errp, "Invalid CPU topology: "
+ "CPU topology parameters must be greater than zero");
+ return;
}
/*
* If not supported by the machine, a topology parameter must be
- * omitted or specified equal to 1.
+ * omitted.
*/
- if (!mc->smp_props.dies_supported && dies > 1) {
- error_setg(errp, "dies not supported by this machine's CPU topology");
- return;
- }
- if (!mc->smp_props.clusters_supported && clusters > 1) {
- error_setg(errp, "clusters not supported by this machine's CPU topology");
- return;
+ if (!mc->smp_props.clusters_supported && config->has_clusters) {
+ if (config->clusters > 1) {
+ error_setg(errp, "clusters not supported by this "
+ "machine's CPU topology");
+ return;
+ } else {
+ /* Here clusters only equals 1 since we've checked zero case. */
+ warn_report("Deprecated CPU topology (considered invalid): "
+ "Unsupported clusters parameter mustn't be "
+ "specified as 1");
+ }
}
+ clusters = clusters > 0 ? clusters : 1;
+ if (!mc->smp_props.dies_supported && config->has_dies) {
+ if (config->dies > 1) {
+ error_setg(errp, "dies not supported by this "
+ "machine's CPU topology");
+ return;
+ } else {
+ /* Here dies only equals 1 since we've checked zero case. */
+ warn_report("Deprecated CPU topology (considered invalid): "
+ "Unsupported dies parameter mustn't be "
+ "specified as 1");
+ }
+ }
dies = dies > 0 ? dies : 1;
- clusters = clusters > 0 ? clusters : 1;
- if (!mc->smp_props.books_supported && books > 1) {
- error_setg(errp, "books not supported by this machine's CPU topology");
- return;
+ if (!mc->smp_props.books_supported && config->has_books) {
+ if (config->books > 1) {
+ error_setg(errp, "books not supported by this "
+ "machine's CPU topology");
+ return;
+ } else {
+ /* Here books only equals 1 since we've checked zero case. */
+ warn_report("Deprecated CPU topology (considered invalid): "
+ "Unsupported books parameter mustn't be "
+ "specified as 1");
+ }
}
books = books > 0 ? books : 1;
- if (!mc->smp_props.drawers_supported && drawers > 1) {
- error_setg(errp,
- "drawers not supported by this machine's CPU topology");
- return;
+ if (!mc->smp_props.drawers_supported && config->has_drawers) {
+ if (config->drawers > 1) {
+ error_setg(errp, "drawers not supported by this "
+ "machine's CPU topology");
+ return;
+ } else {
+ /* Here drawers only equals 1 since we've checked zero case. */
+ warn_report("Deprecated CPU topology (considered invalid): "
+ "Unsupported drawers parameter mustn't be "
+ "specified as 1");
+ }
}
drawers = drawers > 0 ? drawers : 1;
@@ -179,8 +212,8 @@ void machine_parse_smp_config(MachineState *ms,
}
}
- maxcpus = maxcpus > 0 ? maxcpus : drawers * books * sockets * dies *
- clusters * cores * threads;
+ total_cpus = drawers * books * sockets * dies * clusters * cores * threads;
+ maxcpus = maxcpus > 0 ? maxcpus : total_cpus;
cpus = cpus > 0 ? cpus : maxcpus;
ms->smp.cpus = cpus;
@@ -196,8 +229,7 @@ void machine_parse_smp_config(MachineState *ms,
mc->smp_props.has_clusters = config->has_clusters;
/* sanity-check of the computed topology */
- if (drawers * books * sockets * dies * clusters * cores * threads !=
- maxcpus) {
+ if (total_cpus != maxcpus) {
g_autofree char *topo_msg = cpu_hierarchy_to_string(ms);
error_setg(errp, "Invalid CPU topology: "
"product of the hierarchy must match maxcpus: "
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 1a396521d5..b45e90edb2 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -679,6 +679,20 @@ const PropertyInfo qdev_prop_mig_mode = {
.set_default_value = qdev_propinfo_set_default_value_enum,
};
+/* --- GranuleMode --- */
+
+QEMU_BUILD_BUG_ON(sizeof(GranuleMode) != sizeof(int));
+
+const PropertyInfo qdev_prop_granule_mode = {
+ .name = "GranuleMode",
+ .description = "granule_mode values, "
+ "4k, 8k, 16k, 64k, host",
+ .enum_table = &GranuleMode_lookup,
+ .get = qdev_propinfo_get_enum,
+ .set = qdev_propinfo_set_enum,
+ .set_default_value = qdev_propinfo_set_default_value_enum,
+};
+
/* --- Reserved Region --- */
/*
diff --git a/hw/i386/meson.build b/hw/i386/meson.build
index b9c1ca39cb..d8b70ef3e9 100644
--- a/hw/i386/meson.build
+++ b/hw/i386/meson.build
@@ -1,7 +1,7 @@
i386_ss = ss.source_set()
i386_ss.add(files(
'fw_cfg.c',
- 'kvmvapic.c',
+ 'vapic.c',
'e820_memory_layout.c',
'multiboot.c',
'x86.c',
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index ce6aad758d..319bc4b180 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -55,11 +55,13 @@
#ifdef CONFIG_XEN
#include <xen/hvm/hvm_info_table.h>
#include "hw/xen/xen_pt.h"
+#include "hw/xen/xen_igd.h"
#endif
#include "hw/xen/xen-x86.h"
#include "hw/xen/xen.h"
#include "migration/global_state.h"
#include "migration/misc.h"
+#include "sysemu/runstate.h"
#include "sysemu/numa.h"
#include "hw/hyperv/vmbus-bridge.h"
#include "hw/mem/nvdimm.h"
@@ -99,8 +101,7 @@ static void piix_intx_routing_notifier_xen(PCIDevice *dev)
}
/* PC hardware initialisation */
-static void pc_init1(MachineState *machine,
- const char *host_type, const char *pci_type)
+static void pc_init1(MachineState *machine, const char *pci_type)
{
PCMachineState *pcms = PC_MACHINE(machine);
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
@@ -192,7 +193,7 @@ static void pc_init1(MachineState *machine,
memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
rom_memory = pci_memory;
- phb = OBJECT(qdev_new(host_type));
+ phb = OBJECT(qdev_new(TYPE_I440FX_PCI_HOST_BRIDGE));
object_property_add_child(OBJECT(machine), "i440fx", phb);
object_property_set_link(phb, PCI_HOST_PROP_RAM_MEM,
OBJECT(ram_memory), &error_fatal);
@@ -382,9 +383,6 @@ static const QEnumLookup PCSouthBridgeOption_lookup = {
.size = PC_SOUTH_BRIDGE_OPTION_MAX
};
-#define NotifyVmexitOption_str(val) \
- qapi_enum_lookup(&NotifyVmexitOption_lookup, (val))
-
static int pc_get_south_bridge(Object *obj, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
@@ -452,7 +450,7 @@ static void pc_compat_2_0_fn(MachineState *machine)
#ifdef CONFIG_ISAPC
static void pc_init_isa(MachineState *machine)
{
- pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
+ pc_init1(machine, NULL);
}
#endif
@@ -462,9 +460,7 @@ static void pc_xen_hvm_init_pci(MachineState *machine)
const char *pci_type = xen_igd_gfx_pt_enabled() ?
TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE : TYPE_I440FX_PCI_DEVICE;
- pc_init1(machine,
- TYPE_I440FX_PCI_HOST_BRIDGE,
- pci_type);
+ pc_init1(machine, pci_type);
}
static void pc_xen_hvm_init(MachineState *machine)
@@ -489,8 +485,7 @@ static void pc_xen_hvm_init(MachineState *machine)
if (compat) { \
compat(machine); \
} \
- pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
- TYPE_I440FX_PCI_DEVICE); \
+ pc_init1(machine, TYPE_I440FX_PCI_DEVICE); \
} \
DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
diff --git a/hw/i386/kvmvapic.c b/hw/i386/vapic.c
index 61a65ef2ab..f5b1db7e5f 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/vapic.c
@@ -747,8 +747,7 @@ static void do_vapic_enable(CPUState *cs, run_on_cpu_data data)
s->state = VAPIC_ACTIVE;
}
-static void kvmvapic_vm_state_change(void *opaque, bool running,
- RunState state)
+static void vapic_vm_state_change(void *opaque, bool running, RunState state)
{
MachineState *ms = MACHINE(qdev_get_machine());
VAPICROMState *s = opaque;
@@ -793,7 +792,7 @@ static int vapic_post_load(void *opaque, int version_id)
if (!s->vmsentry) {
s->vmsentry =
- qemu_add_vm_change_state_handler(kvmvapic_vm_state_change, s);
+ qemu_add_vm_change_state_handler(vapic_vm_state_change, s);
}
return 0;
}
diff --git a/hw/i386/xen/meson.build b/hw/i386/xen/meson.build
index 3dc4c4f106..3f0df8bc07 100644
--- a/hw/i386/xen/meson.build
+++ b/hw/i386/xen/meson.build
@@ -1,8 +1,10 @@
i386_ss.add(when: 'CONFIG_XEN', if_true: files(
- 'xen-hvm.c',
'xen_apic.c',
'xen_pvdevice.c',
))
+i386_ss.add(when: ['CONFIG_XEN', xen], if_true: files(
+ 'xen-hvm.c',
+))
i386_ss.add(when: 'CONFIG_XEN_BUS', if_true: files(
'xen_platform.c',
diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index f42621e674..7745cb3963 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -23,6 +23,7 @@
#include "hw/xen/xen-hvm-common.h"
#include "hw/xen/arch_hvm.h"
#include <xen/hvm/e820.h>
+#include "exec/target_page.h"
static MemoryRegion ram_640k, ram_lo, ram_hi;
static MemoryRegion *framebuffer;
@@ -149,12 +150,12 @@ static void xen_ram_init(PCMachineState *pcms,
*/
block_len = (4 * GiB) + x86ms->above_4g_mem_size;
}
- memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len,
+ memory_region_init_ram(&xen_memory, NULL, "xen.ram", block_len,
&error_fatal);
- *ram_memory_p = &ram_memory;
+ *ram_memory_p = &xen_memory;
memory_region_init_alias(&ram_640k, NULL, "xen.ram.640k",
- &ram_memory, 0, 0xa0000);
+ &xen_memory, 0, 0xa0000);
memory_region_add_subregion(sysmem, 0, &ram_640k);
/* Skip of the VGA IO memory space, it will be registered later by the VGA
* emulated device.
@@ -163,22 +164,23 @@ static void xen_ram_init(PCMachineState *pcms,
* the Options ROM, so it is registered here as RAM.
*/
memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo",
- &ram_memory, 0xc0000,
+ &xen_memory, 0xc0000,
x86ms->below_4g_mem_size - 0xc0000);
memory_region_add_subregion(sysmem, 0xc0000, &ram_lo);
if (x86ms->above_4g_mem_size > 0) {
memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi",
- &ram_memory, 0x100000000ULL,
+ &xen_memory, 0x100000000ULL,
x86ms->above_4g_mem_size);
memory_region_add_subregion(sysmem, 0x100000000ULL, &ram_hi);
}
}
-static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size)
+static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size,
+ int page_mask)
{
XenPhysmap *physmap = NULL;
- start_addr &= TARGET_PAGE_MASK;
+ start_addr &= page_mask;
QLIST_FOREACH(physmap, &xen_physmap, list) {
if (range_covers_byte(physmap->start_addr, physmap->size, start_addr)) {
@@ -188,9 +190,10 @@ static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size)
return NULL;
}
-static hwaddr xen_phys_offset_to_gaddr(hwaddr phys_offset, ram_addr_t size)
+static hwaddr xen_phys_offset_to_gaddr(hwaddr phys_offset, ram_addr_t size,
+ int page_mask)
{
- hwaddr addr = phys_offset & TARGET_PAGE_MASK;
+ hwaddr addr = phys_offset & page_mask;
XenPhysmap *physmap = NULL;
QLIST_FOREACH(physmap, &xen_physmap, list) {
@@ -245,6 +248,9 @@ static int xen_add_to_physmap(XenIOState *state,
MemoryRegion *mr,
hwaddr offset_within_region)
{
+ unsigned target_page_bits = qemu_target_page_bits();
+ int page_size = qemu_target_page_size();
+ int page_mask = -page_size;
unsigned long nr_pages;
int rc = 0;
XenPhysmap *physmap = NULL;
@@ -252,7 +258,7 @@ static int xen_add_to_physmap(XenIOState *state,
hwaddr phys_offset = memory_region_get_ram_addr(mr);
const char *mr_name;
- if (get_physmapping(start_addr, size)) {
+ if (get_physmapping(start_addr, size, page_mask)) {
return 0;
}
if (size <= 0) {
@@ -292,9 +298,9 @@ go_physmap:
return 0;
}
- pfn = phys_offset >> TARGET_PAGE_BITS;
- start_gpfn = start_addr >> TARGET_PAGE_BITS;
- nr_pages = size >> TARGET_PAGE_BITS;
+ pfn = phys_offset >> target_page_bits;
+ start_gpfn = start_addr >> target_page_bits;
+ nr_pages = size >> target_page_bits;
rc = xendevicemodel_relocate_memory(xen_dmod, xen_domid, nr_pages, pfn,
start_gpfn);
if (rc) {
@@ -308,8 +314,8 @@ go_physmap:
}
rc = xendevicemodel_pin_memory_cacheattr(xen_dmod, xen_domid,
- start_addr >> TARGET_PAGE_BITS,
- (start_addr + size - 1) >> TARGET_PAGE_BITS,
+ start_addr >> target_page_bits,
+ (start_addr + size - 1) >> target_page_bits,
XEN_DOMCTL_MEM_CACHEATTR_WB);
if (rc) {
error_report("pin_memory_cacheattr failed: %s", strerror(errno));
@@ -321,11 +327,14 @@ static int xen_remove_from_physmap(XenIOState *state,
hwaddr start_addr,
ram_addr_t size)
{
+ unsigned target_page_bits = qemu_target_page_bits();
+ int page_size = qemu_target_page_size();
+ int page_mask = -page_size;
int rc = 0;
XenPhysmap *physmap = NULL;
hwaddr phys_offset = 0;
- physmap = get_physmapping(start_addr, size);
+ physmap = get_physmapping(start_addr, size, page_mask);
if (physmap == NULL) {
return -1;
}
@@ -336,9 +345,9 @@ static int xen_remove_from_physmap(XenIOState *state,
DPRINTF("unmapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx", at "
"%"HWADDR_PRIx"\n", start_addr, start_addr + size, phys_offset);
- size >>= TARGET_PAGE_BITS;
- start_addr >>= TARGET_PAGE_BITS;
- phys_offset >>= TARGET_PAGE_BITS;
+ size >>= target_page_bits;
+ start_addr >>= target_page_bits;
+ phys_offset >>= target_page_bits;
rc = xendevicemodel_relocate_memory(xen_dmod, xen_domid, size, start_addr,
phys_offset);
if (rc) {
@@ -367,13 +376,16 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
hwaddr start_addr,
ram_addr_t size)
{
- hwaddr npages = size >> TARGET_PAGE_BITS;
+ unsigned target_page_bits = qemu_target_page_bits();
+ int page_size = qemu_target_page_size();
+ int page_mask = -page_size;
+ hwaddr npages = size >> target_page_bits;
const int width = sizeof(unsigned long) * 8;
size_t bitmap_size = DIV_ROUND_UP(npages, width);
int rc, i, j;
const XenPhysmap *physmap = NULL;
- physmap = get_physmapping(start_addr, size);
+ physmap = get_physmapping(start_addr, size, page_mask);
if (physmap == NULL) {
/* not handled */
return;
@@ -387,7 +399,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
return;
}
- rc = xen_track_dirty_vram(xen_domid, start_addr >> TARGET_PAGE_BITS,
+ rc = xen_track_dirty_vram(xen_domid, start_addr >> target_page_bits,
npages, dirty_bitmap);
if (rc < 0) {
#ifndef ENODATA
@@ -408,8 +420,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
j = ctzl(map);
map &= ~(1ul << j);
memory_region_set_dirty(framebuffer,
- (i * width + j) * TARGET_PAGE_SIZE,
- TARGET_PAGE_SIZE);
+ (i * width + j) * page_size, page_size);
};
}
}
@@ -629,17 +640,21 @@ void xen_register_framebuffer(MemoryRegion *mr)
void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
{
+ unsigned target_page_bits = qemu_target_page_bits();
+ int page_size = qemu_target_page_size();
+ int page_mask = -page_size;
+
if (unlikely(xen_in_migration)) {
int rc;
ram_addr_t start_pfn, nb_pages;
- start = xen_phys_offset_to_gaddr(start, length);
+ start = xen_phys_offset_to_gaddr(start, length, page_mask);
if (length == 0) {
- length = TARGET_PAGE_SIZE;
+ length = page_size;
}
- start_pfn = start >> TARGET_PAGE_BITS;
- nb_pages = ((start + length + TARGET_PAGE_SIZE - 1) >> TARGET_PAGE_BITS)
+ start_pfn = start >> target_page_bits;
+ nb_pages = ((start + length + page_size - 1) >> target_page_bits)
- start_pfn;
rc = xen_modified_memory(xen_domid, start_pfn, nb_pages);
if (rc) {
@@ -662,6 +677,9 @@ void qmp_xen_set_global_dirty_log(bool enable, Error **errp)
void arch_xen_set_memory(XenIOState *state, MemoryRegionSection *section,
bool add)
{
+ unsigned target_page_bits = qemu_target_page_bits();
+ int page_size = qemu_target_page_size();
+ int page_mask = -page_size;
hwaddr start_addr = section->offset_within_address_space;
ram_addr_t size = int128_get64(section->size);
bool log_dirty = memory_region_is_logging(section->mr, DIRTY_MEMORY_VGA);
@@ -677,8 +695,8 @@ void arch_xen_set_memory(XenIOState *state, MemoryRegionSection *section,
trace_xen_client_set_memory(start_addr, size, log_dirty);
- start_addr &= TARGET_PAGE_MASK;
- size = TARGET_PAGE_ALIGN(size);
+ start_addr &= page_mask;
+ size = ROUND_UP(size, page_size);
if (add) {
if (!memory_region_is_rom(section->mr)) {
@@ -687,8 +705,8 @@ void arch_xen_set_memory(XenIOState *state, MemoryRegionSection *section,
} else {
mem_type = HVMMEM_ram_ro;
if (xen_set_mem_type(xen_domid, mem_type,
- start_addr >> TARGET_PAGE_BITS,
- size >> TARGET_PAGE_BITS)) {
+ start_addr >> target_page_bits,
+ size >> target_page_bits)) {
DPRINTF("xen_set_mem_type error, addr: "HWADDR_FMT_plx"\n",
start_addr);
}
diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c
index 144b121d48..c6c51a349c 100644
--- a/hw/intc/grlib_irqmp.c
+++ b/hw/intc/grlib_irqmp.c
@@ -356,6 +356,7 @@ static void grlib_irqmp_realize(DeviceState *dev, Error **errp)
error_setg(errp, "Invalid ncpus properties: "
"%u, must be 0 < ncpus =< %u.", irqmp->ncpus,
IRQMP_MAX_CPU);
+ return;
}
qdev_init_gpio_in(dev, grlib_irqmp_set_irq, MAX_PILS);
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index 0cfb806c20..ec14096aa4 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -40,6 +40,8 @@
#define PCSR_PRE_SHIFT 8
#define PCSR_PRE_MASK 0x0f00
+#define RCR_SOFTRST 0x80
+
typedef struct {
MemoryRegion iomem;
qemu_irq irq;
@@ -185,12 +187,50 @@ static const MemoryRegionOps m5208_sys_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
+static uint64_t m5208_rcm_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ return 0;
+}
+
+static void m5208_rcm_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ M68kCPU *cpu = opaque;
+ CPUState *cs = CPU(cpu);
+ switch (addr) {
+ case 0x0: /* RCR */
+ if (value & RCR_SOFTRST) {
+ cpu_reset(cs);
+ cpu->env.aregs[7] = ldl_phys(cs->as, 0);
+ cpu->env.pc = ldl_phys(cs->as, 4);
+ }
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
+ __func__, addr);
+ break;
+ }
+}
+
+static const MemoryRegionOps m5208_rcm_ops = {
+ .read = m5208_rcm_read,
+ .write = m5208_rcm_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic,
+ M68kCPU *cpu)
{
MemoryRegion *iomem = g_new(MemoryRegion, 1);
+ MemoryRegion *iomem_rcm = g_new(MemoryRegion, 1);
m5208_timer_state *s;
int i;
+ /* RCM */
+ memory_region_init_io(iomem_rcm, NULL, &m5208_rcm_ops, cpu,
+ "m5208-rcm", 0x00000080);
+ memory_region_add_subregion(address_space, 0xfc0a0000, iomem_rcm);
/* SDRAMC. */
memory_region_init_io(iomem, NULL, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000);
memory_region_add_subregion(address_space, 0xfc0a8000, iomem);
@@ -265,7 +305,7 @@ static void mcf5208evb_init(MachineState *machine)
mcf_uart_create_mmap(0xfc064000, pic[27], serial_hd(1));
mcf_uart_create_mmap(0xfc068000, pic[28], serial_hd(2));
- mcf5208_sys_init(address_space_mem, pic);
+ mcf5208_sys_init(address_space_mem, pic, cpu);
mcf_fec_init(address_space_mem, 0xfc030000, pic + 36);
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
index 453fdb9819..89487b49ba 100644
--- a/hw/net/xen_nic.c
+++ b/hw/net/xen_nic.c
@@ -351,6 +351,7 @@ static bool net_event(void *_xendev)
static bool xen_netdev_connect(XenDevice *xendev, Error **errp)
{
+ ERRP_GUARD();
XenNetDev *netdev = XEN_NET_DEVICE(xendev);
unsigned int port, rx_copy;
diff --git a/hw/pci/msi.c b/hw/pci/msi.c
index 041b0bdbec..8104ac1d91 100644
--- a/hw/pci/msi.c
+++ b/hw/pci/msi.c
@@ -23,6 +23,7 @@
#include "hw/xen/xen.h"
#include "qemu/range.h"
#include "qapi/error.h"
+#include "sysemu/xen.h"
#include "hw/i386/kvm/xen_evtchn.h"
@@ -308,7 +309,7 @@ bool msi_is_masked(const PCIDevice *dev, unsigned int vector)
}
data = pci_get_word(dev->config + msi_data_off(dev, msi64bit));
- if (xen_is_pirq_msi(data)) {
+ if (xen_enabled() && xen_is_pirq_msi(data)) {
return false;
}
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 3e796d2f6d..ff9e490c4e 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -77,7 +77,7 @@
#define MAX_IDE_BUS 2
#define CFG_ADDR 0xf0000510
-#define TBFREQ (100UL * 1000UL * 1000UL)
+#define TBFREQ (25UL * 1000UL * 1000UL)
#define CLOCKFREQ (900UL * 1000UL * 1000UL)
#define BUSFREQ (100UL * 1000UL * 1000UL)
diff --git a/hw/remote/remote-obj.c b/hw/remote/remote-obj.c
index 65b6f7cc86..dc27cc8da1 100644
--- a/hw/remote/remote-obj.c
+++ b/hw/remote/remote-obj.c
@@ -49,6 +49,7 @@ struct RemoteObject {
static void remote_object_set_fd(Object *obj, const char *str, Error **errp)
{
+ ERRP_GUARD();
RemoteObject *o = REMOTE_OBJECT(obj);
int fd = -1;
diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index baa1adb9f2..1627da7398 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -1,6 +1,7 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
+#include "exec/target_page.h"
#include "trace.h"
#include "hw/pci/pci_host.h"
@@ -9,11 +10,12 @@
#include "hw/boards.h"
#include "hw/xen/arch_hvm.h"
-MemoryRegion ram_memory;
+MemoryRegion xen_memory;
void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
Error **errp)
{
+ unsigned target_page_bits = qemu_target_page_bits();
unsigned long nr_pfn;
xen_pfn_t *pfn_list;
int i;
@@ -26,17 +28,17 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
return;
}
- if (mr == &ram_memory) {
+ if (mr == &xen_memory) {
return;
}
trace_xen_ram_alloc(ram_addr, size);
- nr_pfn = size >> TARGET_PAGE_BITS;
+ nr_pfn = size >> target_page_bits;
pfn_list = g_new(xen_pfn_t, nr_pfn);
for (i = 0; i < nr_pfn; i++) {
- pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
+ pfn_list[i] = (ram_addr >> target_page_bits) + i;
}
if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
@@ -53,7 +55,7 @@ static void xen_set_memory(struct MemoryListener *listener,
{
XenIOState *state = container_of(listener, XenIOState, memory_listener);
- if (section->mr == &ram_memory) {
+ if (section->mr == &xen_memory) {
return;
} else {
if (add) {
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index 36e6f93c37..a8edabdabc 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -59,7 +59,8 @@
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
-#include "xen_pt.h"
+#include "hw/xen/xen_pt.h"
+#include "hw/xen/xen_igd.h"
#include "hw/xen/xen.h"
#include "hw/xen/xen-legacy-backend.h"
#include "qemu/range.h"
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 31bcfdf705..095a0f0365 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -1,3 +1,13 @@
+/*
+ * Copyright (c) 2007, Neocleus Corporation.
+ * Copyright (c) 2007, Intel Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Alex Novik <alex@neocleus.com>
+ * Allen Kay <allen.m.kay@intel.com>
+ * Guy Zana <guy@neocleus.com>
+ */
#ifndef XEN_PT_H
#define XEN_PT_H
@@ -5,9 +15,6 @@
#include "xen-host-pci-device.h"
#include "qom/object.h"
-bool xen_igd_gfx_pt_enabled(void);
-void xen_igd_gfx_pt_set(bool value, Error **errp);
-
void xen_pt_log(const PCIDevice *d, const char *f, ...) G_GNUC_PRINTF(2, 3);
#define XEN_PT_ERR(d, _f, _a...) xen_pt_log(d, "%s: Error: "_f, __func__, ##_a)
@@ -52,12 +59,6 @@ typedef struct XenPTDeviceClass {
XenPTQdevRealize pci_qdev_realize;
} XenPTDeviceClass;
-uint32_t igd_read_opregion(XenPCIPassthroughState *s);
-void xen_igd_reserve_slot(PCIBus *pci_bus);
-void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val);
-void xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s,
- XenHostPCIDevice *dev);
-
/* function type for config reg */
typedef int (*xen_pt_conf_reg_init)
(XenPCIPassthroughState *, XenPTRegInfo *, uint32_t real_offset,
@@ -343,11 +344,6 @@ static inline bool xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar)
void *pci_assign_dev_load_option_rom(PCIDevice *dev, int *size,
unsigned int domain, unsigned int bus,
unsigned int slot, unsigned int function);
-static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
-{
- return (xen_igd_gfx_pt_enabled()
- && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
-}
int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev,
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 2b8680b112..ba4cd78238 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -15,7 +15,8 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/timer.h"
-#include "xen_pt.h"
+#include "hw/xen/xen_pt.h"
+#include "hw/xen/xen_igd.h"
#include "hw/xen/xen-legacy-backend.h"
#define XEN_PT_MERGE_VALUE(value, data, val_mask) \
diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c
index 0aed3bb6fd..6c2e3f4840 100644
--- a/hw/xen/xen_pt_graphics.c
+++ b/hw/xen/xen_pt_graphics.c
@@ -3,7 +3,8 @@
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "xen_pt.h"
+#include "hw/xen/xen_pt.h"
+#include "hw/xen/xen_igd.h"
#include "xen-host-pci-device.h"
static unsigned long igd_guest_opregion;
diff --git a/hw/xen/xen_pt_stub.c b/hw/xen/xen_pt_stub.c
index 5c108446a8..72feebeb20 100644
--- a/hw/xen/xen_pt_stub.c
+++ b/hw/xen/xen_pt_stub.c
@@ -6,7 +6,7 @@
*/
#include "qemu/osdep.h"
-#include "hw/xen/xen_pt.h"
+#include "hw/xen/xen_igd.h"
#include "qapi/error.h"
bool xen_igd_gfx_pt_enabled(void)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 5065590281..b958023187 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -288,18 +288,6 @@ extern const size_t pc_compat_2_1_len;
extern GlobalProperty pc_compat_2_0[];
extern const size_t pc_compat_2_0_len;
-extern GlobalProperty pc_compat_1_7[];
-extern const size_t pc_compat_1_7_len;
-
-extern GlobalProperty pc_compat_1_6[];
-extern const size_t pc_compat_1_6_len;
-
-extern GlobalProperty pc_compat_1_5[];
-extern const size_t pc_compat_1_5_len;
-
-extern GlobalProperty pc_compat_1_4[];
-extern const size_t pc_compat_1_4_len;
-
#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \
{ \
diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
index 06c359c190..626be87dd3 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -8,6 +8,7 @@ extern const PropertyInfo qdev_prop_macaddr;
extern const PropertyInfo qdev_prop_reserved_region;
extern const PropertyInfo qdev_prop_multifd_compression;
extern const PropertyInfo qdev_prop_mig_mode;
+extern const PropertyInfo qdev_prop_granule_mode;
extern const PropertyInfo qdev_prop_losttickpolicy;
extern const PropertyInfo qdev_prop_blockdev_on_error;
extern const PropertyInfo qdev_prop_bios_chs_trans;
@@ -47,6 +48,8 @@ extern const PropertyInfo qdev_prop_iothread_vq_mapping_list;
#define DEFINE_PROP_MIG_MODE(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_mig_mode, \
MigMode)
+#define DEFINE_PROP_GRANULE_MODE(_n, _s, _f, _d) \
+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_granule_mode, GranuleMode)
#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
LostTickPolicy)
diff --git a/include/hw/xen/xen-hvm-common.h b/include/hw/xen/xen-hvm-common.h
index 4b1d728f35..65a51aac2e 100644
--- a/include/hw/xen/xen-hvm-common.h
+++ b/include/hw/xen/xen-hvm-common.h
@@ -15,7 +15,7 @@
#include "qemu/error-report.h"
#include <xen/hvm/ioreq.h>
-extern MemoryRegion ram_memory;
+extern MemoryRegion xen_memory;
extern MemoryListener xen_io_listener;
extern DeviceListener xen_device_listener;
diff --git a/include/hw/xen/xen_igd.h b/include/hw/xen/xen_igd.h
new file mode 100644
index 0000000000..7ffca06c10
--- /dev/null
+++ b/include/hw/xen/xen_igd.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2007, Neocleus Corporation.
+ * Copyright (c) 2007, Intel Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Alex Novik <alex@neocleus.com>
+ * Allen Kay <allen.m.kay@intel.com>
+ * Guy Zana <guy@neocleus.com>
+ */
+#ifndef XEN_IGD_H
+#define XEN_IGD_H
+
+#include "hw/xen/xen-host-pci-device.h"
+
+typedef struct XenPCIPassthroughState XenPCIPassthroughState;
+
+bool xen_igd_gfx_pt_enabled(void);
+void xen_igd_gfx_pt_set(bool value, Error **errp);
+
+uint32_t igd_read_opregion(XenPCIPassthroughState *s);
+void xen_igd_reserve_slot(PCIBus *pci_bus);
+void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val);
+void xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s,
+ XenHostPCIDevice *dev);
+
+static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
+{
+ return (xen_igd_gfx_pt_enabled()
+ && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
+}
+
+#endif
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index c8e7c2f6cf..10c2e3082a 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -10,10 +10,11 @@
#define XEN_MAPCACHE_H
#include "exec/cpu-common.h"
+#include "sysemu/xen.h"
typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
ram_addr_t size);
-#ifdef CONFIG_XEN
+#ifdef CONFIG_XEN_IS_POSSIBLE
void xen_map_cache_init(phys_offset_to_gaddr_t f,
void *opaque);
diff --git a/include/sysemu/xen.h b/include/sysemu/xen.h
index bc13ad5692..a9f591f26d 100644
--- a/include/sysemu/xen.h
+++ b/include/sysemu/xen.h
@@ -10,6 +10,10 @@
#ifndef SYSEMU_XEN_H
#define SYSEMU_XEN_H
+#ifdef CONFIG_USER_ONLY
+#error Cannot include sysemu/xen.h from user emulation
+#endif
+
#include "exec/cpu-common.h"
#ifdef NEED_CPU_H
@@ -26,16 +30,13 @@ extern bool xen_allowed;
#define xen_enabled() (xen_allowed)
-#ifndef CONFIG_USER_ONLY
void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length);
void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
struct MemoryRegion *mr, Error **errp);
-#endif
#else /* !CONFIG_XEN_IS_POSSIBLE */
#define xen_enabled() 0
-#ifndef CONFIG_USER_ONLY
static inline void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
{
/* nothing */
@@ -45,7 +46,6 @@ static inline void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
{
g_assert_not_reached();
}
-#endif
#endif /* CONFIG_XEN_IS_POSSIBLE */
diff --git a/qapi/virtio.json b/qapi/virtio.json
index a79013fe89..95745fdfd7 100644
--- a/qapi/virtio.json
+++ b/qapi/virtio.json
@@ -957,3 +957,21 @@
{ 'struct': 'DummyVirtioForceArrays',
'data': { 'unused-iothread-vq-mapping': ['IOThreadVirtQueueMapping'] } }
+
+##
+# @GranuleMode:
+#
+# @4k: granule page size of 4KiB
+#
+# @8k: granule page size of 8KiB
+#
+# @16k: granule page size of 16KiB
+#
+# @64k: granule page size of 64KiB
+#
+# @host: granule matches the host page size
+#
+# Since: 9.0
+##
+{ 'enum': 'GranuleMode',
+ 'data': [ '4k', '8k', '16k', '64k', 'host' ] }
diff --git a/stubs/xen-hw-stub.c b/stubs/xen-hw-stub.c
index 7d7ffe83a9..6cf0e9a4c1 100644
--- a/stubs/xen-hw-stub.c
+++ b/stubs/xen-hw-stub.c
@@ -24,10 +24,6 @@ int xen_set_pci_link_route(uint8_t link, uint8_t irq)
return -1;
}
-void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
-{
-}
-
int xen_is_pirq_msi(uint32_t msi_data)
{
return 0;
diff --git a/system/physmem.c b/system/physmem.c
index 3adda08ebf..6e9ed97597 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -35,7 +35,7 @@
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#include "hw/boards.h"
-#include "hw/xen/xen.h"
+#include "sysemu/xen.h"
#include "sysemu/kvm.h"
#include "sysemu/tcg.h"
#include "sysemu/qtest.h"
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 874d65191c..09e07cab9b 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -744,7 +744,6 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
}
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
-static void qbus_print(Monitor *mon, BusState *bus, int indent);
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
int indent)
@@ -784,13 +783,9 @@ static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int ind
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
{
ObjectClass *class;
- BusState *child;
NamedGPIOList *ngl;
NamedClockList *ncl;
- qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
- dev->id ? dev->id : "");
- indent += 2;
QLIST_FOREACH(ngl, &dev->gpios, node) {
if (ngl->num_in) {
qdev_printf("gpio-in \"%s\" %d\n", ngl->name ? ngl->name : "",
@@ -814,12 +809,9 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
class = object_class_get_parent(class);
} while (class != object_class_by_name(TYPE_DEVICE));
bus_print_dev(dev->parent_bus, mon, dev, indent);
- QLIST_FOREACH(child, &dev->child_bus, sibling) {
- qbus_print(mon, child, indent);
- }
}
-static void qbus_print(Monitor *mon, BusState *bus, int indent)
+static void qbus_print(Monitor *mon, BusState *bus, int indent, bool details)
{
BusChild *kid;
@@ -827,16 +819,27 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent)
indent += 2;
qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ BusState *child_bus;
DeviceState *dev = kid->child;
- qdev_print(mon, dev, indent);
+ qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
+ dev->id ? dev->id : "");
+ if (details) {
+ qdev_print(mon, dev, indent + 2);
+ }
+ QLIST_FOREACH(child_bus, &dev->child_bus, sibling) {
+ qbus_print(mon, child_bus, indent + 2, details);
+ }
}
}
#undef qdev_printf
void hmp_info_qtree(Monitor *mon, const QDict *qdict)
{
- if (sysbus_get_default())
- qbus_print(mon, sysbus_get_default(), 0);
+ bool details = !qdict_get_try_bool(qdict, "brief", false);
+
+ if (sysbus_get_default()) {
+ qbus_print(mon, sysbus_get_default(), 0, details);
+ }
}
void hmp_info_qdm(Monitor *mon, const QDict *qdict)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 173de91afe..72930ff0dc 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -1044,6 +1044,7 @@ sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp)
int sev_inject_launch_secret(const char *packet_hdr, const char *secret,
uint64_t gpa, Error **errp)
{
+ ERRP_GUARD();
struct kvm_sev_launch_secret input;
g_autofree guchar *data = NULL, *hdr = NULL;
int error, ret = 1;
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
index 24972666a7..8994337e12 100644
--- a/tests/unit/test-smp-parse.c
+++ b/tests/unit/test-smp-parse.c
@@ -20,8 +20,8 @@
#define T true
#define F false
-#define MIN_CPUS 1 /* set the min CPUs supported by the machine as 1 */
-#define MAX_CPUS 512 /* set the max CPUs supported by the machine as 512 */
+#define MIN_CPUS 1 /* set the min CPUs supported by the machine as 1 */
+#define MAX_CPUS 4096 /* set the max CPUs supported by the machine as 4096 */
#define SMP_MACHINE_NAME "TEST-SMP"
@@ -75,6 +75,40 @@
.has_maxcpus = hf, .maxcpus = f, \
}
+/*
+ * Currently a 5-level topology hierarchy is supported on s390 ccw machines
+ * -drawers/books/sockets/cores/threads
+ */
+#define SMP_CONFIG_WITH_BOOKS_DRAWERS(ha, a, hb, b, hc, c, hd, \
+ d, he, e, hf, f, hg, g) \
+ { \
+ .has_cpus = ha, .cpus = a, \
+ .has_drawers = hb, .drawers = b, \
+ .has_books = hc, .books = c, \
+ .has_sockets = hd, .sockets = d, \
+ .has_cores = he, .cores = e, \
+ .has_threads = hf, .threads = f, \
+ .has_maxcpus = hg, .maxcpus = g, \
+ }
+
+/*
+ * Currently QEMU supports up to a 7-level topology hierarchy, which is the
+ * QEMU's unified abstract representation of CPU topology.
+ * -drawers/books/sockets/dies/clusters/cores/threads
+ */
+#define SMP_CONFIG_WITH_FULL_TOPO(a, b, c, d, e, f, g, h, i) \
+ { \
+ .has_cpus = true, .cpus = a, \
+ .has_drawers = true, .drawers = b, \
+ .has_books = true, .books = c, \
+ .has_sockets = true, .sockets = d, \
+ .has_dies = true, .dies = e, \
+ .has_clusters = true, .clusters = f, \
+ .has_cores = true, .cores = g, \
+ .has_threads = true, .threads = h, \
+ .has_maxcpus = true, .maxcpus = i, \
+ }
+
/**
* @config - the given SMP configuration
* @expect_prefer_sockets - the expected parsing result for the
@@ -309,6 +343,16 @@ static const struct SMPTestData data_generic_invalid[] = {
.config = SMP_CONFIG_WITH_CLUSTERS(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0),
.expect_error = "clusters not supported by this machine's CPU topology",
}, {
+ /* config: -smp 2,books=2 */
+ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 2, F, 0, T, 2, F,
+ 0, F, 0, F, 0, F, 0),
+ .expect_error = "books not supported by this machine's CPU topology",
+ }, {
+ /* config: -smp 2,drawers=2 */
+ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 2, T, 2, F, 0, F,
+ 0, F, 0, F, 0, F, 0),
+ .expect_error = "drawers not supported by this machine's CPU topology",
+ }, {
/* config: -smp 8,sockets=2,cores=4,threads=2,maxcpus=8 */
.config = SMP_CONFIG_GENERIC(T, 8, T, 2, T, 4, T, 2, T, 8),
.expect_error = "Invalid CPU topology: "
@@ -323,17 +367,23 @@ static const struct SMPTestData data_generic_invalid[] = {
"sockets (2) * cores (4) * threads (2) "
"== maxcpus (16) < smp_cpus (18)",
}, {
- /* config: -smp 1
- * should tweak the supported min CPUs to 2 for testing */
- .config = SMP_CONFIG_GENERIC(T, 1, F, 0, F, 0, F, 0, F, 0),
+ /*
+ * config: -smp 1
+ * The test machine should tweak the supported min CPUs to
+ * 2 (MIN_CPUS + 1) for testing.
+ */
+ .config = SMP_CONFIG_GENERIC(T, MIN_CPUS, F, 0, F, 0, F, 0, F, 0),
.expect_error = "Invalid SMP CPUs 1. The min CPUs supported "
"by machine '" SMP_MACHINE_NAME "' is 2",
}, {
- /* config: -smp 512
- * should tweak the supported max CPUs to 511 for testing */
- .config = SMP_CONFIG_GENERIC(T, 512, F, 0, F, 0, F, 0, F, 0),
- .expect_error = "Invalid SMP CPUs 512. The max CPUs supported "
- "by machine '" SMP_MACHINE_NAME "' is 511",
+ /*
+ * config: -smp 4096
+ * The test machine should tweak the supported max CPUs to
+ * 4095 (MAX_CPUS - 1) for testing.
+ */
+ .config = SMP_CONFIG_GENERIC(T, 4096, F, 0, F, 0, F, 0, F, 0),
+ .expect_error = "Invalid SMP CPUs 4096. The max CPUs supported "
+ "by machine '" SMP_MACHINE_NAME "' is 4095",
},
};
@@ -373,11 +423,199 @@ static const struct SMPTestData data_with_clusters_invalid[] = {
},
};
+static const struct SMPTestData data_with_books_invalid[] = {
+ {
+ /* config: -smp 16,books=2,sockets=2,cores=4,threads=2,maxcpus=16 */
+ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 16, F, 1, T, 2, T,
+ 2, T, 4, T, 2, T, 16),
+ .expect_error = "Invalid CPU topology: "
+ "product of the hierarchy must match maxcpus: "
+ "books (2) * sockets (2) * cores (4) * threads (2) "
+ "!= maxcpus (16)",
+ }, {
+ /* config: -smp 34,books=2,sockets=2,cores=4,threads=2,maxcpus=32 */
+ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 34, F, 1, T, 2, T,
+ 2, T, 4, T, 2, T, 32),
+ .expect_error = "Invalid CPU topology: "
+ "maxcpus must be equal to or greater than smp: "
+ "books (2) * sockets (2) * cores (4) * threads (2) "
+ "== maxcpus (32) < smp_cpus (34)",
+ },
+};
+
+static const struct SMPTestData data_with_drawers_invalid[] = {
+ {
+ /* config: -smp 16,drawers=2,sockets=2,cores=4,threads=2,maxcpus=16 */
+ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 16, T, 2, F, 1, T,
+ 2, T, 4, T, 2, T, 16),
+ .expect_error = "Invalid CPU topology: "
+ "product of the hierarchy must match maxcpus: "
+ "drawers (2) * sockets (2) * cores (4) * threads (2) "
+ "!= maxcpus (16)",
+ }, {
+ /* config: -smp 34,drawers=2,sockets=2,cores=4,threads=2,maxcpus=32 */
+ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 34, T, 2, F, 1, T,
+ 2, T, 4, T, 2, T, 32),
+ .expect_error = "Invalid CPU topology: "
+ "maxcpus must be equal to or greater than smp: "
+ "drawers (2) * sockets (2) * cores (4) * threads (2) "
+ "== maxcpus (32) < smp_cpus (34)",
+ },
+};
+
+static const struct SMPTestData data_with_drawers_books_invalid[] = {
+ {
+ /*
+ * config: -smp 200,drawers=2,books=2,sockets=2,cores=4,\
+ * threads=2,maxcpus=200
+ */
+ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 200, T, 3, T, 5, T,
+ 2, T, 4, T, 2, T, 200),
+ .expect_error = "Invalid CPU topology: "
+ "product of the hierarchy must match maxcpus: "
+ "drawers (3) * books (5) * sockets (2) * "
+ "cores (4) * threads (2) != maxcpus (200)",
+ }, {
+ /*
+ * config: -smp 242,drawers=2,books=2,sockets=2,cores=4,\
+ * threads=2,maxcpus=240
+ */
+ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 242, T, 3, T, 5, T,
+ 2, T, 4, T, 2, T, 240),
+ .expect_error = "Invalid CPU topology: "
+ "maxcpus must be equal to or greater than smp: "
+ "drawers (3) * books (5) * sockets (2) * "
+ "cores (4) * threads (2) "
+ "== maxcpus (240) < smp_cpus (242)",
+ },
+};
+
+static const struct SMPTestData data_full_topo_invalid[] = {
+ {
+ /*
+ * config: -smp 200,drawers=3,books=5,sockets=2,dies=4,\
+ * clusters=2,cores=7,threads=2,maxcpus=200
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(200, 3, 5, 2, 4, 2, 7, 2, 200),
+ .expect_error = "Invalid CPU topology: "
+ "product of the hierarchy must match maxcpus: "
+ "drawers (3) * books (5) * sockets (2) * dies (4) * "
+ "clusters (2) * cores (7) * threads (2) "
+ "!= maxcpus (200)",
+ }, {
+ /*
+ * config: -smp 3361,drawers=3,books=5,sockets=2,dies=4,\
+ * clusters=2,cores=7,threads=2,maxcpus=3360
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(3361, 3, 5, 2, 4, 2, 7, 2, 3360),
+ .expect_error = "Invalid CPU topology: "
+ "maxcpus must be equal to or greater than smp: "
+ "drawers (3) * books (5) * sockets (2) * dies (4) * "
+ "clusters (2) * cores (7) * threads (2) "
+ "== maxcpus (3360) < smp_cpus (3361)",
+ }, {
+ /*
+ * config: -smp 1,drawers=3,books=5,sockets=2,dies=4,\
+ * clusters=2,cores=7,threads=3,maxcpus=5040
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(3361, 3, 5, 2, 4, 2, 7, 3, 5040),
+ .expect_error = "Invalid SMP CPUs 5040. The max CPUs supported "
+ "by machine '" SMP_MACHINE_NAME "' is 4096",
+ },
+};
+
+static const struct SMPTestData data_zero_topo_invalid[] = {
+ {
+ /*
+ * Test "cpus=0".
+ * config: -smp 0,drawers=1,books=1,sockets=1,dies=1,\
+ * clusters=1,cores=1,threads=1,maxcpus=1
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(0, 1, 1, 1, 1, 1, 1, 1, 1),
+ .expect_error = "Invalid CPU topology: CPU topology parameters must "
+ "be greater than zero",
+ }, {
+ /*
+ * Test "drawers=0".
+ * config: -smp 1,drawers=0,books=1,sockets=1,dies=1,\
+ * clusters=1,cores=1,threads=1,maxcpus=1
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(1, 0, 1, 1, 1, 1, 1, 1, 1),
+ .expect_error = "Invalid CPU topology: CPU topology parameters must "
+ "be greater than zero",
+ }, {
+ /*
+ * Test "books=0".
+ * config: -smp 1,drawers=1,books=0,sockets=1,dies=1,\
+ * clusters=1,cores=1,threads=1,maxcpus=1
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 0, 1, 1, 1, 1, 1, 1),
+ .expect_error = "Invalid CPU topology: CPU topology parameters must "
+ "be greater than zero",
+ }, {
+ /*
+ * Test "sockets=0".
+ * config: -smp 1,drawers=1,books=1,sockets=0,dies=1,\
+ * clusters=1,cores=1,threads=1,maxcpus=1
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 0, 1, 1, 1, 1, 1),
+ .expect_error = "Invalid CPU topology: CPU topology parameters must "
+ "be greater than zero",
+ }, {
+ /*
+ * Test "dies=0".
+ * config: -smp 1,drawers=1,books=1,sockets=1,dies=0,\
+ * clusters=1,cores=1,threads=1,maxcpus=1
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 0, 1, 1, 1, 1),
+ .expect_error = "Invalid CPU topology: CPU topology parameters must "
+ "be greater than zero",
+ }, {
+ /*
+ * Test "clusters=0".
+ * config: -smp 1,drawers=1,books=1,sockets=1,dies=1,\
+ * clusters=0,cores=1,threads=1,maxcpus=1
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 0, 1, 1, 1),
+ .expect_error = "Invalid CPU topology: CPU topology parameters must "
+ "be greater than zero",
+ }, {
+ /*
+ * Test "cores=0".
+ * config: -smp 1,drawers=1,books=1,sockets=1,dies=1,\
+ * clusters=1,cores=0,threads=1,maxcpus=1
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 1, 0, 1, 1),
+ .expect_error = "Invalid CPU topology: CPU topology parameters must "
+ "be greater than zero",
+ }, {
+ /*
+ * Test "threads=0".
+ * config: -smp 1,drawers=1,books=1,sockets=1,dies=1,\
+ * clusters=1,cores=1,threads=0,maxcpus=1
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 1, 1, 0, 1),
+ .expect_error = "Invalid CPU topology: CPU topology parameters must "
+ "be greater than zero",
+ }, {
+ /*
+ * Test "maxcpus=0".
+ * config: -smp 1,drawers=1,books=1,sockets=1,dies=1,\
+ * clusters=1,cores=1,threads=1,maxcpus=0
+ */
+ .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 1, 1, 1, 0),
+ .expect_error = "Invalid CPU topology: CPU topology parameters must "
+ "be greater than zero",
+ },
+};
+
static char *smp_config_to_string(const SMPConfiguration *config)
{
return g_strdup_printf(
"(SMPConfiguration) {\n"
" .has_cpus = %5s, cpus = %" PRId64 ",\n"
+ " .has_drawers = %5s, drawers = %" PRId64 ",\n"
+ " .has_books = %5s, books = %" PRId64 ",\n"
" .has_sockets = %5s, sockets = %" PRId64 ",\n"
" .has_dies = %5s, dies = %" PRId64 ",\n"
" .has_clusters = %5s, clusters = %" PRId64 ",\n"
@@ -386,6 +624,8 @@ static char *smp_config_to_string(const SMPConfiguration *config)
" .has_maxcpus = %5s, maxcpus = %" PRId64 ",\n"
"}",
config->has_cpus ? "true" : "false", config->cpus,
+ config->has_drawers ? "true" : "false", config->drawers,
+ config->has_books ? "true" : "false", config->books,
config->has_sockets ? "true" : "false", config->sockets,
config->has_dies ? "true" : "false", config->dies,
config->has_clusters ? "true" : "false", config->clusters,
@@ -398,10 +638,10 @@ static char *smp_config_to_string(const SMPConfiguration *config)
static unsigned int cpu_topology_get_threads_per_socket(const CpuTopology *topo)
{
/* Check the divisor to avoid invalid topology examples causing SIGFPE. */
- if (!topo->sockets) {
+ if (!topo->drawers || !topo->books || !topo->sockets) {
return 0;
} else {
- return topo->max_cpus / topo->sockets;
+ return topo->max_cpus / topo->drawers / topo->books / topo->sockets;
}
}
@@ -418,11 +658,14 @@ static unsigned int cpu_topology_get_cores_per_socket(const CpuTopology *topo)
static char *cpu_topology_to_string(const CpuTopology *topo,
unsigned int threads_per_socket,
- unsigned int cores_per_socket)
+ unsigned int cores_per_socket,
+ bool has_clusters)
{
return g_strdup_printf(
"(CpuTopology) {\n"
" .cpus = %u,\n"
+ " .drawers = %u,\n"
+ " .books = %u,\n"
" .sockets = %u,\n"
" .dies = %u,\n"
" .clusters = %u,\n"
@@ -431,16 +674,20 @@ static char *cpu_topology_to_string(const CpuTopology *topo,
" .max_cpus = %u,\n"
" .threads_per_socket = %u,\n"
" .cores_per_socket = %u,\n"
+ " .has_clusters = %s,\n"
"}",
- topo->cpus, topo->sockets, topo->dies, topo->clusters,
+ topo->cpus, topo->drawers, topo->books,
+ topo->sockets, topo->dies, topo->clusters,
topo->cores, topo->threads, topo->max_cpus,
- threads_per_socket, cores_per_socket);
+ threads_per_socket, cores_per_socket,
+ has_clusters ? "true" : "false");
}
static void check_parse(MachineState *ms, const SMPConfiguration *config,
const CpuTopology *expect_topo, const char *expect_err,
bool is_valid)
{
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
g_autofree char *config_str = smp_config_to_string(config);
g_autofree char *expect_topo_str = NULL, *output_topo_str = NULL;
unsigned int expect_threads_per_socket, expect_cores_per_socket;
@@ -453,20 +700,25 @@ static void check_parse(MachineState *ms, const SMPConfiguration *config,
cpu_topology_get_cores_per_socket(expect_topo);
expect_topo_str = cpu_topology_to_string(expect_topo,
expect_threads_per_socket,
- expect_cores_per_socket);
+ expect_cores_per_socket,
+ config->has_clusters);
/* call the generic parser */
machine_parse_smp_config(ms, config, &err);
ms_threads_per_socket = machine_topo_get_threads_per_socket(ms);
ms_cores_per_socket = machine_topo_get_cores_per_socket(ms);
- output_topo_str = cpu_topology_to_string(&ms->smp, ms_threads_per_socket,
- ms_cores_per_socket);
+ output_topo_str = cpu_topology_to_string(&ms->smp,
+ ms_threads_per_socket,
+ ms_cores_per_socket,
+ mc->smp_props.has_clusters);
/* when the configuration is supposed to be valid */
if (is_valid) {
if ((err == NULL) &&
(ms->smp.cpus == expect_topo->cpus) &&
+ (ms->smp.drawers == expect_topo->drawers) &&
+ (ms->smp.books == expect_topo->books) &&
(ms->smp.sockets == expect_topo->sockets) &&
(ms->smp.dies == expect_topo->dies) &&
(ms->smp.clusters == expect_topo->clusters) &&
@@ -474,7 +726,8 @@ static void check_parse(MachineState *ms, const SMPConfiguration *config,
(ms->smp.threads == expect_topo->threads) &&
(ms->smp.max_cpus == expect_topo->max_cpus) &&
(ms_threads_per_socket == expect_threads_per_socket) &&
- (ms_cores_per_socket == expect_cores_per_socket)) {
+ (ms_cores_per_socket == expect_cores_per_socket) &&
+ (mc->smp_props.has_clusters == config->has_clusters)) {
return;
}
@@ -558,6 +811,16 @@ static void unsupported_params_init(const MachineClass *mc, SMPTestData *data)
data->expect_prefer_sockets.clusters = 1;
data->expect_prefer_cores.clusters = 1;
}
+
+ if (!mc->smp_props.books_supported) {
+ data->expect_prefer_sockets.books = 1;
+ data->expect_prefer_cores.books = 1;
+ }
+
+ if (!mc->smp_props.drawers_supported) {
+ data->expect_prefer_sockets.drawers = 1;
+ data->expect_prefer_cores.drawers = 1;
+ }
}
static void machine_base_class_init(ObjectClass *oc, void *data)
@@ -575,8 +838,8 @@ static void machine_generic_invalid_class_init(ObjectClass *oc, void *data)
MachineClass *mc = MACHINE_CLASS(oc);
/* Force invalid min CPUs and max CPUs */
- mc->min_cpus = 2;
- mc->max_cpus = 511;
+ mc->min_cpus = MIN_CPUS + 1;
+ mc->max_cpus = MAX_CPUS - 1;
}
static void machine_with_dies_class_init(ObjectClass *oc, void *data)
@@ -593,6 +856,38 @@ static void machine_with_clusters_class_init(ObjectClass *oc, void *data)
mc->smp_props.clusters_supported = true;
}
+static void machine_with_books_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->smp_props.books_supported = true;
+}
+
+static void machine_with_drawers_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->smp_props.drawers_supported = true;
+}
+
+static void machine_with_drawers_books_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->smp_props.drawers_supported = true;
+ mc->smp_props.books_supported = true;
+}
+
+static void machine_full_topo_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->smp_props.drawers_supported = true;
+ mc->smp_props.books_supported = true;
+ mc->smp_props.dies_supported = true;
+ mc->smp_props.clusters_supported = true;
+}
+
static void test_generic_valid(const void *opaque)
{
const char *machine_type = opaque;
@@ -607,11 +902,6 @@ static void test_generic_valid(const void *opaque)
unsupported_params_init(mc, &data);
smp_parse_test(ms, &data, true);
-
- /* Unsupported parameters can be provided with their values as 1 */
- data.config.has_dies = true;
- data.config.dies = 1;
- smp_parse_test(ms, &data, true);
}
object_unref(obj);
@@ -736,6 +1026,248 @@ static void test_with_clusters(const void *opaque)
object_unref(obj);
}
+static void test_with_books(const void *opaque)
+{
+ const char *machine_type = opaque;
+ Object *obj = object_new(machine_type);
+ MachineState *ms = MACHINE(obj);
+ MachineClass *mc = MACHINE_GET_CLASS(obj);
+ SMPTestData data = {};
+ unsigned int num_books = 2;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) {
+ data = data_generic_valid[i];
+ unsupported_params_init(mc, &data);
+
+ /* when books parameter is omitted, it will be set as 1 */
+ data.expect_prefer_sockets.books = 1;
+ data.expect_prefer_cores.books = 1;
+
+ smp_parse_test(ms, &data, true);
+
+ /* when books parameter is specified */
+ data.config.has_books = true;
+ data.config.books = num_books;
+ if (data.config.has_cpus) {
+ data.config.cpus *= num_books;
+ }
+ if (data.config.has_maxcpus) {
+ data.config.maxcpus *= num_books;
+ }
+
+ data.expect_prefer_sockets.books = num_books;
+ data.expect_prefer_sockets.cpus *= num_books;
+ data.expect_prefer_sockets.max_cpus *= num_books;
+ data.expect_prefer_cores.books = num_books;
+ data.expect_prefer_cores.cpus *= num_books;
+ data.expect_prefer_cores.max_cpus *= num_books;
+
+ smp_parse_test(ms, &data, true);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data_with_books_invalid); i++) {
+ data = data_with_books_invalid[i];
+ unsupported_params_init(mc, &data);
+
+ smp_parse_test(ms, &data, false);
+ }
+
+ object_unref(obj);
+}
+
+static void test_with_drawers(const void *opaque)
+{
+ const char *machine_type = opaque;
+ Object *obj = object_new(machine_type);
+ MachineState *ms = MACHINE(obj);
+ MachineClass *mc = MACHINE_GET_CLASS(obj);
+ SMPTestData data = {};
+ unsigned int num_drawers = 2;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) {
+ data = data_generic_valid[i];
+ unsupported_params_init(mc, &data);
+
+ /* when drawers parameter is omitted, it will be set as 1 */
+ data.expect_prefer_sockets.drawers = 1;
+ data.expect_prefer_cores.drawers = 1;
+
+ smp_parse_test(ms, &data, true);
+
+ /* when drawers parameter is specified */
+ data.config.has_drawers = true;
+ data.config.drawers = num_drawers;
+ if (data.config.has_cpus) {
+ data.config.cpus *= num_drawers;
+ }
+ if (data.config.has_maxcpus) {
+ data.config.maxcpus *= num_drawers;
+ }
+
+ data.expect_prefer_sockets.drawers = num_drawers;
+ data.expect_prefer_sockets.cpus *= num_drawers;
+ data.expect_prefer_sockets.max_cpus *= num_drawers;
+ data.expect_prefer_cores.drawers = num_drawers;
+ data.expect_prefer_cores.cpus *= num_drawers;
+ data.expect_prefer_cores.max_cpus *= num_drawers;
+
+ smp_parse_test(ms, &data, true);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data_with_drawers_invalid); i++) {
+ data = data_with_drawers_invalid[i];
+ unsupported_params_init(mc, &data);
+
+ smp_parse_test(ms, &data, false);
+ }
+
+ object_unref(obj);
+}
+
+static void test_with_drawers_books(const void *opaque)
+{
+ const char *machine_type = opaque;
+ Object *obj = object_new(machine_type);
+ MachineState *ms = MACHINE(obj);
+ MachineClass *mc = MACHINE_GET_CLASS(obj);
+ SMPTestData data = {};
+ unsigned int num_drawers = 5, num_books = 3;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) {
+ data = data_generic_valid[i];
+ unsupported_params_init(mc, &data);
+
+ /*
+ * when drawers and books parameters are omitted, they will
+ * be both set as 1.
+ */
+ data.expect_prefer_sockets.drawers = 1;
+ data.expect_prefer_sockets.books = 1;
+ data.expect_prefer_cores.drawers = 1;
+ data.expect_prefer_cores.books = 1;
+
+ smp_parse_test(ms, &data, true);
+
+ /* when drawers and books parameters are both specified */
+ data.config.has_drawers = true;
+ data.config.drawers = num_drawers;
+ data.config.has_books = true;
+ data.config.books = num_books;
+
+ if (data.config.has_cpus) {
+ data.config.cpus *= num_drawers * num_books;
+ }
+ if (data.config.has_maxcpus) {
+ data.config.maxcpus *= num_drawers * num_books;
+ }
+
+ data.expect_prefer_sockets.drawers = num_drawers;
+ data.expect_prefer_sockets.books = num_books;
+ data.expect_prefer_sockets.cpus *= num_drawers * num_books;
+ data.expect_prefer_sockets.max_cpus *= num_drawers * num_books;
+
+ data.expect_prefer_cores.drawers = num_drawers;
+ data.expect_prefer_cores.books = num_books;
+ data.expect_prefer_cores.cpus *= num_drawers * num_books;
+ data.expect_prefer_cores.max_cpus *= num_drawers * num_books;
+
+ smp_parse_test(ms, &data, true);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data_with_drawers_books_invalid); i++) {
+ data = data_with_drawers_books_invalid[i];
+ unsupported_params_init(mc, &data);
+
+ smp_parse_test(ms, &data, false);
+ }
+
+ object_unref(obj);
+}
+
+static void test_full_topo(const void *opaque)
+{
+ const char *machine_type = opaque;
+ Object *obj = object_new(machine_type);
+ MachineState *ms = MACHINE(obj);
+ MachineClass *mc = MACHINE_GET_CLASS(obj);
+ SMPTestData data = {};
+ unsigned int drawers = 5, books = 3, dies = 2, clusters = 7, multiplier;
+ int i;
+
+ multiplier = drawers * books * dies * clusters;
+ for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) {
+ data = data_generic_valid[i];
+ unsupported_params_init(mc, &data);
+
+ /*
+ * when drawers, books, dies and clusters parameters are omitted,
+ * they will be set as 1.
+ */
+ data.expect_prefer_sockets.drawers = 1;
+ data.expect_prefer_sockets.books = 1;
+ data.expect_prefer_sockets.dies = 1;
+ data.expect_prefer_sockets.clusters = 1;
+ data.expect_prefer_cores.drawers = 1;
+ data.expect_prefer_cores.books = 1;
+ data.expect_prefer_cores.dies = 1;
+ data.expect_prefer_cores.clusters = 1;
+
+ smp_parse_test(ms, &data, true);
+
+ /* when drawers, books, dies and clusters parameters are specified. */
+ data.config.has_drawers = true;
+ data.config.drawers = drawers;
+ data.config.has_books = true;
+ data.config.books = books;
+ data.config.has_dies = true;
+ data.config.dies = dies;
+ data.config.has_clusters = true;
+ data.config.clusters = clusters;
+
+ if (data.config.has_cpus) {
+ data.config.cpus *= multiplier;
+ }
+ if (data.config.has_maxcpus) {
+ data.config.maxcpus *= multiplier;
+ }
+
+ data.expect_prefer_sockets.drawers = drawers;
+ data.expect_prefer_sockets.books = books;
+ data.expect_prefer_sockets.dies = dies;
+ data.expect_prefer_sockets.clusters = clusters;
+ data.expect_prefer_sockets.cpus *= multiplier;
+ data.expect_prefer_sockets.max_cpus *= multiplier;
+
+ data.expect_prefer_cores.drawers = drawers;
+ data.expect_prefer_cores.books = books;
+ data.expect_prefer_cores.dies = dies;
+ data.expect_prefer_cores.clusters = clusters;
+ data.expect_prefer_cores.cpus *= multiplier;
+ data.expect_prefer_cores.max_cpus *= multiplier;
+
+ smp_parse_test(ms, &data, true);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data_full_topo_invalid); i++) {
+ data = data_full_topo_invalid[i];
+ unsupported_params_init(mc, &data);
+
+ smp_parse_test(ms, &data, false);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data_zero_topo_invalid); i++) {
+ data = data_zero_topo_invalid[i];
+ unsupported_params_init(mc, &data);
+
+ smp_parse_test(ms, &data, false);
+ }
+
+ object_unref(obj);
+}
+
/* Type info of the tested machine */
static const TypeInfo smp_machine_types[] = {
{
@@ -760,6 +1292,22 @@ static const TypeInfo smp_machine_types[] = {
.name = MACHINE_TYPE_NAME("smp-with-clusters"),
.parent = TYPE_MACHINE,
.class_init = machine_with_clusters_class_init,
+ }, {
+ .name = MACHINE_TYPE_NAME("smp-with-books"),
+ .parent = TYPE_MACHINE,
+ .class_init = machine_with_books_class_init,
+ }, {
+ .name = MACHINE_TYPE_NAME("smp-with-drawers"),
+ .parent = TYPE_MACHINE,
+ .class_init = machine_with_drawers_class_init,
+ }, {
+ .name = MACHINE_TYPE_NAME("smp-with-drawers-books"),
+ .parent = TYPE_MACHINE,
+ .class_init = machine_with_drawers_books_class_init,
+ }, {
+ .name = MACHINE_TYPE_NAME("smp-full-topo"),
+ .parent = TYPE_MACHINE,
+ .class_init = machine_full_topo_class_init,
}
};
@@ -783,6 +1331,18 @@ int main(int argc, char *argv[])
g_test_add_data_func("/test-smp-parse/with_clusters",
MACHINE_TYPE_NAME("smp-with-clusters"),
test_with_clusters);
+ g_test_add_data_func("/test-smp-parse/with_books",
+ MACHINE_TYPE_NAME("smp-with-books"),
+ test_with_books);
+ g_test_add_data_func("/test-smp-parse/with_drawers",
+ MACHINE_TYPE_NAME("smp-with-drawers"),
+ test_with_drawers);
+ g_test_add_data_func("/test-smp-parse/with_drawers_books",
+ MACHINE_TYPE_NAME("smp-with-drawers-books"),
+ test_with_drawers_books);
+ g_test_add_data_func("/test-smp-parse/full",
+ MACHINE_TYPE_NAME("smp-full-topo"),
+ test_full_topo);
g_test_run();