mirror of https://github.com/xemu-project/xemu.git
target-arm queue:
* arm/kvm: add support for MTE * docs/system/cpu-hotplug: Update example's socket-id/core-id * target/arm: Store FPSR cumulative exception bits in env->vfp.fpsr * target/arm: Don't assert in regime_is_user() for E10 mmuidx values * hw/sd/omap_mmc: Fix breakage of OMAP MMC controller * tests/functional: Add functional tests for collie, sx1 * scripts/symlink-install-tree.py: Fix MESONINTROSPECT parsing * docs/system/arm: Document remaining undocumented boards * target/arm: Fix arithmetic underflow in SETM instruction * docs/devel/reset: Fix minor grammatical error * target/arm: kvm: require KVM_CAP_DEVICE_CTRL -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmcg+oYZHHBldGVyLm1h eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3g/KD/4tzAD2zkWpnIPhY5ht4wBz Kioy+pnXJW5I6pAS4ljnI41pOFnPr6Ln1NfGkP+9pTND8lIQNY0Te2a/NjgEiYJc rYJ/A6UUuCqQ8+/oWWMPETcbbiKcSS2mzCJ/pNXeIquK5Co0Qk7mzdfObudwZpbw o3Cc9YrGZc64XAl2Rb83Oy2UHo1xjmV67wtEmcj+hmWC+tFc7pQpAKwIKcBMgns8 ZILexX18RYZMDqQZQ5tvwTccJeFmljj9PyScou787RXK93BlF3sL/ypq1xMykRru JpMwAI6jD5LG9NO2zNr3FpBef8sJXqNF+O0DcYmhrKBwRkztuEU6DXF6xzdz/HRa c14hWK1jHku+HvKBXx3c5wibTbTU71Jv36Gw5VjOBQe/5cdKJAbZw8OH+IK8ozk9 GwLVQ/JzrIi5m8FwXPwmkOPLX/CY8Wot6IWdJKKGTN8bY+9Cu2gTduFJIvi96HWU xkG1ySN61wKUR8Z26mizim2nBvQjybjqKEhrtQ21K548j4pWFVBgXJQX0Menca/v ziSLCd84Pmh9+DtElPCUyau/nX/jyUJ1gCScvcJjF5jAMPBREpAh53j/GL9JEgX6 9cX2WG6o+9R4Qcrh1O3Vy1bAUcJ27Tr2NitD+g5XObZ+vC6YgqfN2/M53so4rwws N4KCRdV6GcU70bQAul3mLQ== =KWM2 -----END PGP SIGNATURE----- Merge tag 'pull-target-arm-20241029' of https://git.linaro.org/people/pmaydell/qemu-arm into staging target-arm queue: * arm/kvm: add support for MTE * docs/system/cpu-hotplug: Update example's socket-id/core-id * target/arm: Store FPSR cumulative exception bits in env->vfp.fpsr * target/arm: Don't assert in regime_is_user() for E10 mmuidx values * hw/sd/omap_mmc: Fix breakage of OMAP MMC controller * tests/functional: Add functional tests for collie, sx1 * scripts/symlink-install-tree.py: Fix MESONINTROSPECT parsing * docs/system/arm: Document remaining undocumented boards * target/arm: Fix arithmetic underflow in SETM instruction * docs/devel/reset: Fix minor grammatical error * target/arm: kvm: require KVM_CAP_DEVICE_CTRL # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmcg+oYZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3g/KD/4tzAD2zkWpnIPhY5ht4wBz # Kioy+pnXJW5I6pAS4ljnI41pOFnPr6Ln1NfGkP+9pTND8lIQNY0Te2a/NjgEiYJc # rYJ/A6UUuCqQ8+/oWWMPETcbbiKcSS2mzCJ/pNXeIquK5Co0Qk7mzdfObudwZpbw # o3Cc9YrGZc64XAl2Rb83Oy2UHo1xjmV67wtEmcj+hmWC+tFc7pQpAKwIKcBMgns8 # ZILexX18RYZMDqQZQ5tvwTccJeFmljj9PyScou787RXK93BlF3sL/ypq1xMykRru # JpMwAI6jD5LG9NO2zNr3FpBef8sJXqNF+O0DcYmhrKBwRkztuEU6DXF6xzdz/HRa # c14hWK1jHku+HvKBXx3c5wibTbTU71Jv36Gw5VjOBQe/5cdKJAbZw8OH+IK8ozk9 # GwLVQ/JzrIi5m8FwXPwmkOPLX/CY8Wot6IWdJKKGTN8bY+9Cu2gTduFJIvi96HWU # xkG1ySN61wKUR8Z26mizim2nBvQjybjqKEhrtQ21K548j4pWFVBgXJQX0Menca/v # ziSLCd84Pmh9+DtElPCUyau/nX/jyUJ1gCScvcJjF5jAMPBREpAh53j/GL9JEgX6 # 9cX2WG6o+9R4Qcrh1O3Vy1bAUcJ27Tr2NitD+g5XObZ+vC6YgqfN2/M53so4rwws # N4KCRdV6GcU70bQAul3mLQ== # =KWM2 # -----END PGP SIGNATURE----- # gpg: Signature made Tue 29 Oct 2024 15:08:54 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20241029' of https://git.linaro.org/people/pmaydell/qemu-arm: target/arm: kvm: require KVM_CAP_DEVICE_CTRL docs/devel/reset: Fix minor grammatical error target/arm: Fix arithmetic underflow in SETM instruction docs/system/target-arm.rst: Remove "many boards are undocumented" note docs/system/arm: Add placeholder docs for mcimx6ul-evk and mcimx7d-sabre docs/system/arm: Add placeholder doc for xlnx-zcu102 board docs/system/arm: Add placeholder doc for exynos4 boards docs/system/arm: Split fby35 out from aspeed.rst docs/system/arm: Don't use wildcard '*-bmc' in doc titles docs/system/arm/stm32: List olimex-stm32-h405 in document title scripts/symlink-install-tree.py: Fix MESONINTROSPECT parsing tests/functional: Add a functional test for the sx1 board tests/functional: Add a functional test for the collie board hw/sd/omap_mmc: Don't use sd_cmd_type_t target/arm: Don't assert in regime_is_user() for E10 mmuidx values target/arm: Store FPSR cumulative exception bits in env->vfp.fpsr docs/system/cpu-hotplug: Update example's socket-id/core-id arm/kvm: add support for MTE Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
ea8ae47bdd
|
@ -716,6 +716,7 @@ L: qemu-arm@nongnu.org
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
F: hw/*/exynos*
|
F: hw/*/exynos*
|
||||||
F: include/hw/*/exynos*
|
F: include/hw/*/exynos*
|
||||||
|
F: docs/system/arm/exynos.rst
|
||||||
|
|
||||||
Calxeda Highbank
|
Calxeda Highbank
|
||||||
M: Rob Herring <robh@kernel.org>
|
M: Rob Herring <robh@kernel.org>
|
||||||
|
@ -790,6 +791,7 @@ F: hw/arm/fsl-imx6ul.c
|
||||||
F: hw/misc/imx6ul_ccm.c
|
F: hw/misc/imx6ul_ccm.c
|
||||||
F: include/hw/arm/fsl-imx6ul.h
|
F: include/hw/arm/fsl-imx6ul.h
|
||||||
F: include/hw/misc/imx6ul_ccm.h
|
F: include/hw/misc/imx6ul_ccm.h
|
||||||
|
F: docs/system/arm/mcimx6ul-evk.rst
|
||||||
|
|
||||||
MCIMX7D SABRE / i.MX7
|
MCIMX7D SABRE / i.MX7
|
||||||
M: Peter Maydell <peter.maydell@linaro.org>
|
M: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
@ -803,6 +805,7 @@ F: include/hw/arm/fsl-imx7.h
|
||||||
F: include/hw/misc/imx7_*.h
|
F: include/hw/misc/imx7_*.h
|
||||||
F: hw/pci-host/designware.c
|
F: hw/pci-host/designware.c
|
||||||
F: include/hw/pci-host/designware.h
|
F: include/hw/pci-host/designware.h
|
||||||
|
F: docs/system/arm/mcimx7d-sabre.rst
|
||||||
|
|
||||||
MPS2 / MPS3
|
MPS2 / MPS3
|
||||||
M: Peter Maydell <peter.maydell@linaro.org>
|
M: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
@ -929,6 +932,7 @@ F: hw/arm/strongarm*
|
||||||
F: hw/gpio/zaurus.c
|
F: hw/gpio/zaurus.c
|
||||||
F: include/hw/arm/sharpsl.h
|
F: include/hw/arm/sharpsl.h
|
||||||
F: docs/system/arm/collie.rst
|
F: docs/system/arm/collie.rst
|
||||||
|
F: tests/functional/test_arm_collie.py
|
||||||
|
|
||||||
Stellaris
|
Stellaris
|
||||||
M: Peter Maydell <peter.maydell@linaro.org>
|
M: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
@ -1016,6 +1020,7 @@ F: include/hw/ssi/xilinx_spips.h
|
||||||
F: hw/display/dpcd.c
|
F: hw/display/dpcd.c
|
||||||
F: include/hw/display/dpcd.h
|
F: include/hw/display/dpcd.h
|
||||||
F: docs/system/arm/xlnx-versal-virt.rst
|
F: docs/system/arm/xlnx-versal-virt.rst
|
||||||
|
F: docs/system/arm/xlnx-zcu102.rst
|
||||||
|
|
||||||
Xilinx Versal OSPI
|
Xilinx Versal OSPI
|
||||||
M: Francisco Iglesias <francisco.iglesias@amd.com>
|
M: Francisco Iglesias <francisco.iglesias@amd.com>
|
||||||
|
@ -1122,6 +1127,7 @@ F: include/hw/*/*aspeed*
|
||||||
F: hw/net/ftgmac100.c
|
F: hw/net/ftgmac100.c
|
||||||
F: include/hw/net/ftgmac100.h
|
F: include/hw/net/ftgmac100.h
|
||||||
F: docs/system/arm/aspeed.rst
|
F: docs/system/arm/aspeed.rst
|
||||||
|
F: docs/system/arm/fby35.rst
|
||||||
F: tests/*/*aspeed*
|
F: tests/*/*aspeed*
|
||||||
F: tests/*/*ast2700*
|
F: tests/*/*ast2700*
|
||||||
F: hw/arm/fby35.c
|
F: hw/arm/fby35.c
|
||||||
|
|
|
@ -286,8 +286,8 @@ every reset child of the given resettable object. All children must be
|
||||||
resettable too. Additional parameters (a reset type and an opaque pointer) must
|
resettable too. Additional parameters (a reset type and an opaque pointer) must
|
||||||
be passed to the callback too.
|
be passed to the callback too.
|
||||||
|
|
||||||
In ``DeviceClass`` and ``BusClass`` the ``ResettableState`` is located
|
In ``DeviceClass`` and ``BusClass`` the ``ResettableState`` is located in the
|
||||||
``DeviceState`` and ``BusState`` structure. ``child_foreach()`` is implemented
|
``DeviceState`` and ``BusState`` structures. ``child_foreach()`` is implemented
|
||||||
to follow the bus hierarchy; for a bus, it calls the function on every child
|
to follow the bus hierarchy; for a bus, it calls the function on every child
|
||||||
device; for a device, it calls the function on every bus child. When we reset
|
device; for a device, it calls the function on every bus child. When we reset
|
||||||
the main system bus, we reset the whole machine bus tree.
|
the main system bus, we reset the whole machine bus tree.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``, ``ast2700-evb``)
|
Aspeed family boards (``ast2500-evb``, ``ast2600-evb``, ``ast2700-evb``, ``bletchley-bmc``, ``fuji-bmc``, ``fby35-bmc``, ``fp5280g2-bmc``, ``g220a-bmc``, ``palmetto-bmc``, ``qcom-dc-scm-v1-bmc``, ``qcom-firework-bmc``, ``quanta-q71l-bmc``, ``rainier-bmc``, ``romulus-bmc``, ``sonorapass-bmc``, ``supermicrox11-bmc``, ``tiogapass-bmc``, ``tacoma-bmc``, ``witherspoon-bmc``, ``yosemitev2-bmc``)
|
||||||
===================================================================================
|
========================================================================================================================================================================================================================================================================================================================================================================================================
|
||||||
|
|
||||||
The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
|
The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
|
||||||
Aspeed evaluation boards. They are based on different releases of the
|
Aspeed evaluation boards. They are based on different releases of the
|
||||||
|
@ -257,51 +257,3 @@ To boot a kernel directly from a Zephyr build tree:
|
||||||
|
|
||||||
$ qemu-system-arm -M ast1030-evb -nographic \
|
$ qemu-system-arm -M ast1030-evb -nographic \
|
||||||
-kernel zephyr.elf
|
-kernel zephyr.elf
|
||||||
|
|
||||||
Facebook Yosemite v3.5 Platform and CraterLake Server (``fby35``)
|
|
||||||
==================================================================
|
|
||||||
|
|
||||||
Facebook has a series of multi-node compute server designs named
|
|
||||||
Yosemite. The most recent version released was
|
|
||||||
`Yosemite v3 <https://www.opencompute.org/documents/ocp-yosemite-v3-platform-design-specification-1v16-pdf>`__.
|
|
||||||
|
|
||||||
Yosemite v3.5 is an iteration on this design, and is very similar: there's a
|
|
||||||
baseboard with a BMC, and 4 server slots. The new server board design termed
|
|
||||||
"CraterLake" includes a Bridge IC (BIC), with room for expansion boards to
|
|
||||||
include various compute accelerators (video, inferencing, etc). At the moment,
|
|
||||||
only the first server slot's BIC is included.
|
|
||||||
|
|
||||||
Yosemite v3.5 is itself a sled which fits into a 40U chassis, and 3 sleds
|
|
||||||
can be fit into a chassis. See `here <https://www.opencompute.org/products/423/wiwynn-yosemite-v3-server>`__
|
|
||||||
for an example.
|
|
||||||
|
|
||||||
In this generation, the BMC is an AST2600 and each BIC is an AST1030. The BMC
|
|
||||||
runs `OpenBMC <https://github.com/facebook/openbmc>`__, and the BIC runs
|
|
||||||
`OpenBIC <https://github.com/facebook/openbic>`__.
|
|
||||||
|
|
||||||
Firmware images can be retrieved from the Github releases or built from the
|
|
||||||
source code, see the README's for instructions on that. This image uses the
|
|
||||||
"fby35" machine recipe from OpenBMC, and the "yv35-cl" target from OpenBIC.
|
|
||||||
Some reference images can also be found here:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ wget https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
|
|
||||||
$ wget https://github.com/peterdelevoryas/OpenBIC/releases/download/oby35-cl-2022.13.01/Y35BCL.elf
|
|
||||||
|
|
||||||
Since this machine has multiple SoC's, each with their own serial console, the
|
|
||||||
recommended way to run it is to allocate a pseudoterminal for each serial
|
|
||||||
console and let the monitor use stdio. Also, starting in a paused state is
|
|
||||||
useful because it allows you to attach to the pseudoterminals before the boot
|
|
||||||
process starts.
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ qemu-system-arm -machine fby35 \
|
|
||||||
-drive file=fby35.mtd,format=raw,if=mtd \
|
|
||||||
-device loader,file=Y35BCL.elf,addr=0,cpu-num=2 \
|
|
||||||
-serial pty -serial pty -serial mon:stdio \
|
|
||||||
-display none -S
|
|
||||||
$ screen /dev/tty0 # In a separate TMUX pane, terminal window, etc.
|
|
||||||
$ screen /dev/tty1
|
|
||||||
$ (qemu) c # Start the boot process once screen is setup.
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
Exynos4 boards (``nuri``, ``smdkc210``)
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
These are machines which use the Samsung Exynos4210 SoC, which has Cortex-A9 CPUs.
|
||||||
|
|
||||||
|
``nuri`` models the Samsung NURI board.
|
||||||
|
|
||||||
|
``smdkc210`` models the Samsung SMDKC210 board.
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
Facebook Yosemite v3.5 Platform and CraterLake Server (``fby35``)
|
||||||
|
==================================================================
|
||||||
|
|
||||||
|
Facebook has a series of multi-node compute server designs named
|
||||||
|
Yosemite. The most recent version released was
|
||||||
|
`Yosemite v3 <https://www.opencompute.org/documents/ocp-yosemite-v3-platform-design-specification-1v16-pdf>`__.
|
||||||
|
|
||||||
|
Yosemite v3.5 is an iteration on this design, and is very similar: there's a
|
||||||
|
baseboard with a BMC, and 4 server slots. The new server board design termed
|
||||||
|
"CraterLake" includes a Bridge IC (BIC), with room for expansion boards to
|
||||||
|
include various compute accelerators (video, inferencing, etc). At the moment,
|
||||||
|
only the first server slot's BIC is included.
|
||||||
|
|
||||||
|
Yosemite v3.5 is itself a sled which fits into a 40U chassis, and 3 sleds
|
||||||
|
can be fit into a chassis. See `here <https://www.opencompute.org/products/423/wiwynn-yosemite-v3-server>`__
|
||||||
|
for an example.
|
||||||
|
|
||||||
|
In this generation, the BMC is an AST2600 and each BIC is an AST1030. The BMC
|
||||||
|
runs `OpenBMC <https://github.com/facebook/openbmc>`__, and the BIC runs
|
||||||
|
`OpenBIC <https://github.com/facebook/openbic>`__.
|
||||||
|
|
||||||
|
Firmware images can be retrieved from the Github releases or built from the
|
||||||
|
source code, see the README's for instructions on that. This image uses the
|
||||||
|
"fby35" machine recipe from OpenBMC, and the "yv35-cl" target from OpenBIC.
|
||||||
|
Some reference images can also be found here:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ wget https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
|
||||||
|
$ wget https://github.com/peterdelevoryas/OpenBIC/releases/download/oby35-cl-2022.13.01/Y35BCL.elf
|
||||||
|
|
||||||
|
Since this machine has multiple SoC's, each with their own serial console, the
|
||||||
|
recommended way to run it is to allocate a pseudoterminal for each serial
|
||||||
|
console and let the monitor use stdio. Also, starting in a paused state is
|
||||||
|
useful because it allows you to attach to the pseudoterminals before the boot
|
||||||
|
process starts.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ qemu-system-arm -machine fby35 \
|
||||||
|
-drive file=fby35.mtd,format=raw,if=mtd \
|
||||||
|
-device loader,file=Y35BCL.elf,addr=0,cpu-num=2 \
|
||||||
|
-serial pty -serial pty -serial mon:stdio \
|
||||||
|
-display none -S
|
||||||
|
$ screen /dev/tty0 # In a separate TMUX pane, terminal window, etc.
|
||||||
|
$ screen /dev/tty1
|
||||||
|
$ (qemu) c # Start the boot process once screen is setup.
|
|
@ -0,0 +1,5 @@
|
||||||
|
NXP MCIMX6UL-EVK (``mcimx6ul-evk``)
|
||||||
|
===================================
|
||||||
|
|
||||||
|
The ``mcimx6ul-evk`` machine models the NXP i.MX6UltraLite Evaluation Kit
|
||||||
|
MCIMX6UL-EVK development board. It has a single Cortex-A7 CPU.
|
|
@ -0,0 +1,5 @@
|
||||||
|
NXP MCIMX7D Sabre (``mcimx7d-sabre``)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
The ``mcimx7d-sabre`` machine models the NXP SABRE Board MCIMX7SABRE,
|
||||||
|
based an an i.MX7Dual SoC.
|
|
@ -1,5 +1,5 @@
|
||||||
Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
|
Nuvoton iBMC boards (``kudo-bmc``, ``mori-bmc``, ``npcm750-evb``, ``quanta-gbs-bmc``, ``quanta-gsj``)
|
||||||
================================================================
|
=====================================================================================================
|
||||||
|
|
||||||
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
|
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
|
||||||
designed to be used as Baseboard Management Controllers (BMCs) in various
|
designed to be used as Baseboard Management Controllers (BMCs) in various
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
STMicroelectronics STM32 boards (``netduino2``, ``netduinoplus2``, ``stm32vldiscovery``)
|
STMicroelectronics STM32 boards (``netduino2``, ``netduinoplus2``, ``olimex-stm32-h405``, ``stm32vldiscovery``)
|
||||||
========================================================================================
|
===============================================================================================================
|
||||||
|
|
||||||
The `STM32`_ chips are a family of 32-bit ARM-based microcontroller by
|
The `STM32`_ chips are a family of 32-bit ARM-based microcontroller by
|
||||||
STMicroelectronics.
|
STMicroelectronics.
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
Xilinx ZynqMP ZCU102 (``xlnx-zcu102``)
|
||||||
|
======================================
|
||||||
|
|
||||||
|
The ``xlnx-zcu102`` board models the Xilinx ZynqMP ZCU102 board.
|
||||||
|
This board has 4 Cortex-A53 CPUs and 2 Cortex-R5F CPUs.
|
||||||
|
|
||||||
|
Machine-specific options
|
||||||
|
""""""""""""""""""""""""
|
||||||
|
|
||||||
|
The following machine-specific options are supported:
|
||||||
|
|
||||||
|
secure
|
||||||
|
Set ``on``/``off`` to enable/disable emulating a guest CPU which implements the
|
||||||
|
Arm Security Extensions (TrustZone). The default is ``off``.
|
||||||
|
|
||||||
|
virtualization
|
||||||
|
Set ``on``/``off`` to enable/disable emulating a guest CPU which implements the
|
||||||
|
Arm Virtualization Extensions. The default is ``off``.
|
||||||
|
|
|
@ -33,23 +33,23 @@ vCPU hotplug
|
||||||
{
|
{
|
||||||
"return": [
|
"return": [
|
||||||
{
|
{
|
||||||
"type": "IvyBridge-IBRS-x86_64-cpu",
|
|
||||||
"vcpus-count": 1,
|
|
||||||
"props": {
|
"props": {
|
||||||
"socket-id": 1,
|
"core-id": 1,
|
||||||
"core-id": 0,
|
"socket-id": 0,
|
||||||
"thread-id": 0
|
"thread-id": 0
|
||||||
}
|
},
|
||||||
|
"type": "IvyBridge-IBRS-x86_64-cpu",
|
||||||
|
"vcpus-count": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"props": {
|
||||||
|
"core-id": 0,
|
||||||
|
"socket-id": 0,
|
||||||
|
"thread-id": 0
|
||||||
|
},
|
||||||
"qom-path": "/machine/unattached/device[0]",
|
"qom-path": "/machine/unattached/device[0]",
|
||||||
"type": "IvyBridge-IBRS-x86_64-cpu",
|
"type": "IvyBridge-IBRS-x86_64-cpu",
|
||||||
"vcpus-count": 1,
|
"vcpus-count": 1
|
||||||
"props": {
|
|
||||||
"socket-id": 0,
|
|
||||||
"core-id": 0,
|
|
||||||
"thread-id": 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -58,18 +58,18 @@ vCPU hotplug
|
||||||
(4) The ``query-hotpluggable-cpus`` command returns an object for CPUs
|
(4) The ``query-hotpluggable-cpus`` command returns an object for CPUs
|
||||||
that are present (containing a "qom-path" member) or which may be
|
that are present (containing a "qom-path" member) or which may be
|
||||||
hot-plugged (no "qom-path" member). From its output in step (3), we
|
hot-plugged (no "qom-path" member). From its output in step (3), we
|
||||||
can see that ``IvyBridge-IBRS-x86_64-cpu`` is present in socket 0,
|
can see that ``IvyBridge-IBRS-x86_64-cpu`` is present in socket 0 core 0,
|
||||||
while hot-plugging a CPU into socket 1 requires passing the listed
|
while hot-plugging a CPU into socket 0 core 1 requires passing the listed
|
||||||
properties to QMP ``device_add``::
|
properties to QMP ``device_add``::
|
||||||
|
|
||||||
(QEMU) device_add id=cpu-2 driver=IvyBridge-IBRS-x86_64-cpu socket-id=1 core-id=0 thread-id=0
|
(QEMU) device_add id=cpu-2 driver=IvyBridge-IBRS-x86_64-cpu socket-id=0 core-id=1 thread-id=0
|
||||||
{
|
{
|
||||||
"execute": "device_add",
|
"execute": "device_add",
|
||||||
"arguments": {
|
"arguments": {
|
||||||
"socket-id": 1,
|
"core-id": 1,
|
||||||
"driver": "IvyBridge-IBRS-x86_64-cpu",
|
"driver": "IvyBridge-IBRS-x86_64-cpu",
|
||||||
"id": "cpu-2",
|
"id": "cpu-2",
|
||||||
"core-id": 0,
|
"socket-id": 0,
|
||||||
"thread-id": 0
|
"thread-id": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,34 +83,32 @@ vCPU hotplug
|
||||||
|
|
||||||
(QEMU) query-cpus-fast
|
(QEMU) query-cpus-fast
|
||||||
{
|
{
|
||||||
"execute": "query-cpus-fast",
|
|
||||||
"arguments": {}
|
"arguments": {}
|
||||||
|
"execute": "query-cpus-fast",
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
"return": [
|
"return": [
|
||||||
{
|
{
|
||||||
"qom-path": "/machine/unattached/device[0]",
|
|
||||||
"target": "x86_64",
|
|
||||||
"thread-id": 11534,
|
|
||||||
"cpu-index": 0,
|
"cpu-index": 0,
|
||||||
"props": {
|
"props": {
|
||||||
"socket-id": 0,
|
|
||||||
"core-id": 0,
|
"core-id": 0,
|
||||||
|
"socket-id": 0,
|
||||||
"thread-id": 0
|
"thread-id": 0
|
||||||
},
|
},
|
||||||
"arch": "x86"
|
"qom-path": "/machine/unattached/device[0]",
|
||||||
|
"target": "x86_64",
|
||||||
|
"thread-id": 28957
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"qom-path": "/machine/peripheral/cpu-2",
|
|
||||||
"target": "x86_64",
|
|
||||||
"thread-id": 12106,
|
|
||||||
"cpu-index": 1,
|
"cpu-index": 1,
|
||||||
"props": {
|
"props": {
|
||||||
"socket-id": 1,
|
"core-id": 1,
|
||||||
"core-id": 0,
|
"socket-id": 0,
|
||||||
"thread-id": 0
|
"thread-id": 0
|
||||||
},
|
},
|
||||||
"arch": "x86"
|
"qom-path": "/machine/peripheral/cpu-2",
|
||||||
|
"target": "x86_64",
|
||||||
|
"thread-id": 29095
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -123,10 +121,10 @@ From the 'qmp-shell', invoke the QMP ``device_del`` command::
|
||||||
|
|
||||||
(QEMU) device_del id=cpu-2
|
(QEMU) device_del id=cpu-2
|
||||||
{
|
{
|
||||||
"execute": "device_del",
|
|
||||||
"arguments": {
|
"arguments": {
|
||||||
"id": "cpu-2"
|
"id": "cpu-2"
|
||||||
}
|
}
|
||||||
|
"execute": "device_del",
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
"return": {}
|
"return": {}
|
||||||
|
|
|
@ -63,10 +63,6 @@ large amounts of RAM. It also supports 64-bit CPUs.
|
||||||
Board-specific documentation
|
Board-specific documentation
|
||||||
============================
|
============================
|
||||||
|
|
||||||
Unfortunately many of the Arm boards QEMU supports are currently
|
|
||||||
undocumented; you can get a complete list by running
|
|
||||||
``qemu-system-aarch64 --machine help``.
|
|
||||||
|
|
||||||
..
|
..
|
||||||
This table of contents should be kept sorted alphabetically
|
This table of contents should be kept sorted alphabetically
|
||||||
by the title text of each file, which isn't the same ordering
|
by the title text of each file, which isn't the same ordering
|
||||||
|
@ -90,11 +86,15 @@ undocumented; you can get a complete list by running
|
||||||
arm/digic
|
arm/digic
|
||||||
arm/cubieboard
|
arm/cubieboard
|
||||||
arm/emcraft-sf2
|
arm/emcraft-sf2
|
||||||
|
arm/exynos
|
||||||
|
arm/fby35
|
||||||
arm/musicpal
|
arm/musicpal
|
||||||
arm/kzm
|
arm/kzm
|
||||||
arm/nrf
|
arm/nrf
|
||||||
arm/nuvoton
|
arm/nuvoton
|
||||||
arm/imx25-pdk
|
arm/imx25-pdk
|
||||||
|
arm/mcimx6ul-evk
|
||||||
|
arm/mcimx7d-sabre
|
||||||
arm/orangepi
|
arm/orangepi
|
||||||
arm/raspi
|
arm/raspi
|
||||||
arm/collie
|
arm/collie
|
||||||
|
@ -105,6 +105,7 @@ undocumented; you can get a complete list by running
|
||||||
arm/xenpvh
|
arm/xenpvh
|
||||||
arm/xlnx-versal-virt
|
arm/xlnx-versal-virt
|
||||||
arm/xlnx-zynq
|
arm/xlnx-zynq
|
||||||
|
arm/xlnx-zcu102
|
||||||
|
|
||||||
Emulated CPU architecture support
|
Emulated CPU architecture support
|
||||||
=================================
|
=================================
|
||||||
|
|
|
@ -2213,7 +2213,7 @@ static void machvirt_init(MachineState *machine)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vms->mte && (kvm_enabled() || hvf_enabled())) {
|
if (vms->mte && hvf_enabled()) {
|
||||||
error_report("mach-virt: %s does not support providing "
|
error_report("mach-virt: %s does not support providing "
|
||||||
"MTE to the guest CPU",
|
"MTE to the guest CPU",
|
||||||
current_accel_name());
|
current_accel_name());
|
||||||
|
@ -2283,6 +2283,7 @@ static void machvirt_init(MachineState *machine)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vms->mte) {
|
if (vms->mte) {
|
||||||
|
if (tcg_enabled()) {
|
||||||
/* Create the memory region only once, but link to all cpus. */
|
/* Create the memory region only once, but link to all cpus. */
|
||||||
if (!tag_sysmem) {
|
if (!tag_sysmem) {
|
||||||
/*
|
/*
|
||||||
|
@ -2302,21 +2303,32 @@ static void machvirt_init(MachineState *machine)
|
||||||
if (vms->secure) {
|
if (vms->secure) {
|
||||||
secure_tag_sysmem = g_new(MemoryRegion, 1);
|
secure_tag_sysmem = g_new(MemoryRegion, 1);
|
||||||
memory_region_init(secure_tag_sysmem, OBJECT(machine),
|
memory_region_init(secure_tag_sysmem, OBJECT(machine),
|
||||||
"secure-tag-memory", UINT64_MAX / 32);
|
"secure-tag-memory",
|
||||||
|
UINT64_MAX / 32);
|
||||||
|
|
||||||
/* As with ram, secure-tag takes precedence over tag. */
|
/* As with ram, secure-tag takes precedence over tag. */
|
||||||
memory_region_add_subregion_overlap(secure_tag_sysmem, 0,
|
memory_region_add_subregion_overlap(secure_tag_sysmem,
|
||||||
tag_sysmem, -1);
|
0, tag_sysmem, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object_property_set_link(cpuobj, "tag-memory", OBJECT(tag_sysmem),
|
object_property_set_link(cpuobj, "tag-memory",
|
||||||
&error_abort);
|
OBJECT(tag_sysmem), &error_abort);
|
||||||
if (vms->secure) {
|
if (vms->secure) {
|
||||||
object_property_set_link(cpuobj, "secure-tag-memory",
|
object_property_set_link(cpuobj, "secure-tag-memory",
|
||||||
OBJECT(secure_tag_sysmem),
|
OBJECT(secure_tag_sysmem),
|
||||||
&error_abort);
|
&error_abort);
|
||||||
}
|
}
|
||||||
|
} else if (kvm_enabled()) {
|
||||||
|
if (!kvm_arm_mte_supported()) {
|
||||||
|
error_report("MTE requested, but not supported by KVM");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
kvm_arm_enable_mte(cpuobj, &error_abort);
|
||||||
|
} else {
|
||||||
|
error_report("MTE requested, but not supported ");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
|
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
|
||||||
|
|
|
@ -547,17 +547,10 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
|
||||||
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true,
|
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
}
|
}
|
||||||
} else if (kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) {
|
} else {
|
||||||
error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
|
error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
|
||||||
error_append_hint(errp,
|
error_append_hint(errp,
|
||||||
"Perhaps the host CPU does not support GICv2?\n");
|
"Perhaps the host CPU does not support GICv2?\n");
|
||||||
} else if (ret != -ENODEV && ret != -ENOTSUP) {
|
|
||||||
/*
|
|
||||||
* Very ancient kernel without KVM_CAP_DEVICE_CTRL: assume that
|
|
||||||
* ENODEV or ENOTSUP mean "can't create GICv2 with KVM_CREATE_DEVICE",
|
|
||||||
* and that we will get a GICv2 via KVM_CREATE_IRQCHIP.
|
|
||||||
*/
|
|
||||||
error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ static void omap_mmc_fifolevel_update(struct omap_mmc_s *host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* These must match the encoding of the MMC_CMD Response field */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
sd_nore = 0, /* no response */
|
sd_nore = 0, /* no response */
|
||||||
sd_r1, /* normal response command */
|
sd_r1, /* normal response command */
|
||||||
|
@ -112,8 +113,17 @@ typedef enum {
|
||||||
sd_r1b = -1,
|
sd_r1b = -1,
|
||||||
} sd_rsp_type_t;
|
} sd_rsp_type_t;
|
||||||
|
|
||||||
|
/* These must match the encoding of the MMC_CMD Type field */
|
||||||
|
typedef enum {
|
||||||
|
SD_TYPE_BC = 0, /* broadcast -- no response */
|
||||||
|
SD_TYPE_BCR = 1, /* broadcast with response */
|
||||||
|
SD_TYPE_AC = 2, /* addressed -- no data transfer */
|
||||||
|
SD_TYPE_ADTC = 3, /* addressed with data transfer */
|
||||||
|
} MMCCmdType;
|
||||||
|
|
||||||
static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
|
static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
|
||||||
sd_cmd_type_t type, int busy, sd_rsp_type_t resptype, int init)
|
MMCCmdType type, int busy,
|
||||||
|
sd_rsp_type_t resptype, int init)
|
||||||
{
|
{
|
||||||
uint32_t rspstatus, mask;
|
uint32_t rspstatus, mask;
|
||||||
int rsplen, timeout;
|
int rsplen, timeout;
|
||||||
|
@ -128,7 +138,7 @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
|
||||||
if (resptype == sd_r1 && busy)
|
if (resptype == sd_r1 && busy)
|
||||||
resptype = sd_r1b;
|
resptype = sd_r1b;
|
||||||
|
|
||||||
if (type == sd_adtc) {
|
if (type == SD_TYPE_ADTC) {
|
||||||
host->fifo_start = 0;
|
host->fifo_start = 0;
|
||||||
host->fifo_len = 0;
|
host->fifo_len = 0;
|
||||||
host->transfer = 1;
|
host->transfer = 1;
|
||||||
|
@ -433,7 +443,7 @@ static void omap_mmc_write(void *opaque, hwaddr offset,
|
||||||
for (i = 0; i < 8; i ++)
|
for (i = 0; i < 8; i ++)
|
||||||
s->rsp[i] = 0x0000;
|
s->rsp[i] = 0x0000;
|
||||||
omap_mmc_command(s, value & 63, (value >> 15) & 1,
|
omap_mmc_command(s, value & 63, (value >> 15) & 1,
|
||||||
(sd_cmd_type_t) ((value >> 12) & 3),
|
(MMCCmdType)((value >> 12) & 3),
|
||||||
(value >> 11) & 1,
|
(value >> 11) & 1,
|
||||||
(sd_rsp_type_t) ((value >> 8) & 7),
|
(sd_rsp_type_t) ((value >> 8) & 7),
|
||||||
(value >> 7) & 1);
|
(value >> 7) & 1);
|
||||||
|
|
|
@ -71,6 +71,14 @@ typedef enum {
|
||||||
sd_illegal = -2,
|
sd_illegal = -2,
|
||||||
} sd_rsp_type_t;
|
} sd_rsp_type_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
sd_spi,
|
||||||
|
sd_bc, /* broadcast -- no response */
|
||||||
|
sd_bcr, /* broadcast with response */
|
||||||
|
sd_ac, /* addressed -- no data transfer */
|
||||||
|
sd_adtc, /* addressed with data transfer */
|
||||||
|
} sd_cmd_type_t;
|
||||||
|
|
||||||
enum SDCardModes {
|
enum SDCardModes {
|
||||||
sd_inactive,
|
sd_inactive,
|
||||||
sd_card_identification_mode,
|
sd_card_identification_mode,
|
||||||
|
|
|
@ -75,14 +75,6 @@ typedef enum {
|
||||||
UHS_III = 3, /* currently not supported */
|
UHS_III = 3, /* currently not supported */
|
||||||
} sd_uhs_mode_t;
|
} sd_uhs_mode_t;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
sd_spi,
|
|
||||||
sd_bc, /* broadcast -- no response */
|
|
||||||
sd_bcr, /* broadcast with response */
|
|
||||||
sd_ac, /* addressed -- no data transfer */
|
|
||||||
sd_adtc, /* addressed with data transfer */
|
|
||||||
} sd_cmd_type_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
uint32_t arg;
|
uint32_t arg;
|
||||||
|
|
|
@ -4,6 +4,7 @@ from pathlib import PurePath
|
||||||
import errno
|
import errno
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ def destdir_join(d1: str, d2: str) -> str:
|
||||||
return str(PurePath(d1, *PurePath(d2).parts[1:]))
|
return str(PurePath(d1, *PurePath(d2).parts[1:]))
|
||||||
|
|
||||||
introspect = os.environ.get('MESONINTROSPECT')
|
introspect = os.environ.get('MESONINTROSPECT')
|
||||||
out = subprocess.run([*introspect.split(' '), '--installed'],
|
out = subprocess.run([*shlex.split(introspect), '--installed'],
|
||||||
stdout=subprocess.PIPE, check=True).stdout
|
stdout=subprocess.PIPE, check=True).stdout
|
||||||
for source, dest in json.loads(out).items():
|
for source, dest in json.loads(out).items():
|
||||||
bundle_dest = destdir_join('qemu-bundle', dest)
|
bundle_dest = destdir_join('qemu-bundle', dest)
|
||||||
|
|
|
@ -2390,14 +2390,22 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
/*
|
/*
|
||||||
* If we do not have tag-memory provided by the machine,
|
* If we run with TCG and do not have tag-memory provided by
|
||||||
* reduce MTE support to instructions enabled at EL0.
|
* the machine, then reduce MTE support to instructions enabled at EL0.
|
||||||
* This matches Cortex-A710 BROADCASTMTE input being LOW.
|
* This matches Cortex-A710 BROADCASTMTE input being LOW.
|
||||||
*/
|
*/
|
||||||
if (cpu->tag_memory == NULL) {
|
if (tcg_enabled() && cpu->tag_memory == NULL) {
|
||||||
cpu->isar.id_aa64pfr1 =
|
cpu->isar.id_aa64pfr1 =
|
||||||
FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 1);
|
FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If MTE is supported by the host, however it should not be
|
||||||
|
* enabled on the guest (i.e mte=off), clear guest's MTE bits."
|
||||||
|
*/
|
||||||
|
if (kvm_enabled() && !cpu->kvm_mte) {
|
||||||
|
FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -922,6 +922,8 @@ struct ArchCPU {
|
||||||
|
|
||||||
/* CPU has memory protection unit */
|
/* CPU has memory protection unit */
|
||||||
bool has_mpu;
|
bool has_mpu;
|
||||||
|
/* CPU has MTE enabled in KVM mode */
|
||||||
|
bool kvm_mte;
|
||||||
/* PMSAv7 MPU number of supported regions */
|
/* PMSAv7 MPU number of supported regions */
|
||||||
uint32_t pmsav7_dregion;
|
uint32_t pmsav7_dregion;
|
||||||
/* PMSAv8 MPU number of supported hyp regions */
|
/* PMSAv8 MPU number of supported hyp regions */
|
||||||
|
|
|
@ -963,6 +963,7 @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||||
static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
|
static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||||
{
|
{
|
||||||
switch (mmu_idx) {
|
switch (mmu_idx) {
|
||||||
|
case ARMMMUIdx_E10_0:
|
||||||
case ARMMMUIdx_E20_0:
|
case ARMMMUIdx_E20_0:
|
||||||
case ARMMMUIdx_Stage1_E0:
|
case ARMMMUIdx_Stage1_E0:
|
||||||
case ARMMMUIdx_MUser:
|
case ARMMMUIdx_MUser:
|
||||||
|
@ -972,10 +973,6 @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
case ARMMMUIdx_E10_0:
|
|
||||||
case ARMMMUIdx_E10_1:
|
|
||||||
case ARMMMUIdx_E10_1_PAN:
|
|
||||||
g_assert_not_reached();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,10 @@
|
||||||
#include "hw/acpi/acpi.h"
|
#include "hw/acpi/acpi.h"
|
||||||
#include "hw/acpi/ghes.h"
|
#include "hw/acpi/ghes.h"
|
||||||
#include "target/arm/gtimer.h"
|
#include "target/arm/gtimer.h"
|
||||||
|
#include "migration/blocker.h"
|
||||||
|
|
||||||
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
|
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
|
||||||
|
KVM_CAP_INFO(DEVICE_CTRL),
|
||||||
KVM_CAP_LAST_INFO
|
KVM_CAP_LAST_INFO
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,6 +121,21 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
|
||||||
if (vmfd < 0) {
|
if (vmfd < 0) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MTE capability must be enabled by the VMM before creating
|
||||||
|
* any VCPUs in order to allow the MTE bits of the ID_AA64PFR1
|
||||||
|
* register to be probed correctly, as they are masked if MTE
|
||||||
|
* is not enabled.
|
||||||
|
*/
|
||||||
|
if (kvm_arm_mte_supported()) {
|
||||||
|
KVMState kvm_state;
|
||||||
|
|
||||||
|
kvm_state.fd = kvmfd;
|
||||||
|
kvm_state.vmfd = vmfd;
|
||||||
|
kvm_vm_enable_cap(&kvm_state, KVM_CAP_ARM_MTE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
|
cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
|
||||||
if (cpufd < 0) {
|
if (cpufd < 0) {
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -675,19 +692,11 @@ static void kvm_arm_set_device_addr(KVMDevice *kd)
|
||||||
{
|
{
|
||||||
struct kvm_device_attr *attr = &kd->kdattr;
|
struct kvm_device_attr *attr = &kd->kdattr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* If the device control API is available and we have a device fd on the
|
|
||||||
* KVMDevice struct, let's use the newer API
|
|
||||||
*/
|
|
||||||
if (kd->dev_fd >= 0) {
|
|
||||||
uint64_t addr = kd->kda.addr;
|
uint64_t addr = kd->kda.addr;
|
||||||
|
|
||||||
addr |= kd->kda_addr_ormask;
|
addr |= kd->kda_addr_ormask;
|
||||||
attr->addr = (uintptr_t)&addr;
|
attr->addr = (uintptr_t)&addr;
|
||||||
ret = kvm_device_ioctl(kd->dev_fd, KVM_SET_DEVICE_ATTR, attr);
|
ret = kvm_device_ioctl(kd->dev_fd, KVM_SET_DEVICE_ATTR, attr);
|
||||||
} else {
|
|
||||||
ret = kvm_vm_ioctl(kvm_state, KVM_ARM_SET_DEVICE_ADDR, &kd->kda);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Failed to set device address: %s\n",
|
fprintf(stderr, "Failed to set device address: %s\n",
|
||||||
|
@ -1793,6 +1802,11 @@ bool kvm_arm_sve_supported(void)
|
||||||
return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
|
return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool kvm_arm_mte_supported(void)
|
||||||
|
{
|
||||||
|
return kvm_check_extension(kvm_state, KVM_CAP_ARM_MTE);
|
||||||
|
}
|
||||||
|
|
||||||
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
|
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
|
||||||
|
|
||||||
uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
|
uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
|
||||||
|
@ -2417,3 +2431,40 @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
|
||||||
|
{
|
||||||
|
static bool tried_to_enable;
|
||||||
|
static bool succeeded_to_enable;
|
||||||
|
Error *mte_migration_blocker = NULL;
|
||||||
|
ARMCPU *cpu = ARM_CPU(cpuobj);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!tried_to_enable) {
|
||||||
|
/*
|
||||||
|
* MTE on KVM is enabled on a per-VM basis (and retrying doesn't make
|
||||||
|
* sense), and we only want a single migration blocker as well.
|
||||||
|
*/
|
||||||
|
tried_to_enable = true;
|
||||||
|
|
||||||
|
ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_MTE, 0);
|
||||||
|
if (ret) {
|
||||||
|
error_setg_errno(errp, -ret, "Failed to enable KVM_CAP_ARM_MTE");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Add migration support with MTE enabled */
|
||||||
|
error_setg(&mte_migration_blocker,
|
||||||
|
"Live migration disabled due to MTE enabled");
|
||||||
|
if (migrate_add_blocker(&mte_migration_blocker, errp)) {
|
||||||
|
error_free(mte_migration_blocker);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
succeeded_to_enable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (succeeded_to_enable) {
|
||||||
|
cpu->kvm_mte = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,17 +22,15 @@
|
||||||
* @devid: the KVM device ID
|
* @devid: the KVM device ID
|
||||||
* @group: device control API group for setting addresses
|
* @group: device control API group for setting addresses
|
||||||
* @attr: device control API address type
|
* @attr: device control API address type
|
||||||
* @dev_fd: device control device file descriptor (or -1 if not supported)
|
* @dev_fd: device control device file descriptor
|
||||||
* @addr_ormask: value to be OR'ed with resolved address
|
* @addr_ormask: value to be OR'ed with resolved address
|
||||||
*
|
*
|
||||||
* Remember the memory region @mr, and when it is mapped by the
|
* Remember the memory region @mr, and when it is mapped by the machine
|
||||||
* machine model, tell the kernel that base address using the
|
* model, tell the kernel that base address using the device control API.
|
||||||
* KVM_ARM_SET_DEVICE_ADDRESS ioctl or the newer device control API. @devid
|
* @devid should be the ID of the device as defined by the arm-vgic device
|
||||||
* should be the ID of the device as defined by KVM_ARM_SET_DEVICE_ADDRESS or
|
* in the device control API. The machine model may map and unmap the device
|
||||||
* the arm-vgic device in the device control API.
|
* multiple times; the kernel will only be told the final address at the
|
||||||
* The machine model may map
|
* point where machine init is complete.
|
||||||
* and unmap the device multiple times; the kernel will only be told the final
|
|
||||||
* address at the point where machine init is complete.
|
|
||||||
*/
|
*/
|
||||||
void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
|
void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
|
||||||
uint64_t attr, int dev_fd, uint64_t addr_ormask);
|
uint64_t attr, int dev_fd, uint64_t addr_ormask);
|
||||||
|
@ -188,6 +186,13 @@ bool kvm_arm_pmu_supported(void);
|
||||||
*/
|
*/
|
||||||
bool kvm_arm_sve_supported(void);
|
bool kvm_arm_sve_supported(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kvm_arm_mte_supported:
|
||||||
|
*
|
||||||
|
* Returns: true if KVM can enable MTE, and false otherwise.
|
||||||
|
*/
|
||||||
|
bool kvm_arm_mte_supported(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kvm_arm_get_max_vm_ipa_size:
|
* kvm_arm_get_max_vm_ipa_size:
|
||||||
* @ms: Machine state handle
|
* @ms: Machine state handle
|
||||||
|
@ -214,6 +219,8 @@ void kvm_arm_pvtime_init(ARMCPU *cpu, uint64_t ipa);
|
||||||
|
|
||||||
int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
|
int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
|
||||||
|
|
||||||
|
void kvm_arm_enable_mte(Object *cpuobj, Error **errp);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -235,6 +242,11 @@ static inline bool kvm_arm_sve_supported(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool kvm_arm_mte_supported(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These functions should never actually be called without KVM support.
|
* These functions should never actually be called without KVM support.
|
||||||
*/
|
*/
|
||||||
|
@ -283,6 +295,11 @@ static inline uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
|
||||||
|
{
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1348,7 +1348,7 @@ static void do_setm(CPUARMState *env, uint32_t syndrome, uint32_t mtedesc,
|
||||||
/* Do the actual memset: we leave the last partial page to SETE */
|
/* Do the actual memset: we leave the last partial page to SETE */
|
||||||
stagesetsize = setsize & TARGET_PAGE_MASK;
|
stagesetsize = setsize & TARGET_PAGE_MASK;
|
||||||
while (stagesetsize > 0) {
|
while (stagesetsize > 0) {
|
||||||
step = stepfn(env, toaddr, setsize, data, memidx, &mtedesc, ra);
|
step = stepfn(env, toaddr, stagesetsize, data, memidx, &mtedesc, ra);
|
||||||
toaddr += step;
|
toaddr += step;
|
||||||
setsize -= step;
|
setsize -= step;
|
||||||
stagesetsize -= step;
|
stagesetsize -= step;
|
||||||
|
|
|
@ -59,32 +59,6 @@ static inline int vfp_exceptbits_from_host(int host_bits)
|
||||||
return target_bits;
|
return target_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert vfp exception flags to target form. */
|
|
||||||
static inline int vfp_exceptbits_to_host(int target_bits)
|
|
||||||
{
|
|
||||||
int host_bits = 0;
|
|
||||||
|
|
||||||
if (target_bits & 1) {
|
|
||||||
host_bits |= float_flag_invalid;
|
|
||||||
}
|
|
||||||
if (target_bits & 2) {
|
|
||||||
host_bits |= float_flag_divbyzero;
|
|
||||||
}
|
|
||||||
if (target_bits & 4) {
|
|
||||||
host_bits |= float_flag_overflow;
|
|
||||||
}
|
|
||||||
if (target_bits & 8) {
|
|
||||||
host_bits |= float_flag_underflow;
|
|
||||||
}
|
|
||||||
if (target_bits & 0x10) {
|
|
||||||
host_bits |= float_flag_inexact;
|
|
||||||
}
|
|
||||||
if (target_bits & 0x80) {
|
|
||||||
host_bits |= float_flag_input_denormal;
|
|
||||||
}
|
|
||||||
return host_bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t vfp_get_fpsr_from_host(CPUARMState *env)
|
static uint32_t vfp_get_fpsr_from_host(CPUARMState *env)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -99,15 +73,14 @@ static uint32_t vfp_get_fpsr_from_host(CPUARMState *env)
|
||||||
return vfp_exceptbits_from_host(i);
|
return vfp_exceptbits_from_host(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vfp_set_fpsr_to_host(CPUARMState *env, uint32_t val)
|
static void vfp_clear_float_status_exc_flags(CPUARMState *env)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The exception flags are ORed together when we read fpscr so we
|
* Clear out all the exception-flag information in the float_status
|
||||||
* only need to preserve the current state in one of our
|
* values. The caller should have arranged for env->vfp.fpsr to
|
||||||
* float_status values.
|
* be the architecturally up-to-date exception flag information first.
|
||||||
*/
|
*/
|
||||||
int i = vfp_exceptbits_to_host(val);
|
set_float_exception_flags(0, &env->vfp.fp_status);
|
||||||
set_float_exception_flags(i, &env->vfp.fp_status);
|
|
||||||
set_float_exception_flags(0, &env->vfp.fp_status_f16);
|
set_float_exception_flags(0, &env->vfp.fp_status_f16);
|
||||||
set_float_exception_flags(0, &env->vfp.standard_fp_status);
|
set_float_exception_flags(0, &env->vfp.standard_fp_status);
|
||||||
set_float_exception_flags(0, &env->vfp.standard_fp_status_f16);
|
set_float_exception_flags(0, &env->vfp.standard_fp_status_f16);
|
||||||
|
@ -164,7 +137,7 @@ static uint32_t vfp_get_fpsr_from_host(CPUARMState *env)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vfp_set_fpsr_to_host(CPUARMState *env, uint32_t val)
|
static void vfp_clear_float_status_exc_flags(CPUARMState *env)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,8 +189,6 @@ void vfp_set_fpsr(CPUARMState *env, uint32_t val)
|
||||||
{
|
{
|
||||||
ARMCPU *cpu = env_archcpu(env);
|
ARMCPU *cpu = env_archcpu(env);
|
||||||
|
|
||||||
vfp_set_fpsr_to_host(env, val);
|
|
||||||
|
|
||||||
if (arm_feature(env, ARM_FEATURE_NEON) ||
|
if (arm_feature(env, ARM_FEATURE_NEON) ||
|
||||||
cpu_isar_feature(aa32_mve, cpu)) {
|
cpu_isar_feature(aa32_mve, cpu)) {
|
||||||
/*
|
/*
|
||||||
|
@ -231,13 +202,18 @@ void vfp_set_fpsr(CPUARMState *env, uint32_t val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The only FPSR bits we keep in vfp.fpsr are NZCV:
|
* NZCV lives only in env->vfp.fpsr. The cumulative exception flags
|
||||||
* the exception flags IOC|DZC|OFC|UFC|IXC|IDC are stored in
|
* IOC|DZC|OFC|UFC|IXC|IDC also live in env->vfp.fpsr, with possible
|
||||||
* fp_status, and QC is in vfp.qc[]. Store the NZCV bits there,
|
* extra pending exception information that hasn't yet been folded in
|
||||||
* and zero any of the other FPSR bits.
|
* living in the float_status values (for TCG).
|
||||||
|
* Since this FPSR write gives us the up to date values of the exception
|
||||||
|
* flags, we want to store into vfp.fpsr the NZCV and CEXC bits, zeroing
|
||||||
|
* anything else. We also need to clear out the float_status exception
|
||||||
|
* information so that the next vfp_get_fpsr does not fold in stale data.
|
||||||
*/
|
*/
|
||||||
val &= FPSR_NZCV_MASK;
|
val &= FPSR_NZCV_MASK | FPSR_CEXC_MASK;
|
||||||
env->vfp.fpsr = val;
|
env->vfp.fpsr = val;
|
||||||
|
vfp_clear_float_status_exc_flags(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vfp_set_fpcr_masked(CPUARMState *env, uint32_t val, uint32_t mask)
|
static void vfp_set_fpcr_masked(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||||
|
|
|
@ -18,6 +18,7 @@ test_timeouts = {
|
||||||
'arm_aspeed' : 600,
|
'arm_aspeed' : 600,
|
||||||
'arm_raspi2' : 120,
|
'arm_raspi2' : 120,
|
||||||
'arm_tuxrun' : 120,
|
'arm_tuxrun' : 120,
|
||||||
|
'arm_sx1' : 360,
|
||||||
'mips_malta' : 120,
|
'mips_malta' : 120,
|
||||||
'netdev_ethtool' : 180,
|
'netdev_ethtool' : 180,
|
||||||
'ppc_40p' : 240,
|
'ppc_40p' : 240,
|
||||||
|
@ -54,8 +55,10 @@ tests_alpha_system_thorough = [
|
||||||
tests_arm_system_thorough = [
|
tests_arm_system_thorough = [
|
||||||
'arm_aspeed',
|
'arm_aspeed',
|
||||||
'arm_canona1100',
|
'arm_canona1100',
|
||||||
|
'arm_collie',
|
||||||
'arm_integratorcp',
|
'arm_integratorcp',
|
||||||
'arm_raspi2',
|
'arm_raspi2',
|
||||||
|
'arm_sx1',
|
||||||
'arm_vexpress',
|
'arm_vexpress',
|
||||||
'arm_tuxrun',
|
'arm_tuxrun',
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Functional test that boots a Linux kernel on a collie machine
|
||||||
|
# and checks the console
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
from qemu_test import LinuxKernelTest, Asset
|
||||||
|
from qemu_test.utils import archive_extract
|
||||||
|
|
||||||
|
class CollieTest(LinuxKernelTest):
|
||||||
|
|
||||||
|
ASSET_ZIMAGE = Asset(
|
||||||
|
'https://github.com/groeck/linux-test-downloads/raw/225223f2ad7d637b34426810bf6c3b727b76a718/collie/zImage',
|
||||||
|
'10ace8abf9e0875ef8a83b8829cc3b5b50bc6d7bc3ca29f19f49f5673a43c13b')
|
||||||
|
|
||||||
|
ASSET_ROOTFS = Asset(
|
||||||
|
'https://github.com/groeck/linux-test-downloads/raw/225223f2ad7d637b34426810bf6c3b727b76a718/collie/rootfs-sa110.cpio',
|
||||||
|
'89ccaaa5c6b33331887047e1618ffe81b0f55909173944347d5d2426f3bcc1f2')
|
||||||
|
|
||||||
|
def test_arm_collie(self):
|
||||||
|
self.set_machine('collie')
|
||||||
|
zimage_path = self.ASSET_ZIMAGE.fetch()
|
||||||
|
rootfs_path = self.ASSET_ROOTFS.fetch()
|
||||||
|
self.vm.add_args('-append', 'rdinit=/sbin/init console=ttySA1')
|
||||||
|
self.launch_kernel(zimage_path,
|
||||||
|
initrd=rootfs_path,
|
||||||
|
wait_for='reboot: Restarting system')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
LinuxKernelTest.main()
|
|
@ -0,0 +1,72 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 Linaro Ltd.
|
||||||
|
#
|
||||||
|
# Functional test that boots a Linux kernel on an sx1 machine
|
||||||
|
# and checks the console. We have three variants:
|
||||||
|
# * just boot initrd
|
||||||
|
# * boot with filesystem on SD card
|
||||||
|
# * boot from flash
|
||||||
|
# In all cases these images have a userspace that is configured
|
||||||
|
# to immediately reboot the system on successful boot, so we
|
||||||
|
# only need to wait for QEMU to exit (via -no-reboot).
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
from qemu_test import LinuxKernelTest, Asset
|
||||||
|
from qemu_test.utils import archive_extract
|
||||||
|
|
||||||
|
class SX1Test(LinuxKernelTest):
|
||||||
|
|
||||||
|
ASSET_ZIMAGE = Asset(
|
||||||
|
'https://github.com/groeck/linux-test-downloads/raw/225223f2ad7d637b34426810bf6c3b727b76a718/sx1/zImage',
|
||||||
|
'a0271899a8dc2165f9e0adb2d0a57fc839ae3a469722ffc56c77e108a8887615')
|
||||||
|
|
||||||
|
ASSET_INITRD = Asset(
|
||||||
|
'https://github.com/groeck/linux-test-downloads/raw/225223f2ad7d637b34426810bf6c3b727b76a718/sx1/rootfs-armv4.cpio',
|
||||||
|
'35b0721249821aa544cd85b85d3cb8901db4c6d128eed86ab261e5d9e37d58f8')
|
||||||
|
|
||||||
|
ASSET_SD_FS = Asset(
|
||||||
|
'https://github.com/groeck/linux-test-downloads/raw/225223f2ad7d637b34426810bf6c3b727b76a718/sx1/rootfs-armv4.ext2',
|
||||||
|
'c1db7f43ef92469ebc8605013728c8950e7608439f01d13678994f0ce101c3a8')
|
||||||
|
|
||||||
|
ASSET_FLASH = Asset(
|
||||||
|
'https://github.com/groeck/linux-test-downloads/raw/225223f2ad7d637b34426810bf6c3b727b76a718/sx1/flash',
|
||||||
|
'17e6a2758fa38efd2666be0879d4751fd37d194f25168a8deede420df519b676')
|
||||||
|
|
||||||
|
CONSOLE_ARGS = 'console=ttyS0,115200 earlycon=uart8250,mmio32,0xfffb0000,115200n8'
|
||||||
|
|
||||||
|
def test_arm_sx1_initrd(self):
|
||||||
|
self.set_machine('sx1')
|
||||||
|
zimage_path = self.ASSET_ZIMAGE.fetch()
|
||||||
|
initrd_path = self.ASSET_INITRD.fetch()
|
||||||
|
self.vm.add_args('-append', f'kunit.enable=0 rdinit=/sbin/init {self.CONSOLE_ARGS}')
|
||||||
|
self.vm.add_args('-no-reboot')
|
||||||
|
self.launch_kernel(zimage_path,
|
||||||
|
initrd=initrd_path)
|
||||||
|
self.vm.wait()
|
||||||
|
|
||||||
|
def test_arm_sx1_sd(self):
|
||||||
|
self.set_machine('sx1')
|
||||||
|
zimage_path = self.ASSET_ZIMAGE.fetch()
|
||||||
|
sd_fs_path = self.ASSET_SD_FS.fetch()
|
||||||
|
self.vm.add_args('-append', f'kunit.enable=0 root=/dev/mmcblk0 rootwait {self.CONSOLE_ARGS}')
|
||||||
|
self.vm.add_args('-no-reboot')
|
||||||
|
self.vm.add_args('-snapshot')
|
||||||
|
self.vm.add_args('-drive', f'format=raw,if=sd,file={sd_fs_path}')
|
||||||
|
self.launch_kernel(zimage_path)
|
||||||
|
self.vm.wait()
|
||||||
|
|
||||||
|
def test_arm_sx1_flash(self):
|
||||||
|
self.set_machine('sx1')
|
||||||
|
zimage_path = self.ASSET_ZIMAGE.fetch()
|
||||||
|
flash_path = self.ASSET_FLASH.fetch()
|
||||||
|
self.vm.add_args('-append', f'kunit.enable=0 root=/dev/mtdblock3 rootwait {self.CONSOLE_ARGS}')
|
||||||
|
self.vm.add_args('-no-reboot')
|
||||||
|
self.vm.add_args('-snapshot')
|
||||||
|
self.vm.add_args('-drive', f'format=raw,if=pflash,file={flash_path}')
|
||||||
|
self.launch_kernel(zimage_path)
|
||||||
|
self.vm.wait()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
LinuxKernelTest.main()
|
Loading…
Reference in New Issue