mirror of https://github.com/xemu-project/xemu.git
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----- Merge tag 'hw-misc-20240309' of https://github.com/philmd/qemu into staging 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>
This commit is contained in:
commit
7489f7f3f8
|
@ -15,6 +15,7 @@
|
||||||
#include "hw/xen/xen_native.h"
|
#include "hw/xen/xen_native.h"
|
||||||
#include "hw/xen/xen-legacy-backend.h"
|
#include "hw/xen/xen-legacy-backend.h"
|
||||||
#include "hw/xen/xen_pt.h"
|
#include "hw/xen/xen_pt.h"
|
||||||
|
#include "hw/xen/xen_igd.h"
|
||||||
#include "chardev/char.h"
|
#include "chardev/char.h"
|
||||||
#include "qemu/accel.h"
|
#include "qemu/accel.h"
|
||||||
#include "sysemu/cpus.h"
|
#include "sysemu/cpus.h"
|
||||||
|
|
|
@ -36,22 +36,6 @@ and will cause a warning.
|
||||||
The replacement for the ``nodelay`` short-form boolean option is ``nodelay=on``
|
The replacement for the ``nodelay`` short-form boolean option is ``nodelay=on``
|
||||||
rather than ``delay=off``.
|
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)
|
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
|
it is not possible to change the host page size, and using the
|
||||||
option only causes failures.
|
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
|
QEMU Machine Protocol (QMP) commands
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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.
|
and given a name that better reflects what it actually does.
|
||||||
Use ``-accel tcg,one-insn-per-tb=on`` instead.
|
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
|
User-mode emulator command line arguments
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|
|
@ -223,7 +223,7 @@
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# @FirmwareFlashType:
|
# @FirmwareFlashMode:
|
||||||
#
|
#
|
||||||
# Describes how the firmware build handles code versus variable
|
# Describes how the firmware build handles code versus variable
|
||||||
# persistence.
|
# persistence.
|
||||||
|
@ -435,203 +435,203 @@
|
||||||
#
|
#
|
||||||
# Examples:
|
# Examples:
|
||||||
#
|
#
|
||||||
# {
|
# {
|
||||||
# "description": "SeaBIOS",
|
# "description": "SeaBIOS",
|
||||||
# "interface-types": [
|
# "interface-types": [
|
||||||
# "bios"
|
# "bios"
|
||||||
# ],
|
# ],
|
||||||
# "mapping": {
|
# "mapping": {
|
||||||
# "device": "memory",
|
# "device": "memory",
|
||||||
# "filename": "/usr/share/seabios/bios-256k.bin"
|
# "filename": "/usr/share/seabios/bios-256k.bin"
|
||||||
# },
|
|
||||||
# "targets": [
|
|
||||||
# {
|
|
||||||
# "architecture": "i386",
|
|
||||||
# "machines": [
|
|
||||||
# "pc-i440fx-*",
|
|
||||||
# "pc-q35-*"
|
|
||||||
# ]
|
|
||||||
# },
|
# },
|
||||||
# {
|
# "targets": [
|
||||||
# "architecture": "x86_64",
|
# {
|
||||||
# "machines": [
|
# "architecture": "i386",
|
||||||
# "pc-i440fx-*",
|
# "machines": [
|
||||||
# "pc-q35-*"
|
# "pc-i440fx-*",
|
||||||
# ]
|
# "pc-q35-*"
|
||||||
# }
|
# ]
|
||||||
# ],
|
# },
|
||||||
# "features": [
|
# {
|
||||||
# "acpi-s3",
|
# "architecture": "x86_64",
|
||||||
# "acpi-s4"
|
# "machines": [
|
||||||
# ],
|
# "pc-i440fx-*",
|
||||||
# "tags": [
|
# "pc-q35-*"
|
||||||
# "CONFIG_BOOTSPLASH=n",
|
# ]
|
||||||
# "CONFIG_ROM_SIZE=256",
|
# }
|
||||||
# "CONFIG_USE_SMM=n"
|
# ],
|
||||||
# ]
|
# "features": [
|
||||||
# }
|
# "acpi-s3",
|
||||||
|
# "acpi-s4"
|
||||||
|
# ],
|
||||||
|
# "tags": [
|
||||||
|
# "CONFIG_BOOTSPLASH=n",
|
||||||
|
# "CONFIG_ROM_SIZE=256",
|
||||||
|
# "CONFIG_USE_SMM=n"
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
#
|
#
|
||||||
# {
|
# {
|
||||||
# "description": "OVMF with SB+SMM, empty varstore",
|
# "description": "OVMF with SB+SMM, empty varstore",
|
||||||
# "interface-types": [
|
# "interface-types": [
|
||||||
# "uefi"
|
# "uefi"
|
||||||
# ],
|
# ],
|
||||||
# "mapping": {
|
# "mapping": {
|
||||||
# "device": "flash",
|
# "device": "flash",
|
||||||
# "executable": {
|
# "executable": {
|
||||||
# "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
|
# "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
|
||||||
# "format": "raw"
|
# "format": "raw"
|
||||||
|
# },
|
||||||
|
# "nvram-template": {
|
||||||
|
# "filename": "/usr/share/OVMF/OVMF_VARS.fd",
|
||||||
|
# "format": "raw"
|
||||||
|
# }
|
||||||
# },
|
# },
|
||||||
# "nvram-template": {
|
# "targets": [
|
||||||
# "filename": "/usr/share/OVMF/OVMF_VARS.fd",
|
# {
|
||||||
# "format": "raw"
|
# "architecture": "x86_64",
|
||||||
# }
|
# "machines": [
|
||||||
# },
|
# "pc-q35-*"
|
||||||
# "targets": [
|
# ]
|
||||||
# {
|
# }
|
||||||
# "architecture": "x86_64",
|
# ],
|
||||||
# "machines": [
|
# "features": [
|
||||||
# "pc-q35-*"
|
# "acpi-s3",
|
||||||
# ]
|
# "amd-sev",
|
||||||
# }
|
# "requires-smm",
|
||||||
# ],
|
# "secure-boot",
|
||||||
# "features": [
|
# "verbose-dynamic"
|
||||||
# "acpi-s3",
|
# ],
|
||||||
# "amd-sev",
|
# "tags": [
|
||||||
# "requires-smm",
|
# "-a IA32",
|
||||||
# "secure-boot",
|
# "-a X64",
|
||||||
# "verbose-dynamic"
|
# "-p OvmfPkg/OvmfPkgIa32X64.dsc",
|
||||||
# ],
|
# "-t GCC48",
|
||||||
# "tags": [
|
# "-b DEBUG",
|
||||||
# "-a IA32",
|
# "-D SMM_REQUIRE",
|
||||||
# "-a X64",
|
# "-D SECURE_BOOT_ENABLE",
|
||||||
# "-p OvmfPkg/OvmfPkgIa32X64.dsc",
|
# "-D FD_SIZE_4MB"
|
||||||
# "-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",
|
# "description": "OVMF with SB+SMM, SB enabled, MS certs enrolled",
|
||||||
# "interface-types": [
|
# "interface-types": [
|
||||||
# "uefi"
|
# "uefi"
|
||||||
# ],
|
# ],
|
||||||
# "mapping": {
|
# "mapping": {
|
||||||
# "device": "flash",
|
# "device": "flash",
|
||||||
# "executable": {
|
# "executable": {
|
||||||
# "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
|
# "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
|
||||||
# "format": "raw"
|
# "format": "raw"
|
||||||
|
# },
|
||||||
|
# "nvram-template": {
|
||||||
|
# "filename": "/usr/share/OVMF/OVMF_VARS.secboot.fd",
|
||||||
|
# "format": "raw"
|
||||||
|
# }
|
||||||
# },
|
# },
|
||||||
# "nvram-template": {
|
# "targets": [
|
||||||
# "filename": "/usr/share/OVMF/OVMF_VARS.secboot.fd",
|
# {
|
||||||
# "format": "raw"
|
# "architecture": "x86_64",
|
||||||
# }
|
# "machines": [
|
||||||
# },
|
# "pc-q35-*"
|
||||||
# "targets": [
|
# ]
|
||||||
# {
|
# }
|
||||||
# "architecture": "x86_64",
|
# ],
|
||||||
# "machines": [
|
# "features": [
|
||||||
# "pc-q35-*"
|
# "acpi-s3",
|
||||||
# ]
|
# "amd-sev",
|
||||||
# }
|
# "enrolled-keys",
|
||||||
# ],
|
# "requires-smm",
|
||||||
# "features": [
|
# "secure-boot",
|
||||||
# "acpi-s3",
|
# "verbose-dynamic"
|
||||||
# "amd-sev",
|
# ],
|
||||||
# "enrolled-keys",
|
# "tags": [
|
||||||
# "requires-smm",
|
# "-a IA32",
|
||||||
# "secure-boot",
|
# "-a X64",
|
||||||
# "verbose-dynamic"
|
# "-p OvmfPkg/OvmfPkgIa32X64.dsc",
|
||||||
# ],
|
# "-t GCC48",
|
||||||
# "tags": [
|
# "-b DEBUG",
|
||||||
# "-a IA32",
|
# "-D SMM_REQUIRE",
|
||||||
# "-a X64",
|
# "-D SECURE_BOOT_ENABLE",
|
||||||
# "-p OvmfPkg/OvmfPkgIa32X64.dsc",
|
# "-D FD_SIZE_4MB"
|
||||||
# "-t GCC48",
|
# ]
|
||||||
# "-b DEBUG",
|
# }
|
||||||
# "-D SMM_REQUIRE",
|
|
||||||
# "-D SECURE_BOOT_ENABLE",
|
|
||||||
# "-D FD_SIZE_4MB"
|
|
||||||
# ]
|
|
||||||
# }
|
|
||||||
#
|
#
|
||||||
# {
|
# {
|
||||||
# "description": "OVMF with SEV-ES support",
|
# "description": "OVMF with SEV-ES support",
|
||||||
# "interface-types": [
|
# "interface-types": [
|
||||||
# "uefi"
|
# "uefi"
|
||||||
# ],
|
# ],
|
||||||
# "mapping": {
|
# "mapping": {
|
||||||
# "device": "flash",
|
# "device": "flash",
|
||||||
# "executable": {
|
# "executable": {
|
||||||
# "filename": "/usr/share/OVMF/OVMF_CODE.fd",
|
# "filename": "/usr/share/OVMF/OVMF_CODE.fd",
|
||||||
# "format": "raw"
|
# "format": "raw"
|
||||||
|
# },
|
||||||
|
# "nvram-template": {
|
||||||
|
# "filename": "/usr/share/OVMF/OVMF_VARS.fd",
|
||||||
|
# "format": "raw"
|
||||||
|
# }
|
||||||
# },
|
# },
|
||||||
# "nvram-template": {
|
# "targets": [
|
||||||
# "filename": "/usr/share/OVMF/OVMF_VARS.fd",
|
# {
|
||||||
# "format": "raw"
|
# "architecture": "x86_64",
|
||||||
# }
|
# "machines": [
|
||||||
# },
|
# "pc-q35-*"
|
||||||
# "targets": [
|
# ]
|
||||||
# {
|
# }
|
||||||
# "architecture": "x86_64",
|
# ],
|
||||||
# "machines": [
|
# "features": [
|
||||||
# "pc-q35-*"
|
# "acpi-s3",
|
||||||
# ]
|
# "amd-sev",
|
||||||
# }
|
# "amd-sev-es",
|
||||||
# ],
|
# "verbose-dynamic"
|
||||||
# "features": [
|
# ],
|
||||||
# "acpi-s3",
|
# "tags": [
|
||||||
# "amd-sev",
|
# "-a X64",
|
||||||
# "amd-sev-es",
|
# "-p OvmfPkg/OvmfPkgX64.dsc",
|
||||||
# "verbose-dynamic"
|
# "-t GCC48",
|
||||||
# ],
|
# "-b DEBUG",
|
||||||
# "tags": [
|
# "-D FD_SIZE_4MB"
|
||||||
# "-a X64",
|
# ]
|
||||||
# "-p OvmfPkg/OvmfPkgX64.dsc",
|
# }
|
||||||
# "-t GCC48",
|
|
||||||
# "-b DEBUG",
|
|
||||||
# "-D FD_SIZE_4MB"
|
|
||||||
# ]
|
|
||||||
# }
|
|
||||||
#
|
#
|
||||||
# {
|
# {
|
||||||
# "description": "UEFI firmware for ARM64 virtual machines",
|
# "description": "UEFI firmware for ARM64 virtual machines",
|
||||||
# "interface-types": [
|
# "interface-types": [
|
||||||
# "uefi"
|
# "uefi"
|
||||||
# ],
|
# ],
|
||||||
# "mapping": {
|
# "mapping": {
|
||||||
# "device": "flash",
|
# "device": "flash",
|
||||||
# "executable": {
|
# "executable": {
|
||||||
# "filename": "/usr/share/AAVMF/AAVMF_CODE.fd",
|
# "filename": "/usr/share/AAVMF/AAVMF_CODE.fd",
|
||||||
# "format": "raw"
|
# "format": "raw"
|
||||||
|
# },
|
||||||
|
# "nvram-template": {
|
||||||
|
# "filename": "/usr/share/AAVMF/AAVMF_VARS.fd",
|
||||||
|
# "format": "raw"
|
||||||
|
# }
|
||||||
# },
|
# },
|
||||||
# "nvram-template": {
|
# "targets": [
|
||||||
# "filename": "/usr/share/AAVMF/AAVMF_VARS.fd",
|
# {
|
||||||
# "format": "raw"
|
# "architecture": "aarch64",
|
||||||
# }
|
# "machines": [
|
||||||
# },
|
# "virt-*"
|
||||||
# "targets": [
|
# ]
|
||||||
# {
|
# }
|
||||||
# "architecture": "aarch64",
|
# ],
|
||||||
# "machines": [
|
# "features": [
|
||||||
# "virt-*"
|
|
||||||
# ]
|
|
||||||
# }
|
|
||||||
# ],
|
|
||||||
# "features": [
|
|
||||||
#
|
#
|
||||||
# ],
|
# ],
|
||||||
# "tags": [
|
# "tags": [
|
||||||
# "-a AARCH64",
|
# "-a AARCH64",
|
||||||
# "-p ArmVirtPkg/ArmVirtQemu.dsc",
|
# "-p ArmVirtPkg/ArmVirtQemu.dsc",
|
||||||
# "-t GCC48",
|
# "-t GCC48",
|
||||||
# "-b DEBUG",
|
# "-b DEBUG",
|
||||||
# "-D DEBUG_PRINT_ERROR_LEVEL=0x80000000"
|
# "-D DEBUG_PRINT_ERROR_LEVEL=0x80000000"
|
||||||
# ]
|
# ]
|
||||||
# }
|
# }
|
||||||
##
|
##
|
||||||
{ 'struct' : 'Firmware',
|
{ 'struct' : 'Firmware',
|
||||||
'data' : { 'description' : 'str',
|
'data' : { 'description' : 'str',
|
||||||
|
|
|
@ -540,9 +540,9 @@ ERST
|
||||||
|
|
||||||
{
|
{
|
||||||
.name = "qtree",
|
.name = "qtree",
|
||||||
.args_type = "",
|
.args_type = "brief:-b",
|
||||||
.params = "",
|
.params = "[-b]",
|
||||||
.help = "show device tree",
|
.help = "show device tree (-b: brief, omit properties)",
|
||||||
.cmd = hmp_info_qtree,
|
.cmd = hmp_info_qtree,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -114,14 +114,14 @@ static void xen_init_ram(MachineState *machine)
|
||||||
block_len = GUEST_RAM1_BASE + ram_size[1];
|
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);
|
&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]);
|
GUEST_RAM0_BASE, ram_size[0]);
|
||||||
memory_region_add_subregion(sysmem, GUEST_RAM0_BASE, &ram_lo);
|
memory_region_add_subregion(sysmem, GUEST_RAM0_BASE, &ram_lo);
|
||||||
if (ram_size[1] > 0) {
|
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]);
|
GUEST_RAM1_BASE, ram_size[1]);
|
||||||
memory_region_add_subregion(sysmem, GUEST_RAM1_BASE, &ram_hi);
|
memory_region_add_subregion(sysmem, GUEST_RAM1_BASE, &ram_hi);
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,6 +206,7 @@ static bool con_event(void *_xendev)
|
||||||
|
|
||||||
static bool xen_console_connect(XenDevice *xendev, Error **errp)
|
static bool xen_console_connect(XenDevice *xendev, Error **errp)
|
||||||
{
|
{
|
||||||
|
ERRP_GUARD();
|
||||||
XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
|
XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
|
||||||
unsigned int port, limit;
|
unsigned int port, limit;
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,7 @@ void machine_parse_smp_config(MachineState *ms,
|
||||||
unsigned cores = config->has_cores ? config->cores : 0;
|
unsigned cores = config->has_cores ? config->cores : 0;
|
||||||
unsigned threads = config->has_threads ? config->threads : 0;
|
unsigned threads = config->has_threads ? config->threads : 0;
|
||||||
unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
|
unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
|
||||||
|
unsigned total_cpus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Specified CPU topology parameters must be greater than zero,
|
* 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_cores && config->cores == 0) ||
|
||||||
(config->has_threads && config->threads == 0) ||
|
(config->has_threads && config->threads == 0) ||
|
||||||
(config->has_maxcpus && config->maxcpus == 0)) {
|
(config->has_maxcpus && config->maxcpus == 0)) {
|
||||||
warn_report("Deprecated CPU topology (considered invalid): "
|
error_setg(errp, "Invalid CPU topology: "
|
||||||
"CPU topology parameters must be greater than zero");
|
"CPU topology parameters must be greater than zero");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If not supported by the machine, a topology parameter must be
|
* 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) {
|
if (!mc->smp_props.clusters_supported && config->has_clusters) {
|
||||||
error_setg(errp, "dies not supported by this machine's CPU topology");
|
if (config->clusters > 1) {
|
||||||
return;
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!mc->smp_props.clusters_supported && clusters > 1) {
|
|
||||||
error_setg(errp, "clusters not supported by this machine's CPU topology");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dies = dies > 0 ? dies : 1;
|
|
||||||
clusters = clusters > 0 ? clusters : 1;
|
clusters = clusters > 0 ? clusters : 1;
|
||||||
|
|
||||||
if (!mc->smp_props.books_supported && books > 1) {
|
if (!mc->smp_props.dies_supported && config->has_dies) {
|
||||||
error_setg(errp, "books not supported by this machine's CPU topology");
|
if (config->dies > 1) {
|
||||||
return;
|
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;
|
||||||
|
|
||||||
|
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;
|
books = books > 0 ? books : 1;
|
||||||
|
|
||||||
if (!mc->smp_props.drawers_supported && drawers > 1) {
|
if (!mc->smp_props.drawers_supported && config->has_drawers) {
|
||||||
error_setg(errp,
|
if (config->drawers > 1) {
|
||||||
"drawers not supported by this machine's CPU topology");
|
error_setg(errp, "drawers not supported by this "
|
||||||
return;
|
"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;
|
drawers = drawers > 0 ? drawers : 1;
|
||||||
|
|
||||||
|
@ -179,8 +212,8 @@ void machine_parse_smp_config(MachineState *ms,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
maxcpus = maxcpus > 0 ? maxcpus : drawers * books * sockets * dies *
|
total_cpus = drawers * books * sockets * dies * clusters * cores * threads;
|
||||||
clusters * cores * threads;
|
maxcpus = maxcpus > 0 ? maxcpus : total_cpus;
|
||||||
cpus = cpus > 0 ? cpus : maxcpus;
|
cpus = cpus > 0 ? cpus : maxcpus;
|
||||||
|
|
||||||
ms->smp.cpus = cpus;
|
ms->smp.cpus = cpus;
|
||||||
|
@ -196,8 +229,7 @@ void machine_parse_smp_config(MachineState *ms,
|
||||||
mc->smp_props.has_clusters = config->has_clusters;
|
mc->smp_props.has_clusters = config->has_clusters;
|
||||||
|
|
||||||
/* sanity-check of the computed topology */
|
/* sanity-check of the computed topology */
|
||||||
if (drawers * books * sockets * dies * clusters * cores * threads !=
|
if (total_cpus != maxcpus) {
|
||||||
maxcpus) {
|
|
||||||
g_autofree char *topo_msg = cpu_hierarchy_to_string(ms);
|
g_autofree char *topo_msg = cpu_hierarchy_to_string(ms);
|
||||||
error_setg(errp, "Invalid CPU topology: "
|
error_setg(errp, "Invalid CPU topology: "
|
||||||
"product of the hierarchy must match maxcpus: "
|
"product of the hierarchy must match maxcpus: "
|
||||||
|
|
|
@ -679,6 +679,20 @@ const PropertyInfo qdev_prop_mig_mode = {
|
||||||
.set_default_value = qdev_propinfo_set_default_value_enum,
|
.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 --- */
|
/* --- Reserved Region --- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
i386_ss = ss.source_set()
|
i386_ss = ss.source_set()
|
||||||
i386_ss.add(files(
|
i386_ss.add(files(
|
||||||
'fw_cfg.c',
|
'fw_cfg.c',
|
||||||
'kvmvapic.c',
|
'vapic.c',
|
||||||
'e820_memory_layout.c',
|
'e820_memory_layout.c',
|
||||||
'multiboot.c',
|
'multiboot.c',
|
||||||
'x86.c',
|
'x86.c',
|
||||||
|
|
|
@ -55,11 +55,13 @@
|
||||||
#ifdef CONFIG_XEN
|
#ifdef CONFIG_XEN
|
||||||
#include <xen/hvm/hvm_info_table.h>
|
#include <xen/hvm/hvm_info_table.h>
|
||||||
#include "hw/xen/xen_pt.h"
|
#include "hw/xen/xen_pt.h"
|
||||||
|
#include "hw/xen/xen_igd.h"
|
||||||
#endif
|
#endif
|
||||||
#include "hw/xen/xen-x86.h"
|
#include "hw/xen/xen-x86.h"
|
||||||
#include "hw/xen/xen.h"
|
#include "hw/xen/xen.h"
|
||||||
#include "migration/global_state.h"
|
#include "migration/global_state.h"
|
||||||
#include "migration/misc.h"
|
#include "migration/misc.h"
|
||||||
|
#include "sysemu/runstate.h"
|
||||||
#include "sysemu/numa.h"
|
#include "sysemu/numa.h"
|
||||||
#include "hw/hyperv/vmbus-bridge.h"
|
#include "hw/hyperv/vmbus-bridge.h"
|
||||||
#include "hw/mem/nvdimm.h"
|
#include "hw/mem/nvdimm.h"
|
||||||
|
@ -99,8 +101,7 @@ static void piix_intx_routing_notifier_xen(PCIDevice *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PC hardware initialisation */
|
/* PC hardware initialisation */
|
||||||
static void pc_init1(MachineState *machine,
|
static void pc_init1(MachineState *machine, const char *pci_type)
|
||||||
const char *host_type, const char *pci_type)
|
|
||||||
{
|
{
|
||||||
PCMachineState *pcms = PC_MACHINE(machine);
|
PCMachineState *pcms = PC_MACHINE(machine);
|
||||||
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
|
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);
|
memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
|
||||||
rom_memory = pci_memory;
|
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_add_child(OBJECT(machine), "i440fx", phb);
|
||||||
object_property_set_link(phb, PCI_HOST_PROP_RAM_MEM,
|
object_property_set_link(phb, PCI_HOST_PROP_RAM_MEM,
|
||||||
OBJECT(ram_memory), &error_fatal);
|
OBJECT(ram_memory), &error_fatal);
|
||||||
|
@ -382,9 +383,6 @@ static const QEnumLookup PCSouthBridgeOption_lookup = {
|
||||||
.size = PC_SOUTH_BRIDGE_OPTION_MAX
|
.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)
|
static int pc_get_south_bridge(Object *obj, Error **errp)
|
||||||
{
|
{
|
||||||
PCMachineState *pcms = PC_MACHINE(obj);
|
PCMachineState *pcms = PC_MACHINE(obj);
|
||||||
|
@ -452,7 +450,7 @@ static void pc_compat_2_0_fn(MachineState *machine)
|
||||||
#ifdef CONFIG_ISAPC
|
#ifdef CONFIG_ISAPC
|
||||||
static void pc_init_isa(MachineState *machine)
|
static void pc_init_isa(MachineState *machine)
|
||||||
{
|
{
|
||||||
pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
|
pc_init1(machine, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -462,9 +460,7 @@ static void pc_xen_hvm_init_pci(MachineState *machine)
|
||||||
const char *pci_type = xen_igd_gfx_pt_enabled() ?
|
const char *pci_type = xen_igd_gfx_pt_enabled() ?
|
||||||
TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE : TYPE_I440FX_PCI_DEVICE;
|
TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE : TYPE_I440FX_PCI_DEVICE;
|
||||||
|
|
||||||
pc_init1(machine,
|
pc_init1(machine, pci_type);
|
||||||
TYPE_I440FX_PCI_HOST_BRIDGE,
|
|
||||||
pci_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pc_xen_hvm_init(MachineState *machine)
|
static void pc_xen_hvm_init(MachineState *machine)
|
||||||
|
@ -489,8 +485,7 @@ static void pc_xen_hvm_init(MachineState *machine)
|
||||||
if (compat) { \
|
if (compat) { \
|
||||||
compat(machine); \
|
compat(machine); \
|
||||||
} \
|
} \
|
||||||
pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
|
pc_init1(machine, TYPE_I440FX_PCI_DEVICE); \
|
||||||
TYPE_I440FX_PCI_DEVICE); \
|
|
||||||
} \
|
} \
|
||||||
DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
|
DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
|
||||||
|
|
||||||
|
|
|
@ -747,8 +747,7 @@ static void do_vapic_enable(CPUState *cs, run_on_cpu_data data)
|
||||||
s->state = VAPIC_ACTIVE;
|
s->state = VAPIC_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvmvapic_vm_state_change(void *opaque, bool running,
|
static void vapic_vm_state_change(void *opaque, bool running, RunState state)
|
||||||
RunState state)
|
|
||||||
{
|
{
|
||||||
MachineState *ms = MACHINE(qdev_get_machine());
|
MachineState *ms = MACHINE(qdev_get_machine());
|
||||||
VAPICROMState *s = opaque;
|
VAPICROMState *s = opaque;
|
||||||
|
@ -793,7 +792,7 @@ static int vapic_post_load(void *opaque, int version_id)
|
||||||
|
|
||||||
if (!s->vmsentry) {
|
if (!s->vmsentry) {
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
i386_ss.add(when: 'CONFIG_XEN', if_true: files(
|
i386_ss.add(when: 'CONFIG_XEN', if_true: files(
|
||||||
'xen-hvm.c',
|
|
||||||
'xen_apic.c',
|
'xen_apic.c',
|
||||||
'xen_pvdevice.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(
|
i386_ss.add(when: 'CONFIG_XEN_BUS', if_true: files(
|
||||||
'xen_platform.c',
|
'xen_platform.c',
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "hw/xen/xen-hvm-common.h"
|
#include "hw/xen/xen-hvm-common.h"
|
||||||
#include "hw/xen/arch_hvm.h"
|
#include "hw/xen/arch_hvm.h"
|
||||||
#include <xen/hvm/e820.h>
|
#include <xen/hvm/e820.h>
|
||||||
|
#include "exec/target_page.h"
|
||||||
|
|
||||||
static MemoryRegion ram_640k, ram_lo, ram_hi;
|
static MemoryRegion ram_640k, ram_lo, ram_hi;
|
||||||
static MemoryRegion *framebuffer;
|
static MemoryRegion *framebuffer;
|
||||||
|
@ -149,12 +150,12 @@ static void xen_ram_init(PCMachineState *pcms,
|
||||||
*/
|
*/
|
||||||
block_len = (4 * GiB) + x86ms->above_4g_mem_size;
|
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);
|
&error_fatal);
|
||||||
*ram_memory_p = &ram_memory;
|
*ram_memory_p = &xen_memory;
|
||||||
|
|
||||||
memory_region_init_alias(&ram_640k, NULL, "xen.ram.640k",
|
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);
|
memory_region_add_subregion(sysmem, 0, &ram_640k);
|
||||||
/* Skip of the VGA IO memory space, it will be registered later by the VGA
|
/* Skip of the VGA IO memory space, it will be registered later by the VGA
|
||||||
* emulated device.
|
* emulated device.
|
||||||
|
@ -163,22 +164,23 @@ static void xen_ram_init(PCMachineState *pcms,
|
||||||
* the Options ROM, so it is registered here as RAM.
|
* the Options ROM, so it is registered here as RAM.
|
||||||
*/
|
*/
|
||||||
memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo",
|
memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo",
|
||||||
&ram_memory, 0xc0000,
|
&xen_memory, 0xc0000,
|
||||||
x86ms->below_4g_mem_size - 0xc0000);
|
x86ms->below_4g_mem_size - 0xc0000);
|
||||||
memory_region_add_subregion(sysmem, 0xc0000, &ram_lo);
|
memory_region_add_subregion(sysmem, 0xc0000, &ram_lo);
|
||||||
if (x86ms->above_4g_mem_size > 0) {
|
if (x86ms->above_4g_mem_size > 0) {
|
||||||
memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi",
|
memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi",
|
||||||
&ram_memory, 0x100000000ULL,
|
&xen_memory, 0x100000000ULL,
|
||||||
x86ms->above_4g_mem_size);
|
x86ms->above_4g_mem_size);
|
||||||
memory_region_add_subregion(sysmem, 0x100000000ULL, &ram_hi);
|
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;
|
XenPhysmap *physmap = NULL;
|
||||||
|
|
||||||
start_addr &= TARGET_PAGE_MASK;
|
start_addr &= page_mask;
|
||||||
|
|
||||||
QLIST_FOREACH(physmap, &xen_physmap, list) {
|
QLIST_FOREACH(physmap, &xen_physmap, list) {
|
||||||
if (range_covers_byte(physmap->start_addr, physmap->size, start_addr)) {
|
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;
|
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;
|
XenPhysmap *physmap = NULL;
|
||||||
|
|
||||||
QLIST_FOREACH(physmap, &xen_physmap, list) {
|
QLIST_FOREACH(physmap, &xen_physmap, list) {
|
||||||
|
@ -245,6 +248,9 @@ static int xen_add_to_physmap(XenIOState *state,
|
||||||
MemoryRegion *mr,
|
MemoryRegion *mr,
|
||||||
hwaddr offset_within_region)
|
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;
|
unsigned long nr_pages;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
XenPhysmap *physmap = NULL;
|
XenPhysmap *physmap = NULL;
|
||||||
|
@ -252,7 +258,7 @@ static int xen_add_to_physmap(XenIOState *state,
|
||||||
hwaddr phys_offset = memory_region_get_ram_addr(mr);
|
hwaddr phys_offset = memory_region_get_ram_addr(mr);
|
||||||
const char *mr_name;
|
const char *mr_name;
|
||||||
|
|
||||||
if (get_physmapping(start_addr, size)) {
|
if (get_physmapping(start_addr, size, page_mask)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
|
@ -292,9 +298,9 @@ go_physmap:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pfn = phys_offset >> TARGET_PAGE_BITS;
|
pfn = phys_offset >> target_page_bits;
|
||||||
start_gpfn = start_addr >> TARGET_PAGE_BITS;
|
start_gpfn = start_addr >> target_page_bits;
|
||||||
nr_pages = size >> TARGET_PAGE_BITS;
|
nr_pages = size >> target_page_bits;
|
||||||
rc = xendevicemodel_relocate_memory(xen_dmod, xen_domid, nr_pages, pfn,
|
rc = xendevicemodel_relocate_memory(xen_dmod, xen_domid, nr_pages, pfn,
|
||||||
start_gpfn);
|
start_gpfn);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -308,8 +314,8 @@ go_physmap:
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = xendevicemodel_pin_memory_cacheattr(xen_dmod, xen_domid,
|
rc = xendevicemodel_pin_memory_cacheattr(xen_dmod, xen_domid,
|
||||||
start_addr >> TARGET_PAGE_BITS,
|
start_addr >> target_page_bits,
|
||||||
(start_addr + size - 1) >> TARGET_PAGE_BITS,
|
(start_addr + size - 1) >> target_page_bits,
|
||||||
XEN_DOMCTL_MEM_CACHEATTR_WB);
|
XEN_DOMCTL_MEM_CACHEATTR_WB);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
error_report("pin_memory_cacheattr failed: %s", strerror(errno));
|
error_report("pin_memory_cacheattr failed: %s", strerror(errno));
|
||||||
|
@ -321,11 +327,14 @@ static int xen_remove_from_physmap(XenIOState *state,
|
||||||
hwaddr start_addr,
|
hwaddr start_addr,
|
||||||
ram_addr_t size)
|
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;
|
int rc = 0;
|
||||||
XenPhysmap *physmap = NULL;
|
XenPhysmap *physmap = NULL;
|
||||||
hwaddr phys_offset = 0;
|
hwaddr phys_offset = 0;
|
||||||
|
|
||||||
physmap = get_physmapping(start_addr, size);
|
physmap = get_physmapping(start_addr, size, page_mask);
|
||||||
if (physmap == NULL) {
|
if (physmap == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -336,9 +345,9 @@ static int xen_remove_from_physmap(XenIOState *state,
|
||||||
DPRINTF("unmapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx", at "
|
DPRINTF("unmapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx", at "
|
||||||
"%"HWADDR_PRIx"\n", start_addr, start_addr + size, phys_offset);
|
"%"HWADDR_PRIx"\n", start_addr, start_addr + size, phys_offset);
|
||||||
|
|
||||||
size >>= TARGET_PAGE_BITS;
|
size >>= target_page_bits;
|
||||||
start_addr >>= TARGET_PAGE_BITS;
|
start_addr >>= target_page_bits;
|
||||||
phys_offset >>= TARGET_PAGE_BITS;
|
phys_offset >>= target_page_bits;
|
||||||
rc = xendevicemodel_relocate_memory(xen_dmod, xen_domid, size, start_addr,
|
rc = xendevicemodel_relocate_memory(xen_dmod, xen_domid, size, start_addr,
|
||||||
phys_offset);
|
phys_offset);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -367,13 +376,16 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
|
||||||
hwaddr start_addr,
|
hwaddr start_addr,
|
||||||
ram_addr_t size)
|
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;
|
const int width = sizeof(unsigned long) * 8;
|
||||||
size_t bitmap_size = DIV_ROUND_UP(npages, width);
|
size_t bitmap_size = DIV_ROUND_UP(npages, width);
|
||||||
int rc, i, j;
|
int rc, i, j;
|
||||||
const XenPhysmap *physmap = NULL;
|
const XenPhysmap *physmap = NULL;
|
||||||
|
|
||||||
physmap = get_physmapping(start_addr, size);
|
physmap = get_physmapping(start_addr, size, page_mask);
|
||||||
if (physmap == NULL) {
|
if (physmap == NULL) {
|
||||||
/* not handled */
|
/* not handled */
|
||||||
return;
|
return;
|
||||||
|
@ -387,7 +399,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
|
||||||
return;
|
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);
|
npages, dirty_bitmap);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
#ifndef ENODATA
|
#ifndef ENODATA
|
||||||
|
@ -408,8 +420,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
|
||||||
j = ctzl(map);
|
j = ctzl(map);
|
||||||
map &= ~(1ul << j);
|
map &= ~(1ul << j);
|
||||||
memory_region_set_dirty(framebuffer,
|
memory_region_set_dirty(framebuffer,
|
||||||
(i * width + j) * TARGET_PAGE_SIZE,
|
(i * width + j) * page_size, page_size);
|
||||||
TARGET_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)
|
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)) {
|
if (unlikely(xen_in_migration)) {
|
||||||
int rc;
|
int rc;
|
||||||
ram_addr_t start_pfn, nb_pages;
|
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) {
|
if (length == 0) {
|
||||||
length = TARGET_PAGE_SIZE;
|
length = page_size;
|
||||||
}
|
}
|
||||||
start_pfn = start >> TARGET_PAGE_BITS;
|
start_pfn = start >> target_page_bits;
|
||||||
nb_pages = ((start + length + TARGET_PAGE_SIZE - 1) >> TARGET_PAGE_BITS)
|
nb_pages = ((start + length + page_size - 1) >> target_page_bits)
|
||||||
- start_pfn;
|
- start_pfn;
|
||||||
rc = xen_modified_memory(xen_domid, start_pfn, nb_pages);
|
rc = xen_modified_memory(xen_domid, start_pfn, nb_pages);
|
||||||
if (rc) {
|
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,
|
void arch_xen_set_memory(XenIOState *state, MemoryRegionSection *section,
|
||||||
bool add)
|
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;
|
hwaddr start_addr = section->offset_within_address_space;
|
||||||
ram_addr_t size = int128_get64(section->size);
|
ram_addr_t size = int128_get64(section->size);
|
||||||
bool log_dirty = memory_region_is_logging(section->mr, DIRTY_MEMORY_VGA);
|
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);
|
trace_xen_client_set_memory(start_addr, size, log_dirty);
|
||||||
|
|
||||||
start_addr &= TARGET_PAGE_MASK;
|
start_addr &= page_mask;
|
||||||
size = TARGET_PAGE_ALIGN(size);
|
size = ROUND_UP(size, page_size);
|
||||||
|
|
||||||
if (add) {
|
if (add) {
|
||||||
if (!memory_region_is_rom(section->mr)) {
|
if (!memory_region_is_rom(section->mr)) {
|
||||||
|
@ -687,8 +705,8 @@ void arch_xen_set_memory(XenIOState *state, MemoryRegionSection *section,
|
||||||
} else {
|
} else {
|
||||||
mem_type = HVMMEM_ram_ro;
|
mem_type = HVMMEM_ram_ro;
|
||||||
if (xen_set_mem_type(xen_domid, mem_type,
|
if (xen_set_mem_type(xen_domid, mem_type,
|
||||||
start_addr >> TARGET_PAGE_BITS,
|
start_addr >> target_page_bits,
|
||||||
size >> TARGET_PAGE_BITS)) {
|
size >> target_page_bits)) {
|
||||||
DPRINTF("xen_set_mem_type error, addr: "HWADDR_FMT_plx"\n",
|
DPRINTF("xen_set_mem_type error, addr: "HWADDR_FMT_plx"\n",
|
||||||
start_addr);
|
start_addr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,6 +356,7 @@ static void grlib_irqmp_realize(DeviceState *dev, Error **errp)
|
||||||
error_setg(errp, "Invalid ncpus properties: "
|
error_setg(errp, "Invalid ncpus properties: "
|
||||||
"%u, must be 0 < ncpus =< %u.", irqmp->ncpus,
|
"%u, must be 0 < ncpus =< %u.", irqmp->ncpus,
|
||||||
IRQMP_MAX_CPU);
|
IRQMP_MAX_CPU);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdev_init_gpio_in(dev, grlib_irqmp_set_irq, MAX_PILS);
|
qdev_init_gpio_in(dev, grlib_irqmp_set_irq, MAX_PILS);
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#define PCSR_PRE_SHIFT 8
|
#define PCSR_PRE_SHIFT 8
|
||||||
#define PCSR_PRE_MASK 0x0f00
|
#define PCSR_PRE_MASK 0x0f00
|
||||||
|
|
||||||
|
#define RCR_SOFTRST 0x80
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
MemoryRegion iomem;
|
MemoryRegion iomem;
|
||||||
qemu_irq irq;
|
qemu_irq irq;
|
||||||
|
@ -185,12 +187,50 @@ static const MemoryRegionOps m5208_sys_ops = {
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
.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 = g_new(MemoryRegion, 1);
|
||||||
|
MemoryRegion *iomem_rcm = g_new(MemoryRegion, 1);
|
||||||
m5208_timer_state *s;
|
m5208_timer_state *s;
|
||||||
int i;
|
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. */
|
/* SDRAMC. */
|
||||||
memory_region_init_io(iomem, NULL, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000);
|
memory_region_init_io(iomem, NULL, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000);
|
||||||
memory_region_add_subregion(address_space, 0xfc0a8000, iomem);
|
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(0xfc064000, pic[27], serial_hd(1));
|
||||||
mcf_uart_create_mmap(0xfc068000, pic[28], serial_hd(2));
|
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);
|
mcf_fec_init(address_space_mem, 0xfc030000, pic + 36);
|
||||||
|
|
||||||
|
|
|
@ -351,6 +351,7 @@ static bool net_event(void *_xendev)
|
||||||
|
|
||||||
static bool xen_netdev_connect(XenDevice *xendev, Error **errp)
|
static bool xen_netdev_connect(XenDevice *xendev, Error **errp)
|
||||||
{
|
{
|
||||||
|
ERRP_GUARD();
|
||||||
XenNetDev *netdev = XEN_NET_DEVICE(xendev);
|
XenNetDev *netdev = XEN_NET_DEVICE(xendev);
|
||||||
unsigned int port, rx_copy;
|
unsigned int port, rx_copy;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "hw/xen/xen.h"
|
#include "hw/xen/xen.h"
|
||||||
#include "qemu/range.h"
|
#include "qemu/range.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
#include "sysemu/xen.h"
|
||||||
|
|
||||||
#include "hw/i386/kvm/xen_evtchn.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));
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
|
|
||||||
#define MAX_IDE_BUS 2
|
#define MAX_IDE_BUS 2
|
||||||
#define CFG_ADDR 0xf0000510
|
#define CFG_ADDR 0xf0000510
|
||||||
#define TBFREQ (100UL * 1000UL * 1000UL)
|
#define TBFREQ (25UL * 1000UL * 1000UL)
|
||||||
#define CLOCKFREQ (900UL * 1000UL * 1000UL)
|
#define CLOCKFREQ (900UL * 1000UL * 1000UL)
|
||||||
#define BUSFREQ (100UL * 1000UL * 1000UL)
|
#define BUSFREQ (100UL * 1000UL * 1000UL)
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ struct RemoteObject {
|
||||||
|
|
||||||
static void remote_object_set_fd(Object *obj, const char *str, Error **errp)
|
static void remote_object_set_fd(Object *obj, const char *str, Error **errp)
|
||||||
{
|
{
|
||||||
|
ERRP_GUARD();
|
||||||
RemoteObject *o = REMOTE_OBJECT(obj);
|
RemoteObject *o = REMOTE_OBJECT(obj);
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/units.h"
|
#include "qemu/units.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
#include "exec/target_page.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
#include "hw/pci/pci_host.h"
|
#include "hw/pci/pci_host.h"
|
||||||
|
@ -9,11 +10,12 @@
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#include "hw/xen/arch_hvm.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,
|
void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
unsigned target_page_bits = qemu_target_page_bits();
|
||||||
unsigned long nr_pfn;
|
unsigned long nr_pfn;
|
||||||
xen_pfn_t *pfn_list;
|
xen_pfn_t *pfn_list;
|
||||||
int i;
|
int i;
|
||||||
|
@ -26,17 +28,17 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mr == &ram_memory) {
|
if (mr == &xen_memory) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_xen_ram_alloc(ram_addr, size);
|
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);
|
pfn_list = g_new(xen_pfn_t, nr_pfn);
|
||||||
|
|
||||||
for (i = 0; i < nr_pfn; i++) {
|
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)) {
|
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);
|
XenIOState *state = container_of(listener, XenIOState, memory_listener);
|
||||||
|
|
||||||
if (section->mr == &ram_memory) {
|
if (section->mr == &xen_memory) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (add) {
|
if (add) {
|
||||||
|
|
|
@ -59,7 +59,8 @@
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
#include "hw/qdev-properties-system.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.h"
|
||||||
#include "hw/xen/xen-legacy-backend.h"
|
#include "hw/xen/xen-legacy-backend.h"
|
||||||
#include "qemu/range.h"
|
#include "qemu/range.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
|
#ifndef XEN_PT_H
|
||||||
#define XEN_PT_H
|
#define XEN_PT_H
|
||||||
|
|
||||||
|
@ -5,9 +15,6 @@
|
||||||
#include "xen-host-pci-device.h"
|
#include "xen-host-pci-device.h"
|
||||||
#include "qom/object.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);
|
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)
|
#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;
|
XenPTQdevRealize pci_qdev_realize;
|
||||||
} XenPTDeviceClass;
|
} 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 */
|
/* function type for config reg */
|
||||||
typedef int (*xen_pt_conf_reg_init)
|
typedef int (*xen_pt_conf_reg_init)
|
||||||
(XenPCIPassthroughState *, XenPTRegInfo *, uint32_t real_offset,
|
(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,
|
void *pci_assign_dev_load_option_rom(PCIDevice *dev, int *size,
|
||||||
unsigned int domain, unsigned int bus,
|
unsigned int domain, unsigned int bus,
|
||||||
unsigned int slot, unsigned int function);
|
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_register_vga_regions(XenHostPCIDevice *dev);
|
||||||
int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
|
int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
|
||||||
void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev,
|
void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev,
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/timer.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"
|
#include "hw/xen/xen-legacy-backend.h"
|
||||||
|
|
||||||
#define XEN_PT_MERGE_VALUE(value, data, val_mask) \
|
#define XEN_PT_MERGE_VALUE(value, data, val_mask) \
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
*/
|
*/
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.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"
|
#include "xen-host-pci-device.h"
|
||||||
|
|
||||||
static unsigned long igd_guest_opregion;
|
static unsigned long igd_guest_opregion;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "hw/xen/xen_pt.h"
|
#include "hw/xen/xen_igd.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
|
||||||
bool xen_igd_gfx_pt_enabled(void)
|
bool xen_igd_gfx_pt_enabled(void)
|
||||||
|
|
|
@ -288,18 +288,6 @@ extern const size_t pc_compat_2_1_len;
|
||||||
extern GlobalProperty pc_compat_2_0[];
|
extern GlobalProperty pc_compat_2_0[];
|
||||||
extern const size_t pc_compat_2_0_len;
|
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) \
|
#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
|
||||||
static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \
|
static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -8,6 +8,7 @@ extern const PropertyInfo qdev_prop_macaddr;
|
||||||
extern const PropertyInfo qdev_prop_reserved_region;
|
extern const PropertyInfo qdev_prop_reserved_region;
|
||||||
extern const PropertyInfo qdev_prop_multifd_compression;
|
extern const PropertyInfo qdev_prop_multifd_compression;
|
||||||
extern const PropertyInfo qdev_prop_mig_mode;
|
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_losttickpolicy;
|
||||||
extern const PropertyInfo qdev_prop_blockdev_on_error;
|
extern const PropertyInfo qdev_prop_blockdev_on_error;
|
||||||
extern const PropertyInfo qdev_prop_bios_chs_trans;
|
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 DEFINE_PROP_MIG_MODE(_n, _s, _f, _d) \
|
||||||
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_mig_mode, \
|
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_mig_mode, \
|
||||||
MigMode)
|
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 DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
|
||||||
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
|
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
|
||||||
LostTickPolicy)
|
LostTickPolicy)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include <xen/hvm/ioreq.h>
|
#include <xen/hvm/ioreq.h>
|
||||||
|
|
||||||
extern MemoryRegion ram_memory;
|
extern MemoryRegion xen_memory;
|
||||||
extern MemoryListener xen_io_listener;
|
extern MemoryListener xen_io_listener;
|
||||||
extern DeviceListener xen_device_listener;
|
extern DeviceListener xen_device_listener;
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -10,10 +10,11 @@
|
||||||
#define XEN_MAPCACHE_H
|
#define XEN_MAPCACHE_H
|
||||||
|
|
||||||
#include "exec/cpu-common.h"
|
#include "exec/cpu-common.h"
|
||||||
|
#include "sysemu/xen.h"
|
||||||
|
|
||||||
typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
|
typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
|
||||||
ram_addr_t size);
|
ram_addr_t size);
|
||||||
#ifdef CONFIG_XEN
|
#ifdef CONFIG_XEN_IS_POSSIBLE
|
||||||
|
|
||||||
void xen_map_cache_init(phys_offset_to_gaddr_t f,
|
void xen_map_cache_init(phys_offset_to_gaddr_t f,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
#ifndef SYSEMU_XEN_H
|
#ifndef SYSEMU_XEN_H
|
||||||
#define 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"
|
#include "exec/cpu-common.h"
|
||||||
|
|
||||||
#ifdef NEED_CPU_H
|
#ifdef NEED_CPU_H
|
||||||
|
@ -26,16 +30,13 @@ extern bool xen_allowed;
|
||||||
|
|
||||||
#define xen_enabled() (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_hvm_modified_memory(ram_addr_t start, ram_addr_t length);
|
||||||
void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
|
void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
|
||||||
struct MemoryRegion *mr, Error **errp);
|
struct MemoryRegion *mr, Error **errp);
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* !CONFIG_XEN_IS_POSSIBLE */
|
#else /* !CONFIG_XEN_IS_POSSIBLE */
|
||||||
|
|
||||||
#define xen_enabled() 0
|
#define xen_enabled() 0
|
||||||
#ifndef CONFIG_USER_ONLY
|
|
||||||
static inline void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
|
static inline void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
|
||||||
{
|
{
|
||||||
/* nothing */
|
/* nothing */
|
||||||
|
@ -45,7 +46,6 @@ static inline void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
|
||||||
{
|
{
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CONFIG_XEN_IS_POSSIBLE */
|
#endif /* CONFIG_XEN_IS_POSSIBLE */
|
||||||
|
|
||||||
|
|
|
@ -957,3 +957,21 @@
|
||||||
|
|
||||||
{ 'struct': 'DummyVirtioForceArrays',
|
{ 'struct': 'DummyVirtioForceArrays',
|
||||||
'data': { 'unused-iothread-vq-mapping': ['IOThreadVirtQueueMapping'] } }
|
'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' ] }
|
||||||
|
|
|
@ -24,10 +24,6 @@ int xen_set_pci_link_route(uint8_t link, uint8_t irq)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int xen_is_pirq_msi(uint32_t msi_data)
|
int xen_is_pirq_msi(uint32_t msi_data)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include "hw/qdev-core.h"
|
#include "hw/qdev-core.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#include "hw/xen/xen.h"
|
#include "sysemu/xen.h"
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "sysemu/tcg.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "sysemu/qtest.h"
|
#include "sysemu/qtest.h"
|
||||||
|
|
|
@ -744,7 +744,6 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
|
#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,
|
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
|
||||||
int indent)
|
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)
|
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
|
||||||
{
|
{
|
||||||
ObjectClass *class;
|
ObjectClass *class;
|
||||||
BusState *child;
|
|
||||||
NamedGPIOList *ngl;
|
NamedGPIOList *ngl;
|
||||||
NamedClockList *ncl;
|
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) {
|
QLIST_FOREACH(ngl, &dev->gpios, node) {
|
||||||
if (ngl->num_in) {
|
if (ngl->num_in) {
|
||||||
qdev_printf("gpio-in \"%s\" %d\n", ngl->name ? ngl->name : "",
|
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);
|
class = object_class_get_parent(class);
|
||||||
} while (class != object_class_by_name(TYPE_DEVICE));
|
} while (class != object_class_by_name(TYPE_DEVICE));
|
||||||
bus_print_dev(dev->parent_bus, mon, dev, indent);
|
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;
|
BusChild *kid;
|
||||||
|
|
||||||
|
@ -827,16 +819,27 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent)
|
||||||
indent += 2;
|
indent += 2;
|
||||||
qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
|
qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
|
||||||
QTAILQ_FOREACH(kid, &bus->children, sibling) {
|
QTAILQ_FOREACH(kid, &bus->children, sibling) {
|
||||||
|
BusState *child_bus;
|
||||||
DeviceState *dev = kid->child;
|
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
|
#undef qdev_printf
|
||||||
|
|
||||||
void hmp_info_qtree(Monitor *mon, const QDict *qdict)
|
void hmp_info_qtree(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
if (sysbus_get_default())
|
bool details = !qdict_get_try_bool(qdict, "brief", false);
|
||||||
qbus_print(mon, sysbus_get_default(), 0);
|
|
||||||
|
if (sysbus_get_default()) {
|
||||||
|
qbus_print(mon, sysbus_get_default(), 0, details);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_info_qdm(Monitor *mon, const QDict *qdict)
|
void hmp_info_qdm(Monitor *mon, const QDict *qdict)
|
||||||
|
|
|
@ -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,
|
int sev_inject_launch_secret(const char *packet_hdr, const char *secret,
|
||||||
uint64_t gpa, Error **errp)
|
uint64_t gpa, Error **errp)
|
||||||
{
|
{
|
||||||
|
ERRP_GUARD();
|
||||||
struct kvm_sev_launch_secret input;
|
struct kvm_sev_launch_secret input;
|
||||||
g_autofree guchar *data = NULL, *hdr = NULL;
|
g_autofree guchar *data = NULL, *hdr = NULL;
|
||||||
int error, ret = 1;
|
int error, ret = 1;
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
#define T true
|
#define T true
|
||||||
#define F false
|
#define F false
|
||||||
|
|
||||||
#define MIN_CPUS 1 /* set the min CPUs supported by the machine as 1 */
|
#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 MAX_CPUS 4096 /* set the max CPUs supported by the machine as 4096 */
|
||||||
|
|
||||||
#define SMP_MACHINE_NAME "TEST-SMP"
|
#define SMP_MACHINE_NAME "TEST-SMP"
|
||||||
|
|
||||||
|
@ -75,6 +75,40 @@
|
||||||
.has_maxcpus = hf, .maxcpus = f, \
|
.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
|
* @config - the given SMP configuration
|
||||||
* @expect_prefer_sockets - the expected parsing result for the
|
* @expect_prefer_sockets - the expected parsing result for the
|
||||||
|
@ -308,6 +342,16 @@ static const struct SMPTestData data_generic_invalid[] = {
|
||||||
/* config: -smp 2,clusters=2 */
|
/* config: -smp 2,clusters=2 */
|
||||||
.config = SMP_CONFIG_WITH_CLUSTERS(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0),
|
.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",
|
.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 8,sockets=2,cores=4,threads=2,maxcpus=8 */
|
||||||
.config = SMP_CONFIG_GENERIC(T, 8, T, 2, T, 4, T, 2, T, 8),
|
.config = SMP_CONFIG_GENERIC(T, 8, T, 2, T, 4, T, 2, T, 8),
|
||||||
|
@ -323,17 +367,23 @@ static const struct SMPTestData data_generic_invalid[] = {
|
||||||
"sockets (2) * cores (4) * threads (2) "
|
"sockets (2) * cores (4) * threads (2) "
|
||||||
"== maxcpus (16) < smp_cpus (18)",
|
"== maxcpus (16) < smp_cpus (18)",
|
||||||
}, {
|
}, {
|
||||||
/* config: -smp 1
|
/*
|
||||||
* should tweak the supported min CPUs to 2 for testing */
|
* config: -smp 1
|
||||||
.config = SMP_CONFIG_GENERIC(T, 1, F, 0, F, 0, F, 0, F, 0),
|
* 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 "
|
.expect_error = "Invalid SMP CPUs 1. The min CPUs supported "
|
||||||
"by machine '" SMP_MACHINE_NAME "' is 2",
|
"by machine '" SMP_MACHINE_NAME "' is 2",
|
||||||
}, {
|
}, {
|
||||||
/* config: -smp 512
|
/*
|
||||||
* should tweak the supported max CPUs to 511 for testing */
|
* config: -smp 4096
|
||||||
.config = SMP_CONFIG_GENERIC(T, 512, F, 0, F, 0, F, 0, F, 0),
|
* The test machine should tweak the supported max CPUs to
|
||||||
.expect_error = "Invalid SMP CPUs 512. The max CPUs supported "
|
* 4095 (MAX_CPUS - 1) for testing.
|
||||||
"by machine '" SMP_MACHINE_NAME "' is 511",
|
*/
|
||||||
|
.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)
|
static char *smp_config_to_string(const SMPConfiguration *config)
|
||||||
{
|
{
|
||||||
return g_strdup_printf(
|
return g_strdup_printf(
|
||||||
"(SMPConfiguration) {\n"
|
"(SMPConfiguration) {\n"
|
||||||
" .has_cpus = %5s, cpus = %" PRId64 ",\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_sockets = %5s, sockets = %" PRId64 ",\n"
|
||||||
" .has_dies = %5s, dies = %" PRId64 ",\n"
|
" .has_dies = %5s, dies = %" PRId64 ",\n"
|
||||||
" .has_clusters = %5s, clusters = %" 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"
|
" .has_maxcpus = %5s, maxcpus = %" PRId64 ",\n"
|
||||||
"}",
|
"}",
|
||||||
config->has_cpus ? "true" : "false", config->cpus,
|
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_sockets ? "true" : "false", config->sockets,
|
||||||
config->has_dies ? "true" : "false", config->dies,
|
config->has_dies ? "true" : "false", config->dies,
|
||||||
config->has_clusters ? "true" : "false", config->clusters,
|
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)
|
static unsigned int cpu_topology_get_threads_per_socket(const CpuTopology *topo)
|
||||||
{
|
{
|
||||||
/* Check the divisor to avoid invalid topology examples causing SIGFPE. */
|
/* Check the divisor to avoid invalid topology examples causing SIGFPE. */
|
||||||
if (!topo->sockets) {
|
if (!topo->drawers || !topo->books || !topo->sockets) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} 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,
|
static char *cpu_topology_to_string(const CpuTopology *topo,
|
||||||
unsigned int threads_per_socket,
|
unsigned int threads_per_socket,
|
||||||
unsigned int cores_per_socket)
|
unsigned int cores_per_socket,
|
||||||
|
bool has_clusters)
|
||||||
{
|
{
|
||||||
return g_strdup_printf(
|
return g_strdup_printf(
|
||||||
"(CpuTopology) {\n"
|
"(CpuTopology) {\n"
|
||||||
" .cpus = %u,\n"
|
" .cpus = %u,\n"
|
||||||
|
" .drawers = %u,\n"
|
||||||
|
" .books = %u,\n"
|
||||||
" .sockets = %u,\n"
|
" .sockets = %u,\n"
|
||||||
" .dies = %u,\n"
|
" .dies = %u,\n"
|
||||||
" .clusters = %u,\n"
|
" .clusters = %u,\n"
|
||||||
|
@ -431,16 +674,20 @@ static char *cpu_topology_to_string(const CpuTopology *topo,
|
||||||
" .max_cpus = %u,\n"
|
" .max_cpus = %u,\n"
|
||||||
" .threads_per_socket = %u,\n"
|
" .threads_per_socket = %u,\n"
|
||||||
" .cores_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,
|
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,
|
static void check_parse(MachineState *ms, const SMPConfiguration *config,
|
||||||
const CpuTopology *expect_topo, const char *expect_err,
|
const CpuTopology *expect_topo, const char *expect_err,
|
||||||
bool is_valid)
|
bool is_valid)
|
||||||
{
|
{
|
||||||
|
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||||
g_autofree char *config_str = smp_config_to_string(config);
|
g_autofree char *config_str = smp_config_to_string(config);
|
||||||
g_autofree char *expect_topo_str = NULL, *output_topo_str = NULL;
|
g_autofree char *expect_topo_str = NULL, *output_topo_str = NULL;
|
||||||
unsigned int expect_threads_per_socket, expect_cores_per_socket;
|
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);
|
cpu_topology_get_cores_per_socket(expect_topo);
|
||||||
expect_topo_str = cpu_topology_to_string(expect_topo,
|
expect_topo_str = cpu_topology_to_string(expect_topo,
|
||||||
expect_threads_per_socket,
|
expect_threads_per_socket,
|
||||||
expect_cores_per_socket);
|
expect_cores_per_socket,
|
||||||
|
config->has_clusters);
|
||||||
|
|
||||||
/* call the generic parser */
|
/* call the generic parser */
|
||||||
machine_parse_smp_config(ms, config, &err);
|
machine_parse_smp_config(ms, config, &err);
|
||||||
|
|
||||||
ms_threads_per_socket = machine_topo_get_threads_per_socket(ms);
|
ms_threads_per_socket = machine_topo_get_threads_per_socket(ms);
|
||||||
ms_cores_per_socket = machine_topo_get_cores_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,
|
output_topo_str = cpu_topology_to_string(&ms->smp,
|
||||||
ms_cores_per_socket);
|
ms_threads_per_socket,
|
||||||
|
ms_cores_per_socket,
|
||||||
|
mc->smp_props.has_clusters);
|
||||||
|
|
||||||
/* when the configuration is supposed to be valid */
|
/* when the configuration is supposed to be valid */
|
||||||
if (is_valid) {
|
if (is_valid) {
|
||||||
if ((err == NULL) &&
|
if ((err == NULL) &&
|
||||||
(ms->smp.cpus == expect_topo->cpus) &&
|
(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.sockets == expect_topo->sockets) &&
|
||||||
(ms->smp.dies == expect_topo->dies) &&
|
(ms->smp.dies == expect_topo->dies) &&
|
||||||
(ms->smp.clusters == expect_topo->clusters) &&
|
(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.threads == expect_topo->threads) &&
|
||||||
(ms->smp.max_cpus == expect_topo->max_cpus) &&
|
(ms->smp.max_cpus == expect_topo->max_cpus) &&
|
||||||
(ms_threads_per_socket == expect_threads_per_socket) &&
|
(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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,6 +811,16 @@ static void unsupported_params_init(const MachineClass *mc, SMPTestData *data)
|
||||||
data->expect_prefer_sockets.clusters = 1;
|
data->expect_prefer_sockets.clusters = 1;
|
||||||
data->expect_prefer_cores.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)
|
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);
|
MachineClass *mc = MACHINE_CLASS(oc);
|
||||||
|
|
||||||
/* Force invalid min CPUs and max CPUs */
|
/* Force invalid min CPUs and max CPUs */
|
||||||
mc->min_cpus = 2;
|
mc->min_cpus = MIN_CPUS + 1;
|
||||||
mc->max_cpus = 511;
|
mc->max_cpus = MAX_CPUS - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void machine_with_dies_class_init(ObjectClass *oc, void *data)
|
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;
|
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)
|
static void test_generic_valid(const void *opaque)
|
||||||
{
|
{
|
||||||
const char *machine_type = opaque;
|
const char *machine_type = opaque;
|
||||||
|
@ -607,11 +902,6 @@ static void test_generic_valid(const void *opaque)
|
||||||
unsupported_params_init(mc, &data);
|
unsupported_params_init(mc, &data);
|
||||||
|
|
||||||
smp_parse_test(ms, &data, true);
|
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);
|
object_unref(obj);
|
||||||
|
@ -736,6 +1026,248 @@ static void test_with_clusters(const void *opaque)
|
||||||
object_unref(obj);
|
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 */
|
/* Type info of the tested machine */
|
||||||
static const TypeInfo smp_machine_types[] = {
|
static const TypeInfo smp_machine_types[] = {
|
||||||
{
|
{
|
||||||
|
@ -760,6 +1292,22 @@ static const TypeInfo smp_machine_types[] = {
|
||||||
.name = MACHINE_TYPE_NAME("smp-with-clusters"),
|
.name = MACHINE_TYPE_NAME("smp-with-clusters"),
|
||||||
.parent = TYPE_MACHINE,
|
.parent = TYPE_MACHINE,
|
||||||
.class_init = machine_with_clusters_class_init,
|
.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",
|
g_test_add_data_func("/test-smp-parse/with_clusters",
|
||||||
MACHINE_TYPE_NAME("smp-with-clusters"),
|
MACHINE_TYPE_NAME("smp-with-clusters"),
|
||||||
test_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();
|
g_test_run();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue