aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.d/edk2.yml27
-rw-r--r--.gitlab-ci.d/static_checks.yml1
-rw-r--r--MAINTAINERS5
-rw-r--r--docs/devel/testing.rst82
-rw-r--r--hw/i386/Kconfig4
-rw-r--r--hw/i386/meson.build2
-rw-r--r--hw/i386/pc_sysfw.c107
-rw-r--r--hw/i386/pc_sysfw_ovmf-stubs.c26
-rw-r--r--hw/i386/pc_sysfw_ovmf.c151
-rw-r--r--include/hw/i386/pc.h1
-rw-r--r--python/Makefile5
-rw-r--r--python/qemu/machine/machine.py22
-rw-r--r--python/setup.cfg1
-rw-r--r--qga/commands-win32.c3
-rw-r--r--target/alpha/translate.c70
-rw-r--r--target/hppa/translate.c99
-rw-r--r--target/i386/cpu.h2
-rw-r--r--target/i386/tcg/fpu_helper.c42
-rw-r--r--target/i386/tcg/sysemu/bpt_helper.c4
-rw-r--r--target/i386/tcg/translate.c920
-rw-r--r--target/openrisc/translate.c68
-rw-r--r--tests/Makefile.include2
-rw-r--r--tests/acceptance/avocado_qemu/__init__.py179
-rw-r--r--tests/acceptance/boot_linux.py11
-rw-r--r--tests/acceptance/boot_linux_console.py14
-rw-r--r--tests/acceptance/boot_xen.py1
-rw-r--r--tests/acceptance/cpu_queries.py4
-rw-r--r--tests/acceptance/intel_iommu.py119
-rw-r--r--tests/acceptance/linux_ssh_mips_malta.py7
-rw-r--r--tests/acceptance/machine_mips_malta.py7
-rw-r--r--tests/acceptance/pc_cpu_hotplug_props.py2
-rw-r--r--tests/acceptance/ppc_prep_40p.py2
-rw-r--r--tests/acceptance/replay_kernel.py17
-rw-r--r--tests/acceptance/reverse_debugging.py2
-rw-r--r--tests/acceptance/smmu.py137
-rw-r--r--tests/acceptance/tcg_plugins.py15
-rw-r--r--tests/acceptance/virtio-gpu.py4
-rw-r--r--tests/acceptance/x86_cpu_model_versions.py40
38 files changed, 1380 insertions, 825 deletions
diff --git a/.gitlab-ci.d/edk2.yml b/.gitlab-ci.d/edk2.yml
index ba7280605c..aae2f7ad88 100644
--- a/.gitlab-ci.d/edk2.yml
+++ b/.gitlab-ci.d/edk2.yml
@@ -1,10 +1,22 @@
-docker-edk2:
- stage: containers
- rules: # Only run this job when the Dockerfile is modified
+# All jobs needing docker-edk2 must use the same rules it uses.
+.edk2_job_rules:
+ rules: # Only run this job when ...
- changes:
+ # this file is modified
- .gitlab-ci.d/edk2.yml
+ # or the Dockerfile is modified
- .gitlab-ci.d/edk2/Dockerfile
+ # or roms/edk2/ is modified (submodule updated)
+ - roms/edk2/*
when: always
+ - if: '$CI_COMMIT_REF_NAME =~ /^edk2/' # or the branch/tag starts with 'edk2'
+ when: always
+ - if: '$CI_COMMIT_MESSAGE =~ /edk2/i' # or last commit description contains 'EDK2'
+ when: always
+
+docker-edk2:
+ extends: .edk2_job_rules
+ stage: containers
image: docker:19.03.1
services:
- docker:19.03.1-dind
@@ -24,16 +36,9 @@ docker-edk2:
- docker push $IMAGE_TAG
build-edk2:
+ extends: .edk2_job_rules
stage: build
needs: ['docker-edk2']
- rules: # Only run this job when ...
- - changes: # ... roms/edk2/ is modified (submodule updated)
- - roms/edk2/*
- when: always
- - if: '$CI_COMMIT_REF_NAME =~ /^edk2/' # or the branch/tag starts with 'edk2'
- when: always
- - if: '$CI_COMMIT_MESSAGE =~ /edk2/i' # or last commit description contains 'EDK2'
- when: always
artifacts:
paths: # 'artifacts.zip' will contains the following files:
- pc-bios/edk2*bz2
diff --git a/.gitlab-ci.d/static_checks.yml b/.gitlab-ci.d/static_checks.yml
index b01f6ec231..96dbd9e310 100644
--- a/.gitlab-ci.d/static_checks.yml
+++ b/.gitlab-ci.d/static_checks.yml
@@ -43,6 +43,7 @@ check-python-tox:
- make -C python check-tox
variables:
GIT_DEPTH: 1
+ QEMU_TOX_EXTRA_ARGS: --skip-missing-interpreters=false
needs:
job: python-container
allow_failure: true
diff --git a/MAINTAINERS b/MAINTAINERS
index c4439a9488..9100f9a043 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -171,6 +171,7 @@ L: qemu-arm@nongnu.org
S: Maintained
F: hw/arm/smmu*
F: include/hw/arm/smmu*
+F: tests/acceptance/smmu.py
AVR TCG CPUs
M: Michael Rolnik <mrolnik@gmail.com>
@@ -2201,7 +2202,6 @@ F: include/hw/southbridge/piix.h
Firmware configuration (fw_cfg)
M: Philippe Mathieu-Daudé <philmd@redhat.com>
-R: Laszlo Ersek <lersek@redhat.com>
R: Gerd Hoffmann <kraxel@redhat.com>
S: Supported
F: docs/specs/fw_cfg.txt
@@ -2933,7 +2933,6 @@ F: include/hw/i2c/smbus_slave.h
F: include/hw/i2c/smbus_eeprom.h
Firmware schema specifications
-M: Laszlo Ersek <lersek@redhat.com>
M: Philippe Mathieu-Daudé <philmd@redhat.com>
R: Daniel P. Berrange <berrange@redhat.com>
R: Kashyap Chamarthy <kchamart@redhat.com>
@@ -2941,9 +2940,9 @@ S: Maintained
F: docs/interop/firmware.json
EDK2 Firmware
-M: Laszlo Ersek <lersek@redhat.com>
M: Philippe Mathieu-Daudé <philmd@redhat.com>
S: Supported
+F: hw/i386/*ovmf*
F: pc-bios/descriptors/??-edk2-*.json
F: pc-bios/edk2-*
F: roms/Makefile.edk2
diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index 4e42392810..8f572255d3 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -904,6 +904,17 @@ name. If one is not given explicitly, it will either be set to
``None``, or, if the test is tagged with one (and only one)
``:avocado: tags=arch:VALUE`` tag, it will be set to ``VALUE``.
+cpu
+~~~
+
+The cpu model that will be set to all QEMUMachine instances created
+by the test.
+
+The ``cpu`` attribute will be set to the test parameter of the same
+name. If one is not given explicitly, it will either be set to
+``None ``, or, if the test is tagged with one (and only one)
+``:avocado: tags=cpu:VALUE`` tag, it will be set to ``VALUE``.
+
machine
~~~~~~~
@@ -922,6 +933,39 @@ The preserved value of the ``qemu_bin`` parameter or the result of the
dynamic probe for a QEMU binary in the current working directory or
source tree.
+LinuxTest
+~~~~~~~~~
+
+Besides the attributes present on the ``avocado_qemu.Test`` base
+class, the ``avocado_qemu.LinuxTest`` adds the following attributes:
+
+distro
+......
+
+The name of the Linux distribution used as the guest image for the
+test. The name should match the **Provider** column on the list
+of images supported by the avocado.utils.vmimage library:
+
+https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
+
+distro_version
+..............
+
+The version of the Linux distribution as the guest image for the
+test. The name should match the **Version** column on the list
+of images supported by the avocado.utils.vmimage library:
+
+https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
+
+distro_checksum
+...............
+
+The sha256 hash of the guest image file used for the test.
+
+If this value is not set in the code or by a test parameter (with the
+same name), no validation on the integrity of the image will be
+performed.
+
Parameter reference
-------------------
@@ -950,6 +994,12 @@ architecture of a kernel or disk image to boot a VM with.
This parameter has a direct relation with the ``arch`` attribute. If
not given, it will default to None.
+cpu
+~~~
+
+The cpu model that will be set to all QEMUMachine instances created
+by the test.
+
machine
~~~~~~~
@@ -962,6 +1012,38 @@ qemu_bin
The exact QEMU binary to be used on QEMUMachine.
+LinuxTest
+~~~~~~~~~
+
+Besides the parameters present on the ``avocado_qemu.Test`` base
+class, the ``avocado_qemu.LinuxTest`` adds the following parameters:
+
+distro
+......
+
+The name of the Linux distribution used as the guest image for the
+test. The name should match the **Provider** column on the list
+of images supported by the avocado.utils.vmimage library:
+
+https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
+
+distro_version
+..............
+
+The version of the Linux distribution as the guest image for the
+test. The name should match the **Version** column on the list
+of images supported by the avocado.utils.vmimage library:
+
+https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
+
+distro_checksum
+...............
+
+The sha256 hash of the guest image file used for the test.
+
+If this value is not set in the code or by this parameter no
+validation on the integrity of the image will be performed.
+
Skipping tests
--------------
The Avocado framework provides Python decorators which allow for easily skip
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index aacb6f6d96..bad6cf5b4e 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -1,5 +1,9 @@
+config X86_FW_OVMF
+ bool
+
config SEV
bool
+ select X86_FW_OVMF
depends on KVM
config PC
diff --git a/hw/i386/meson.build b/hw/i386/meson.build
index e5d109f5c6..80dad29f2b 100644
--- a/hw/i386/meson.build
+++ b/hw/i386/meson.build
@@ -24,6 +24,8 @@ i386_ss.add(when: 'CONFIG_PC', if_true: files(
'pc_sysfw.c',
'acpi-build.c',
'port92.c'))
+i386_ss.add(when: 'CONFIG_X86_FW_OVMF', if_true: files('pc_sysfw_ovmf.c'),
+ if_false: files('pc_sysfw_ovmf-stubs.c'))
subdir('kvm')
subdir('xen')
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 6ce37a2b05..68d6b1f783 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -124,113 +124,6 @@ void pc_system_flash_cleanup_unused(PCMachineState *pcms)
}
}
-#define OVMF_TABLE_FOOTER_GUID "96b582de-1fb2-45f7-baea-a366c55a082d"
-
-static uint8_t *ovmf_table;
-static int ovmf_table_len;
-
-static void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size)
-{
- uint8_t *ptr;
- QemuUUID guid;
- int tot_len;
-
- /* should only be called once */
- if (ovmf_table) {
- return;
- }
-
- if (flash_size < TARGET_PAGE_SIZE) {
- return;
- }
-
- /*
- * if this is OVMF there will be a table footer
- * guid 48 bytes before the end of the flash file. If it's
- * not found, silently abort the flash parsing.
- */
- qemu_uuid_parse(OVMF_TABLE_FOOTER_GUID, &guid);
- guid = qemu_uuid_bswap(guid); /* guids are LE */
- ptr = flash_ptr + flash_size - 48;
- if (!qemu_uuid_is_equal((QemuUUID *)ptr, &guid)) {
- return;
- }
-
- /* if found, just before is two byte table length */
- ptr -= sizeof(uint16_t);
- tot_len = le16_to_cpu(*(uint16_t *)ptr) - sizeof(guid) - sizeof(uint16_t);
-
- if (tot_len <= 0) {
- return;
- }
-
- ovmf_table = g_malloc(tot_len);
- ovmf_table_len = tot_len;
-
- /*
- * ptr is the foot of the table, so copy it all to the newly
- * allocated ovmf_table and then set the ovmf_table pointer
- * to the table foot
- */
- memcpy(ovmf_table, ptr - tot_len, tot_len);
- ovmf_table += tot_len;
-}
-
-bool pc_system_ovmf_table_find(const char *entry, uint8_t **data,
- int *data_len)
-{
- uint8_t *ptr = ovmf_table;
- int tot_len = ovmf_table_len;
- QemuUUID entry_guid;
-
- if (qemu_uuid_parse(entry, &entry_guid) < 0) {
- return false;
- }
-
- if (!ptr) {
- return false;
- }
-
- entry_guid = qemu_uuid_bswap(entry_guid); /* guids are LE */
- while (tot_len >= sizeof(QemuUUID) + sizeof(uint16_t)) {
- int len;
- QemuUUID *guid;
-
- /*
- * The data structure is
- * arbitrary length data
- * 2 byte length of entire entry
- * 16 byte guid
- */
- guid = (QemuUUID *)(ptr - sizeof(QemuUUID));
- len = le16_to_cpu(*(uint16_t *)(ptr - sizeof(QemuUUID) -
- sizeof(uint16_t)));
-
- /*
- * just in case the table is corrupt, wouldn't want to spin in
- * the zero case
- */
- if (len < sizeof(QemuUUID) + sizeof(uint16_t)) {
- return false;
- } else if (len > tot_len) {
- return false;
- }
-
- ptr -= len;
- tot_len -= len;
- if (qemu_uuid_is_equal(guid, &entry_guid)) {
- if (data) {
- *data = ptr;
- }
- if (data_len) {
- *data_len = len - sizeof(QemuUUID) - sizeof(uint16_t);
- }
- return true;
- }
- }
- return false;
-}
-
/*
* Map the pcms->flash[] from 4GiB downward, and realize.
* Map them in descending order, i.e. pcms->flash[0] at the top,
diff --git a/hw/i386/pc_sysfw_ovmf-stubs.c b/hw/i386/pc_sysfw_ovmf-stubs.c
new file mode 100644
index 0000000000..aabe78b271
--- /dev/null
+++ b/hw/i386/pc_sysfw_ovmf-stubs.c
@@ -0,0 +1,26 @@
+/*
+ * QEMU PC System Firmware (OVMF stubs)
+ *
+ * Copyright (c) 2021 Red Hat, Inc.
+ *
+ * Author:
+ * Philippe Mathieu-Daudé <philmd@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/i386/pc.h"
+
+bool pc_system_ovmf_table_find(const char *entry, uint8_t **data, int *data_len)
+{
+ g_assert_not_reached();
+}
+
+void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size)
+{
+ g_assert_not_reached();
+}
diff --git a/hw/i386/pc_sysfw_ovmf.c b/hw/i386/pc_sysfw_ovmf.c
new file mode 100644
index 0000000000..f4dd92c588
--- /dev/null
+++ b/hw/i386/pc_sysfw_ovmf.c
@@ -0,0 +1,151 @@
+/*
+ * QEMU PC System Firmware (OVMF specific)
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2011-2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/i386/pc.h"
+#include "cpu.h"
+
+#define OVMF_TABLE_FOOTER_GUID "96b582de-1fb2-45f7-baea-a366c55a082d"
+
+static bool ovmf_flash_parsed;
+static uint8_t *ovmf_table;
+static int ovmf_table_len;
+
+void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size)
+{
+ uint8_t *ptr;
+ QemuUUID guid;
+ int tot_len;
+
+ /* should only be called once */
+ if (ovmf_flash_parsed) {
+ return;
+ }
+
+ ovmf_flash_parsed = true;
+
+ if (flash_size < TARGET_PAGE_SIZE) {
+ return;
+ }
+
+ /*
+ * if this is OVMF there will be a table footer
+ * guid 48 bytes before the end of the flash file. If it's
+ * not found, silently abort the flash parsing.
+ */
+ qemu_uuid_parse(OVMF_TABLE_FOOTER_GUID, &guid);
+ guid = qemu_uuid_bswap(guid); /* guids are LE */
+ ptr = flash_ptr + flash_size - 48;
+ if (!qemu_uuid_is_equal((QemuUUID *)ptr, &guid)) {
+ return;
+ }
+
+ /* if found, just before is two byte table length */
+ ptr -= sizeof(uint16_t);
+ tot_len = le16_to_cpu(*(uint16_t *)ptr) - sizeof(guid) - sizeof(uint16_t);
+
+ if (tot_len <= 0) {
+ return;
+ }
+
+ ovmf_table = g_malloc(tot_len);
+ ovmf_table_len = tot_len;
+
+ /*
+ * ptr is the foot of the table, so copy it all to the newly
+ * allocated ovmf_table and then set the ovmf_table pointer
+ * to the table foot
+ */
+ memcpy(ovmf_table, ptr - tot_len, tot_len);
+ ovmf_table += tot_len;
+}
+
+/**
+ * pc_system_ovmf_table_find - Find the data associated with an entry in OVMF's
+ * reset vector GUIDed table.
+ *
+ * @entry: GUID string of the entry to lookup
+ * @data: Filled with a pointer to the entry's value (if not NULL)
+ * @data_len: Filled with the length of the entry's value (if not NULL). Pass
+ * NULL here if the length of data is known.
+ *
+ * Return: true if the entry was found in the OVMF table; false otherwise.
+ */
+bool pc_system_ovmf_table_find(const char *entry, uint8_t **data,
+ int *data_len)
+{
+ uint8_t *ptr = ovmf_table;
+ int tot_len = ovmf_table_len;
+ QemuUUID entry_guid;
+
+ assert(ovmf_flash_parsed);
+
+ if (qemu_uuid_parse(entry, &entry_guid) < 0) {
+ return false;
+ }
+
+ if (!ptr) {
+ return false;
+ }
+
+ entry_guid = qemu_uuid_bswap(entry_guid); /* guids are LE */
+ while (tot_len >= sizeof(QemuUUID) + sizeof(uint16_t)) {
+ int len;
+ QemuUUID *guid;
+
+ /*
+ * The data structure is
+ * arbitrary length data
+ * 2 byte length of entire entry
+ * 16 byte guid
+ */
+ guid = (QemuUUID *)(ptr - sizeof(QemuUUID));
+ len = le16_to_cpu(*(uint16_t *)(ptr - sizeof(QemuUUID) -
+ sizeof(uint16_t)));
+
+ /*
+ * just in case the table is corrupt, wouldn't want to spin in
+ * the zero case
+ */
+ if (len < sizeof(QemuUUID) + sizeof(uint16_t)) {
+ return false;
+ } else if (len > tot_len) {
+ return false;
+ }
+
+ ptr -= len;
+ tot_len -= len;
+ if (qemu_uuid_is_equal(guid, &entry_guid)) {
+ if (data) {
+ *data = ptr;
+ }
+ if (data_len) {
+ *data_len = len - sizeof(QemuUUID) - sizeof(uint16_t);
+ }
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 87294f2632..0775f945d7 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -188,6 +188,7 @@ void pc_system_flash_cleanup_unused(PCMachineState *pcms);
void pc_system_firmware_init(PCMachineState *pcms, MemoryRegion *rom_memory);
bool pc_system_ovmf_table_find(const char *entry, uint8_t **data,
int *data_len);
+void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size);
/* acpi-build.c */
diff --git a/python/Makefile b/python/Makefile
index ac46ae33e7..fe27a3e12e 100644
--- a/python/Makefile
+++ b/python/Makefile
@@ -1,4 +1,5 @@
QEMU_VENV_DIR=.dev-venv
+QEMU_TOX_EXTRA_ARGS ?=
.PHONY: help
help:
@@ -15,6 +16,8 @@ help:
@echo " These tests use the newest dependencies."
@echo " Requires: Python 3.6 - 3.10, and tox."
@echo " Hint (Fedora): 'sudo dnf install python3-tox python3.10'"
+ @echo " The variable QEMU_TOX_EXTRA_ARGS can be use to pass extra"
+ @echo " arguments to tox".
@echo ""
@echo "make check-dev:"
@echo " Run tests in a venv against your default python3 version."
@@ -87,7 +90,7 @@ check:
.PHONY: check-tox
check-tox:
- @tox
+ @tox $(QEMU_TOX_EXTRA_ARGS)
.PHONY: clean
clean:
diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index d47ab3d896..971ed7e8c6 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -96,7 +96,8 @@ class QEMUMachine:
socket_scm_helper: Optional[str] = None,
sock_dir: Optional[str] = None,
drain_console: bool = False,
- console_log: Optional[str] = None):
+ console_log: Optional[str] = None,
+ log_dir: Optional[str] = None):
'''
Initialize a QEMUMachine
@@ -110,6 +111,7 @@ class QEMUMachine:
@param sock_dir: where to create socket (defaults to base_temp_dir)
@param drain_console: (optional) True to drain console socket to buffer
@param console_log: (optional) path to console log file
+ @param log_dir: where to create and keep log files
@note: Qemu process is not started until launch() is used.
'''
# pylint: disable=too-many-arguments
@@ -123,6 +125,7 @@ class QEMUMachine:
self._name = name or "qemu-%d" % os.getpid()
self._base_temp_dir = base_temp_dir
self._sock_dir = sock_dir or self._base_temp_dir
+ self._log_dir = log_dir
self._socket_scm_helper = socket_scm_helper
if monitor_address is not None:
@@ -313,9 +316,12 @@ class QEMUMachine:
args.extend(['-device', device])
return args
- def _pre_launch(self) -> None:
- self._qemu_log_path = os.path.join(self.temp_dir, self._name + ".log")
+ @property
+ def args(self) -> List[str]:
+ """Returns the list of arguments given to the QEMU binary."""
+ return self._args
+ def _pre_launch(self) -> None:
if self._console_set:
self._remove_files.append(self._console_address)
@@ -332,6 +338,7 @@ class QEMUMachine:
# NOTE: Make sure any opened resources are *definitely* freed in
# _post_shutdown()!
# pylint: disable=consider-using-with
+ self._qemu_log_path = os.path.join(self.log_dir, self._name + ".log")
self._qemu_log_file = open(self._qemu_log_path, 'wb')
def _post_launch(self) -> None:
@@ -770,3 +777,12 @@ class QEMUMachine:
self._temp_dir = tempfile.mkdtemp(prefix="qemu-machine-",
dir=self._base_temp_dir)
return self._temp_dir
+
+ @property
+ def log_dir(self) -> str:
+ """
+ Returns a directory to be used for writing logs
+ """
+ if self._log_dir is None:
+ return self.temp_dir
+ return self._log_dir
diff --git a/python/setup.cfg b/python/setup.cfg
index 11f71d5312..14bab90288 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -121,6 +121,7 @@ multi_line_output=3
[tox:tox]
envlist = py36, py37, py38, py39, py310
+skip_missing_interpreters = true
[testenv]
allowlist_externals = make
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 27baf17d6c..a099acb34d 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -2166,9 +2166,10 @@ typedef struct _ga_win_10_0_server_t {
char const *version_id;
} ga_win_10_0_server_t;
-static ga_win_10_0_server_t const WIN_10_0_SERVER_VERSION_MATRIX[3] = {
+static ga_win_10_0_server_t const WIN_10_0_SERVER_VERSION_MATRIX[4] = {
{14393, "Microsoft Windows Server 2016", "2016"},
{17763, "Microsoft Windows Server 2019", "2019"},
+ {20344, "Microsoft Windows Server 2022", "2022"},
{0, 0}
};
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 833d3baa7b..103c6326a2 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -66,8 +66,6 @@ struct DisasContext {
/* Temporaries for $31 and $f31 as source and destination. */
TCGv zero;
TCGv sink;
- /* Temporary for immediate constants. */
- TCGv lit;
};
/* Target-specific return values from translate_one, indicating the
@@ -157,7 +155,7 @@ void alpha_translate_init(void)
static TCGv load_zero(DisasContext *ctx)
{
if (!ctx->zero) {
- ctx->zero = tcg_const_i64(0);
+ ctx->zero = tcg_constant_i64(0);
}
return ctx->zero;
}
@@ -177,14 +175,6 @@ static void free_context_temps(DisasContext *ctx)
tcg_temp_free(ctx->sink);
ctx->sink = NULL;
}
- if (ctx->zero) {
- tcg_temp_free(ctx->zero);
- ctx->zero = NULL;
- }
- if (ctx->lit) {
- tcg_temp_free(ctx->lit);
- ctx->lit = NULL;
- }
}
static TCGv load_gpr(DisasContext *ctx, unsigned reg)
@@ -200,8 +190,7 @@ static TCGv load_gpr_lit(DisasContext *ctx, unsigned reg,
uint8_t lit, bool islit)
{
if (islit) {
- ctx->lit = tcg_const_i64(lit);
- return ctx->lit;
+ return tcg_constant_i64(lit);
} else if (likely(reg < 31)) {
return ctx->ir[reg];
} else {
@@ -261,11 +250,9 @@ static void gen_excp_1(int exception, int error_code)
{
TCGv_i32 tmp1, tmp2;
- tmp1 = tcg_const_i32(exception);
- tmp2 = tcg_const_i32(error_code);
+ tmp1 = tcg_constant_i32(exception);
+ tmp2 = tcg_constant_i32(error_code);
gen_helper_excp(cpu_env, tmp1, tmp2);
- tcg_temp_free_i32(tmp2);
- tcg_temp_free_i32(tmp1);
}
static DisasJumpType gen_excp(DisasContext *ctx, int exception, int error_code)
@@ -485,15 +472,11 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
return DISAS_NORETURN;
} else {
- TCGv_i64 z = tcg_const_i64(0);
- TCGv_i64 d = tcg_const_i64(dest);
- TCGv_i64 p = tcg_const_i64(ctx->base.pc_next);
+ TCGv_i64 z = load_zero(ctx);
+ TCGv_i64 d = tcg_constant_i64(dest);
+ TCGv_i64 p = tcg_constant_i64(ctx->base.pc_next);
tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
-
- tcg_temp_free_i64(z);
- tcg_temp_free_i64(d);
- tcg_temp_free_i64(p);
return DISAS_PC_UPDATED;
}
}
@@ -695,22 +678,19 @@ static void gen_fp_exc_raise(int rc, int fn11)
if (!(fn11 & QUAL_I)) {
ignore |= FPCR_INE;
}
- ign = tcg_const_i32(ignore);
+ ign = tcg_constant_i32(ignore);
/* ??? Pass in the regno of the destination so that the helper can
set EXC_MASK, which contains a bitmask of destination registers
that have caused arithmetic traps. A simple userspace emulation
does not require this. We do need it for a guest kernel's entArith,
or if we were to do something clever with imprecise exceptions. */
- reg = tcg_const_i32(rc + 32);
+ reg = tcg_constant_i32(rc + 32);
if (fn11 & QUAL_S) {
gen_helper_fp_exc_raise_s(cpu_env, ign, reg);
} else {
gen_helper_fp_exc_raise(cpu_env, ign, reg);
}
-
- tcg_temp_free_i32(reg);
- tcg_temp_free_i32(ign);
}
static void gen_cvtlq(TCGv vc, TCGv vb)
@@ -803,7 +783,7 @@ IEEE_INTCVT(cvtqt)
static void gen_cpy_mask(TCGv vc, TCGv va, TCGv vb, bool inv_a, uint64_t mask)
{
- TCGv vmask = tcg_const_i64(mask);
+ TCGv vmask = tcg_constant_i64(mask);
TCGv tmp = tcg_temp_new_i64();
if (inv_a) {
@@ -815,7 +795,6 @@ static void gen_cpy_mask(TCGv vc, TCGv va, TCGv vb, bool inv_a, uint64_t mask)
tcg_gen_andc_i64(vc, vb, vmask);
tcg_gen_or_i64(vc, vc, tmp);
- tcg_temp_free(vmask);
tcg_temp_free(tmp);
}
@@ -1084,15 +1063,11 @@ static void gen_msk_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
static void gen_rx(DisasContext *ctx, int ra, int set)
{
- TCGv tmp;
-
if (ra != 31) {
ld_flag_byte(ctx->ir[ra], ENV_FLAG_RX_SHIFT);
}
- tmp = tcg_const_i64(set);
- st_flag_byte(ctx->ir[ra], ENV_FLAG_RX_SHIFT);
- tcg_temp_free(tmp);
+ st_flag_byte(tcg_constant_i64(set), ENV_FLAG_RX_SHIFT);
}
static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
@@ -1193,12 +1168,9 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
case 0x3E:
/* WTINT */
- {
- TCGv_i32 tmp = tcg_const_i32(1);
- tcg_gen_st_i32(tmp, cpu_env, -offsetof(AlphaCPU, env) +
- offsetof(CPUState, halted));
- tcg_temp_free_i32(tmp);
- }
+ tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
+ -offsetof(AlphaCPU, env) +
+ offsetof(CPUState, halted));
tcg_gen_movi_i64(ctx->ir[IR_V0], 0);
return gen_excp(ctx, EXCP_HALTED, 0);
@@ -1349,12 +1321,8 @@ static DisasJumpType gen_mtpr(DisasContext *ctx, TCGv vb, int regno)
case 253:
/* WAIT */
- {
- TCGv_i32 tmp = tcg_const_i32(1);
- tcg_gen_st_i32(tmp, cpu_env, -offsetof(AlphaCPU, env) +
- offsetof(CPUState, halted));
- tcg_temp_free_i32(tmp);
- }
+ tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
+ -offsetof(AlphaCPU, env) + offsetof(CPUState, halted));
return gen_excp(ctx, EXCP_HALTED, 0);
case 252:
@@ -2721,15 +2689,14 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
/* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
address from EXC_ADDR. This turns out to be useful for our
emulation PALcode, so continue to accept it. */
- ctx->lit = vb = tcg_temp_new();
+ vb = dest_sink(ctx);
tcg_gen_ld_i64(vb, cpu_env, offsetof(CPUAlphaState, exc_addr));
} else {
vb = load_gpr(ctx, rb);
}
tcg_gen_movi_i64(cpu_lock_addr, -1);
+ st_flag_byte(load_zero(ctx), ENV_FLAG_RX_SHIFT);
tmp = tcg_temp_new();
- tcg_gen_movi_i64(tmp, 0);
- st_flag_byte(tmp, ENV_FLAG_RX_SHIFT);
tcg_gen_andi_i64(tmp, vb, 1);
st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT);
tcg_temp_free(tmp);
@@ -2996,7 +2963,6 @@ static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
ctx->zero = NULL;
ctx->sink = NULL;
- ctx->lit = NULL;
/* Bound the number of insns to execute to those left on the page. */
bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 835120c038..2552747138 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -144,6 +144,7 @@
#define tcg_gen_sextract_reg tcg_gen_sextract_i64
#define tcg_const_reg tcg_const_i64
#define tcg_const_local_reg tcg_const_local_i64
+#define tcg_constant_reg tcg_constant_i64
#define tcg_gen_movcond_reg tcg_gen_movcond_i64
#define tcg_gen_add2_reg tcg_gen_add2_i64
#define tcg_gen_sub2_reg tcg_gen_sub2_i64
@@ -238,6 +239,7 @@
#define tcg_gen_sextract_reg tcg_gen_sextract_i32
#define tcg_const_reg tcg_const_i32
#define tcg_const_local_reg tcg_const_local_i32
+#define tcg_constant_reg tcg_constant_i32
#define tcg_gen_movcond_reg tcg_gen_movcond_i32
#define tcg_gen_add2_reg tcg_gen_add2_i32
#define tcg_gen_sub2_reg tcg_gen_sub2_i32
@@ -250,8 +252,6 @@
typedef struct DisasCond {
TCGCond c;
TCGv_reg a0, a1;
- bool a0_is_n;
- bool a1_is_0;
} DisasCond;
typedef struct DisasContext {
@@ -446,9 +446,7 @@ static DisasCond cond_make_n(void)
return (DisasCond){
.c = TCG_COND_NE,
.a0 = cpu_psw_n,
- .a0_is_n = true,
- .a1 = NULL,
- .a1_is_0 = true
+ .a1 = tcg_constant_reg(0)
};
}
@@ -456,7 +454,7 @@ static DisasCond cond_make_0_tmp(TCGCond c, TCGv_reg a0)
{
assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
return (DisasCond){
- .c = c, .a0 = a0, .a1_is_0 = true
+ .c = c, .a0 = a0, .a1 = tcg_constant_reg(0)
};
}
@@ -480,26 +478,14 @@ static DisasCond cond_make(TCGCond c, TCGv_reg a0, TCGv_reg a1)
return r;
}
-static void cond_prep(DisasCond *cond)
-{
- if (cond->a1_is_0) {
- cond->a1_is_0 = false;
- cond->a1 = tcg_const_reg(0);
- }
-}
-
static void cond_free(DisasCond *cond)
{
switch (cond->c) {
default:
- if (!cond->a0_is_n) {
+ if (cond->a0 != cpu_psw_n) {
tcg_temp_free(cond->a0);
}
- if (!cond->a1_is_0) {
- tcg_temp_free(cond->a1);
- }
- cond->a0_is_n = false;
- cond->a1_is_0 = false;
+ tcg_temp_free(cond->a1);
cond->a0 = NULL;
cond->a1 = NULL;
/* fallthru */
@@ -557,9 +543,8 @@ static TCGv_reg dest_gpr(DisasContext *ctx, unsigned reg)
static void save_or_nullify(DisasContext *ctx, TCGv_reg dest, TCGv_reg t)
{
if (ctx->null_cond.c != TCG_COND_NEVER) {
- cond_prep(&ctx->null_cond);
tcg_gen_movcond_reg(ctx->null_cond.c, dest, ctx->null_cond.a0,
- ctx->null_cond.a1, dest, t);
+ ctx->null_cond.a1, dest, t);
} else {
tcg_gen_mov_reg(dest, t);
}
@@ -666,11 +651,9 @@ static void nullify_over(DisasContext *ctx)
assert(ctx->null_cond.c != TCG_COND_ALWAYS);
ctx->null_lab = gen_new_label();
- cond_prep(&ctx->null_cond);
/* If we're using PSW[N], copy it to a temp because... */
- if (ctx->null_cond.a0_is_n) {
- ctx->null_cond.a0_is_n = false;
+ if (ctx->null_cond.a0 == cpu_psw_n) {
ctx->null_cond.a0 = tcg_temp_new();
tcg_gen_mov_reg(ctx->null_cond.a0, cpu_psw_n);
}
@@ -683,7 +666,7 @@ static void nullify_over(DisasContext *ctx)
}
tcg_gen_brcond_reg(ctx->null_cond.c, ctx->null_cond.a0,
- ctx->null_cond.a1, ctx->null_lab);
+ ctx->null_cond.a1, ctx->null_lab);
cond_free(&ctx->null_cond);
}
}
@@ -697,10 +680,9 @@ static void nullify_save(DisasContext *ctx)
}
return;
}
- if (!ctx->null_cond.a0_is_n) {
- cond_prep(&ctx->null_cond);
+ if (ctx->null_cond.a0 != cpu_psw_n) {
tcg_gen_setcond_reg(ctx->null_cond.c, cpu_psw_n,
- ctx->null_cond.a0, ctx->null_cond.a1);
+ ctx->null_cond.a0, ctx->null_cond.a1);
ctx->psw_n_nonzero = true;
}
cond_free(&ctx->null_cond);
@@ -771,9 +753,7 @@ static inline target_ureg iaoq_dest(DisasContext *ctx, target_sreg disp)
static void gen_excp_1(int exception)
{
- TCGv_i32 t = tcg_const_i32(exception);
- gen_helper_excp(cpu_env, t);
- tcg_temp_free_i32(t);
+ gen_helper_excp(cpu_env, tcg_constant_i32(exception));
}
static void gen_excp(DisasContext *ctx, int exception)
@@ -787,12 +767,9 @@ static void gen_excp(DisasContext *ctx, int exception)
static bool gen_excp_iir(DisasContext *ctx, int exc)
{
- TCGv_reg tmp;
-
nullify_over(ctx);
- tmp = tcg_const_reg(ctx->insn);
- tcg_gen_st_reg(tmp, cpu_env, offsetof(CPUHPPAState, cr[CR_IIR]));
- tcg_temp_free(tmp);
+ tcg_gen_st_reg(tcg_constant_reg(ctx->insn),
+ cpu_env, offsetof(CPUHPPAState, cr[CR_IIR]));
gen_excp(ctx, exc);
return nullify_end(ctx);
}
@@ -1150,13 +1127,12 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1,
}
if (!is_l || cond_need_cb(c)) {
- TCGv_reg zero = tcg_const_reg(0);
+ TCGv_reg zero = tcg_constant_reg(0);
cb_msb = get_temp(ctx);
tcg_gen_add2_reg(dest, cb_msb, in1, zero, in2, zero);
if (is_c) {
tcg_gen_add2_reg(dest, cb_msb, dest, cb_msb, cpu_psw_cb_msb, zero);
}
- tcg_temp_free(zero);
if (!is_l) {
cb = get_temp(ctx);
tcg_gen_xor_reg(cb, in1, in2);
@@ -1182,7 +1158,6 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1,
/* Emit any conditional trap before any writeback. */
cond = do_cond(cf, dest, cb_msb, sv);
if (is_tc) {
- cond_prep(&cond);
tmp = tcg_temp_new();
tcg_gen_setcond_reg(cond.c, tmp, cond.a0, cond.a1);
gen_helper_tcond(cpu_env, tmp);
@@ -1242,7 +1217,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
cb = tcg_temp_new();
cb_msb = tcg_temp_new();
- zero = tcg_const_reg(0);
+ zero = tcg_constant_reg(0);
if (is_b) {
/* DEST,C = IN1 + ~IN2 + C. */
tcg_gen_not_reg(cb, in2);
@@ -1258,7 +1233,6 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
tcg_gen_eqv_reg(cb, in1, in2);
tcg_gen_xor_reg(cb, cb, dest);
}
- tcg_temp_free(zero);
/* Compute signed overflow if required. */
sv = NULL;
@@ -1278,7 +1252,6 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
/* Emit any conditional trap before any writeback. */
if (is_tc) {
- cond_prep(&cond);
tmp = tcg_temp_new();
tcg_gen_setcond_reg(cond.c, tmp, cond.a0, cond.a1);
gen_helper_tcond(cpu_env, tmp);
@@ -1404,7 +1377,6 @@ static void do_unit(DisasContext *ctx, unsigned rt, TCGv_reg in1,
if (is_tc) {
TCGv_reg tmp = tcg_temp_new();
- cond_prep(&cond);
tcg_gen_setcond_reg(cond.c, tmp, cond.a0, cond.a1);
gen_helper_tcond(cpu_env, tmp);
tcg_temp_free(tmp);
@@ -1860,7 +1832,6 @@ static bool do_cbranch(DisasContext *ctx, target_sreg disp, bool is_n,
}
taken = gen_new_label();
- cond_prep(cond);
tcg_gen_brcond_reg(c, cond->a0, cond->a1, taken);
cond_free(cond);
@@ -1957,7 +1928,6 @@ static bool do_ibranch(DisasContext *ctx, TCGv_reg dest,
tcg_gen_lookup_and_goto_ptr();
return nullify_end(ctx);
} else {
- cond_prep(&ctx->null_cond);
c = ctx->null_cond.c;
a0 = ctx->null_cond.a0;
a1 = ctx->null_cond.a1;
@@ -2449,17 +2419,16 @@ static bool trans_probe(DisasContext *ctx, arg_probe *a)
form_gva(ctx, &addr, &ofs, a->b, 0, 0, 0, a->sp, 0, false);
if (a->imm) {
- level = tcg_const_i32(a->ri);
+ level = tcg_constant_i32(a->ri);
} else {
level = tcg_temp_new_i32();
tcg_gen_trunc_reg_i32(level, load_gpr(ctx, a->ri));
tcg_gen_andi_i32(level, level, 3);
}
- want = tcg_const_i32(a->write ? PAGE_WRITE : PAGE_READ);
+ want = tcg_constant_i32(a->write ? PAGE_WRITE : PAGE_READ);
gen_helper_probe(dest, cpu_env, addr, level, want);
- tcg_temp_free_i32(want);
tcg_temp_free_i32(level);
save_gpr(ctx, a->t, dest);
@@ -2599,17 +2568,13 @@ static bool trans_lpa(DisasContext *ctx, arg_ldst *a)
static bool trans_lci(DisasContext *ctx, arg_lci *a)
{
- TCGv_reg ci;
-
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
/* The Coherence Index is an implementation-defined function of the
physical address. Two addresses with the same CI have a coherent
view of the cache. Our implementation is to return 0 for all,
since the entire address space is coherent. */
- ci = tcg_const_reg(0);
- save_gpr(ctx, a->t, ci);
- tcg_temp_free(ci);
+ save_gpr(ctx, a->t, tcg_constant_reg(0));
cond_free(&ctx->null_cond);
return true;
@@ -2710,8 +2675,6 @@ static bool trans_or(DisasContext *ctx, arg_rrr_cf *a)
* currently implemented as idle.
*/
if ((rt == 10 || rt == 31) && r1 == rt && r2 == rt) { /* PAUSE */
- TCGv_i32 tmp;
-
/* No need to check for supervisor, as userland can only pause
until the next timer interrupt. */
nullify_over(ctx);
@@ -2722,10 +2685,8 @@ static bool trans_or(DisasContext *ctx, arg_rrr_cf *a)
nullify_set(ctx, 0);
/* Tell the qemu main loop to halt until this cpu has work. */
- tmp = tcg_const_i32(1);
- tcg_gen_st_i32(tmp, cpu_env, -offsetof(HPPACPU, env) +
- offsetof(CPUState, halted));
- tcg_temp_free_i32(tmp);
+ tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
+ offsetof(CPUState, halted) - offsetof(HPPACPU, env));
gen_excp_1(EXCP_HALTED);
ctx->base.is_jmp = DISAS_NORETURN;
@@ -2833,7 +2794,7 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
add2 = tcg_temp_new();
addc = tcg_temp_new();
dest = tcg_temp_new();
- zero = tcg_const_reg(0);
+ zero = tcg_constant_reg(0);
/* Form R1 << 1 | PSW[CB]{8}. */
tcg_gen_add_reg(add1, in1, in1);
@@ -2851,7 +2812,6 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
tcg_gen_add2_i32(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb, addc, zero);
tcg_temp_free(addc);
- tcg_temp_free(zero);
/* Write back the result register. */
save_gpr(ctx, a->t, dest);
@@ -2967,9 +2927,8 @@ static bool trans_ldc(DisasContext *ctx, arg_ldst *a)
*/
gen_helper_ldc_check(addr);
- zero = tcg_const_reg(0);
+ zero = tcg_constant_reg(0);
tcg_gen_atomic_xchg_reg(dest, addr, zero, ctx->mmu_idx, mop);
- tcg_temp_free(zero);
if (a->m) {
save_gpr(ctx, a->b, ofs);
@@ -3882,15 +3841,13 @@ static bool trans_fcmp_f(DisasContext *ctx, arg_fclass2 *a)
ta = load_frw0_i32(a->r1);
tb = load_frw0_i32(a->r2);
- ty = tcg_const_i32(a->y);
- tc = tcg_const_i32(a->c);
+ ty = tcg_constant_i32(a->y);
+ tc = tcg_constant_i32(a->c);
gen_helper_fcmp_s(cpu_env, ta, tb, ty, tc);
tcg_temp_free_i32(ta);
tcg_temp_free_i32(tb);
- tcg_temp_free_i32(ty);
- tcg_temp_free_i32(tc);
return nullify_end(ctx);
}
@@ -3904,15 +3861,13 @@ static bool trans_fcmp_d(DisasContext *ctx, arg_fclass2 *a)
ta = load_frd0(a->r1);
tb = load_frd0(a->r2);
- ty = tcg_const_i32(a->y);
- tc = tcg_const_i32(a->c);
+ ty = tcg_constant_i32(a->y);
+ tc = tcg_constant_i32(a->c);
gen_helper_fcmp_d(cpu_env, ta, tb, ty, tc);
tcg_temp_free_i64(ta);
tcg_temp_free_i64(tb);
- tcg_temp_free_i32(ty);
- tcg_temp_free_i32(tc);
return nullify_end(ctx);
}
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 950a991a71..5d98a4e7c0 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1437,6 +1437,8 @@ typedef struct CPUX86State {
FPReg fpregs[8];
/* KVM-only so far */
uint16_t fpop;
+ uint16_t fpcs;
+ uint16_t fpds;
uint64_t fpip;
uint64_t fpdp;
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 74bbe94b80..cdd8e9f947 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -727,10 +727,14 @@ void helper_fwait(CPUX86State *env)
}
}
-void helper_fninit(CPUX86State *env)
+static void do_fninit(CPUX86State *env)
{
env->fpus = 0;
env->fpstt = 0;
+ env->fpcs = 0;
+ env->fpds = 0;
+ env->fpip = 0;
+ env->fpdp = 0;
cpu_set_fpuc(env, 0x37f);
env->fptags[0] = 1;
env->fptags[1] = 1;
@@ -742,6 +746,11 @@ void helper_fninit(CPUX86State *env)
env->fptags[7] = 1;
}
+void helper_fninit(CPUX86State *env)
+{
+ do_fninit(env);
+}
+
/* BCD ops */
void helper_fbld_ST0(CPUX86State *env, target_ulong ptr)
@@ -2373,19 +2382,19 @@ static void do_fstenv(CPUX86State *env, target_ulong ptr, int data32,
cpu_stl_data_ra(env, ptr, env->fpuc, retaddr);
cpu_stl_data_ra(env, ptr + 4, fpus, retaddr);
cpu_stl_data_ra(env, ptr + 8, fptag, retaddr);
- cpu_stl_data_ra(env, ptr + 12, 0, retaddr); /* fpip */
- cpu_stl_data_ra(env, ptr + 16, 0, retaddr); /* fpcs */
- cpu_stl_data_ra(env, ptr + 20, 0, retaddr); /* fpoo */
- cpu_stl_data_ra(env, ptr + 24, 0, retaddr); /* fpos */
+ cpu_stl_data_ra(env, ptr + 12, env->fpip, retaddr); /* fpip */
+ cpu_stl_data_ra(env, ptr + 16, env->fpcs, retaddr); /* fpcs */
+ cpu_stl_data_ra(env, ptr + 20, env->fpdp, retaddr); /* fpoo */
+ cpu_stl_data_ra(env, ptr + 24, env->fpds, retaddr); /* fpos */
} else {
/* 16 bit */
cpu_stw_data_ra(env, ptr, env->fpuc, retaddr);
cpu_stw_data_ra(env, ptr + 2, fpus, retaddr);
cpu_stw_data_ra(env, ptr + 4, fptag, retaddr);
- cpu_stw_data_ra(env, ptr + 6, 0, retaddr);
- cpu_stw_data_ra(env, ptr + 8, 0, retaddr);
- cpu_stw_data_ra(env, ptr + 10, 0, retaddr);
- cpu_stw_data_ra(env, ptr + 12, 0, retaddr);
+ cpu_stw_data_ra(env, ptr + 6, env->fpip, retaddr);
+ cpu_stw_data_ra(env, ptr + 8, env->fpcs, retaddr);
+ cpu_stw_data_ra(env, ptr + 10, env->fpdp, retaddr);
+ cpu_stw_data_ra(env, ptr + 12, env->fpds, retaddr);
}
}
@@ -2451,18 +2460,7 @@ static void do_fsave(CPUX86State *env, target_ulong ptr, int data32,
ptr += 10;
}
- /* fninit */
- env->fpus = 0;
- env->fpstt = 0;
- cpu_set_fpuc(env, 0x37f);
- env->fptags[0] = 1;
- env->fptags[1] = 1;
- env->fptags[2] = 1;
- env->fptags[3] = 1;
- env->fptags[4] = 1;
- env->fptags[5] = 1;
- env->fptags[6] = 1;
- env->fptags[7] = 1;
+ do_fninit(env);
}
void helper_fsave(CPUX86State *env, target_ulong ptr, int data32)
@@ -2834,7 +2832,7 @@ void helper_xrstor(CPUX86State *env, target_ulong ptr, uint64_t rfbm)
if (xstate_bv & XSTATE_FP_MASK) {
do_xrstor_fpu(env, ptr, ra);
} else {
- helper_fninit(env);
+ do_fninit(env);
memset(env->fpregs, 0, sizeof(env->fpregs));
}
}
diff --git a/target/i386/tcg/sysemu/bpt_helper.c b/target/i386/tcg/sysemu/bpt_helper.c
index 624f90b789..4d96a48a3c 100644
--- a/target/i386/tcg/sysemu/bpt_helper.c
+++ b/target/i386/tcg/sysemu/bpt_helper.c
@@ -109,9 +109,9 @@ static void hw_breakpoint_remove(CPUX86State *env, int index)
case DR7_TYPE_DATA_WR:
case DR7_TYPE_DATA_RW:
- if (env->cpu_breakpoint[index]) {
+ if (env->cpu_watchpoint[index]) {
cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
- env->cpu_breakpoint[index] = NULL;
+ env->cpu_watchpoint[index] = NULL;
}
break;
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 3814ce2a3e..8520d5a1e2 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -5919,503 +5919,555 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
/************************/
/* floats */
case 0xd8 ... 0xdf:
- if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
- /* if CR0.EM or CR0.TS are set, generate an FPU exception */
- /* XXX: what to do if illegal op ? */
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
- break;
- }
- modrm = x86_ldub_code(env, s);
- mod = (modrm >> 6) & 3;
- rm = modrm & 7;
- op = ((b & 7) << 3) | ((modrm >> 3) & 7);
- if (mod != 3) {
- /* memory op */
- gen_lea_modrm(env, s, modrm);
- switch(op) {
- case 0x00 ... 0x07: /* fxxxs */
- case 0x10 ... 0x17: /* fixxxl */
- case 0x20 ... 0x27: /* fxxxl */
- case 0x30 ... 0x37: /* fixxx */
- {
- int op1;
- op1 = op & 7;
+ {
+ bool update_fip = true;
+
+ if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
+ /* if CR0.EM or CR0.TS are set, generate an FPU exception */
+ /* XXX: what to do if illegal op ? */
+ gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ break;
+ }
+ modrm = x86_ldub_code(env, s);
+ mod = (modrm >> 6) & 3;
+ rm = modrm & 7;
+ op = ((b & 7) << 3) | ((modrm >> 3) & 7);
+ if (mod != 3) {
+ /* memory op */
+ AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ TCGv ea = gen_lea_modrm_1(s, a);
+ TCGv last_addr = tcg_temp_new();
+ bool update_fdp = true;
+
+ tcg_gen_mov_tl(last_addr, ea);
+ gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
+
+ switch (op) {
+ case 0x00 ... 0x07: /* fxxxs */
+ case 0x10 ... 0x17: /* fixxxl */
+ case 0x20 ... 0x27: /* fxxxl */
+ case 0x30 ... 0x37: /* fixxx */
+ {
+ int op1;
+ op1 = op & 7;
+
+ switch (op >> 4) {
+ case 0:
+ tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUL);
+ gen_helper_flds_FT0(cpu_env, s->tmp2_i32);
+ break;
+ case 1:
+ tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUL);
+ gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
+ break;
+ case 2:
+ tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
+ s->mem_index, MO_LEQ);
+ gen_helper_fldl_FT0(cpu_env, s->tmp1_i64);
+ break;
+ case 3:
+ default:
+ tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LESW);
+ gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
+ break;
+ }
- switch(op >> 4) {
+ gen_helper_fp_arith_ST0_FT0(op1);
+ if (op1 == 3) {
+ /* fcomp needs pop */
+ gen_helper_fpop(cpu_env);
+ }
+ }
+ break;
+ case 0x08: /* flds */
+ case 0x0a: /* fsts */
+ case 0x0b: /* fstps */
+ case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
+ case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
+ case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
+ switch (op & 7) {
case 0:
- tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUL);
- gen_helper_flds_FT0(cpu_env, s->tmp2_i32);
+ switch (op >> 4) {
+ case 0:
+ tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUL);
+ gen_helper_flds_ST0(cpu_env, s->tmp2_i32);
+ break;
+ case 1:
+ tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUL);
+ gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
+ break;
+ case 2:
+ tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
+ s->mem_index, MO_LEQ);
+ gen_helper_fldl_ST0(cpu_env, s->tmp1_i64);
+ break;
+ case 3:
+ default:
+ tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LESW);
+ gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
+ break;
+ }
break;
case 1:
- tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUL);
- gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
- break;
- case 2:
- tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
- s->mem_index, MO_LEQ);
- gen_helper_fldl_FT0(cpu_env, s->tmp1_i64);
+ /* XXX: the corresponding CPUID bit must be tested ! */
+ switch (op >> 4) {
+ case 1:
+ gen_helper_fisttl_ST0(s->tmp2_i32, cpu_env);
+ tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUL);
+ break;
+ case 2:
+ gen_helper_fisttll_ST0(s->tmp1_i64, cpu_env);
+ tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
+ s->mem_index, MO_LEQ);
+ break;
+ case 3:
+ default:
+ gen_helper_fistt_ST0(s->tmp2_i32, cpu_env);
+ tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUW);
+ break;
+ }
+ gen_helper_fpop(cpu_env);
break;
- case 3:
default:
- tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LESW);
- gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
+ switch (op >> 4) {
+ case 0:
+ gen_helper_fsts_ST0(s->tmp2_i32, cpu_env);
+ tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUL);
+ break;
+ case 1:
+ gen_helper_fistl_ST0(s->tmp2_i32, cpu_env);
+ tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUL);
+ break;
+ case 2:
+ gen_helper_fstl_ST0(s->tmp1_i64, cpu_env);
+ tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
+ s->mem_index, MO_LEQ);
+ break;
+ case 3:
+ default:
+ gen_helper_fist_ST0(s->tmp2_i32, cpu_env);
+ tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUW);
+ break;
+ }
+ if ((op & 7) == 3) {
+ gen_helper_fpop(cpu_env);
+ }
break;
}
+ break;
+ case 0x0c: /* fldenv mem */
+ gen_helper_fldenv(cpu_env, s->A0,
+ tcg_const_i32(dflag - 1));
+ update_fip = update_fdp = false;
+ break;
+ case 0x0d: /* fldcw mem */
+ tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUW);
+ gen_helper_fldcw(cpu_env, s->tmp2_i32);
+ update_fip = update_fdp = false;
+ break;
+ case 0x0e: /* fnstenv mem */
+ gen_helper_fstenv(cpu_env, s->A0,
+ tcg_const_i32(dflag - 1));
+ update_fip = update_fdp = false;
+ break;
+ case 0x0f: /* fnstcw mem */
+ gen_helper_fnstcw(s->tmp2_i32, cpu_env);
+ tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUW);
+ update_fip = update_fdp = false;
+ break;
+ case 0x1d: /* fldt mem */
+ gen_helper_fldt_ST0(cpu_env, s->A0);
+ break;
+ case 0x1f: /* fstpt mem */
+ gen_helper_fstt_ST0(cpu_env, s->A0);
+ gen_helper_fpop(cpu_env);
+ break;
+ case 0x2c: /* frstor mem */
+ gen_helper_frstor(cpu_env, s->A0,
+ tcg_const_i32(dflag - 1));
+ update_fip = update_fdp = false;
+ break;
+ case 0x2e: /* fnsave mem */
+ gen_helper_fsave(cpu_env, s->A0,
+ tcg_const_i32(dflag - 1));
+ update_fip = update_fdp = false;
+ break;
+ case 0x2f: /* fnstsw mem */
+ gen_helper_fnstsw(s->tmp2_i32, cpu_env);
+ tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
+ s->mem_index, MO_LEUW);
+ update_fip = update_fdp = false;
+ break;
+ case 0x3c: /* fbld */
+ gen_helper_fbld_ST0(cpu_env, s->A0);
+ break;
+ case 0x3e: /* fbstp */
+ gen_helper_fbst_ST0(cpu_env, s->A0);
+ gen_helper_fpop(cpu_env);
+ break;
+ case 0x3d: /* fildll */
+ tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
+ s->mem_index, MO_LEQ);
+ gen_helper_fildll_ST0(cpu_env, s->tmp1_i64);
+ break;
+ case 0x3f: /* fistpll */
+ gen_helper_fistll_ST0(s->tmp1_i64, cpu_env);
+ tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
+ s->mem_index, MO_LEQ);
+ gen_helper_fpop(cpu_env);
+ break;
+ default:
+ goto unknown_op;
+ }
- gen_helper_fp_arith_ST0_FT0(op1);
- if (op1 == 3) {
- /* fcomp needs pop */
- gen_helper_fpop(cpu_env);
- }
+ if (update_fdp) {
+ int last_seg = s->override >= 0 ? s->override : a.def_seg;
+
+ tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
+ offsetof(CPUX86State,
+ segs[last_seg].selector));
+ tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
+ offsetof(CPUX86State, fpds));
+ tcg_gen_st_tl(last_addr, cpu_env,
+ offsetof(CPUX86State, fpdp));
}
- break;
- case 0x08: /* flds */
- case 0x0a: /* fsts */
- case 0x0b: /* fstps */
- case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
- case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
- case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
- switch(op & 7) {
- case 0:
- switch(op >> 4) {
- case 0:
- tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUL);
- gen_helper_flds_ST0(cpu_env, s->tmp2_i32);
+ tcg_temp_free(last_addr);
+ } else {
+ /* register float ops */
+ opreg = rm;
+
+ switch (op) {
+ case 0x08: /* fld sti */
+ gen_helper_fpush(cpu_env);
+ gen_helper_fmov_ST0_STN(cpu_env,
+ tcg_const_i32((opreg + 1) & 7));
+ break;
+ case 0x09: /* fxchg sti */
+ case 0x29: /* fxchg4 sti, undocumented op */
+ case 0x39: /* fxchg7 sti, undocumented op */
+ gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
+ break;
+ case 0x0a: /* grp d9/2 */
+ switch (rm) {
+ case 0: /* fnop */
+ /* check exceptions (FreeBSD FPU probe) */
+ gen_helper_fwait(cpu_env);
+ update_fip = false;
break;
- case 1:
- tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUL);
- gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
+ default:
+ goto unknown_op;
+ }
+ break;
+ case 0x0c: /* grp d9/4 */
+ switch (rm) {
+ case 0: /* fchs */
+ gen_helper_fchs_ST0(cpu_env);
break;
- case 2:
- tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
- s->mem_index, MO_LEQ);
- gen_helper_fldl_ST0(cpu_env, s->tmp1_i64);
+ case 1: /* fabs */
+ gen_helper_fabs_ST0(cpu_env);
break;
- case 3:
- default:
- tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LESW);
- gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
+ case 4: /* ftst */
+ gen_helper_fldz_FT0(cpu_env);
+ gen_helper_fcom_ST0_FT0(cpu_env);
break;
+ case 5: /* fxam */
+ gen_helper_fxam_ST0(cpu_env);
+ break;
+ default:
+ goto unknown_op;
}
break;
- case 1:
- /* XXX: the corresponding CPUID bit must be tested ! */
- switch(op >> 4) {
- case 1:
- gen_helper_fisttl_ST0(s->tmp2_i32, cpu_env);
- tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUL);
+ case 0x0d: /* grp d9/5 */
+ {
+ switch (rm) {
+ case 0:
+ gen_helper_fpush(cpu_env);
+ gen_helper_fld1_ST0(cpu_env);
+ break;
+ case 1:
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldl2t_ST0(cpu_env);
+ break;
+ case 2:
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldl2e_ST0(cpu_env);
+ break;
+ case 3:
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldpi_ST0(cpu_env);
+ break;
+ case 4:
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldlg2_ST0(cpu_env);
+ break;
+ case 5:
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldln2_ST0(cpu_env);
+ break;
+ case 6:
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldz_ST0(cpu_env);
+ break;
+ default:
+ goto unknown_op;
+ }
+ }
+ break;
+ case 0x0e: /* grp d9/6 */
+ switch (rm) {
+ case 0: /* f2xm1 */
+ gen_helper_f2xm1(cpu_env);
break;
- case 2:
- gen_helper_fisttll_ST0(s->tmp1_i64, cpu_env);
- tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
- s->mem_index, MO_LEQ);
+ case 1: /* fyl2x */
+ gen_helper_fyl2x(cpu_env);
+ break;
+ case 2: /* fptan */
+ gen_helper_fptan(cpu_env);
+ break;
+ case 3: /* fpatan */
+ gen_helper_fpatan(cpu_env);
+ break;
+ case 4: /* fxtract */
+ gen_helper_fxtract(cpu_env);
+ break;
+ case 5: /* fprem1 */
+ gen_helper_fprem1(cpu_env);
+ break;
+ case 6: /* fdecstp */
+ gen_helper_fdecstp(cpu_env);
break;
- case 3:
default:
- gen_helper_fistt_ST0(s->tmp2_i32, cpu_env);
- tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUW);
+ case 7: /* fincstp */
+ gen_helper_fincstp(cpu_env);
break;
}
- gen_helper_fpop(cpu_env);
break;
- default:
- switch(op >> 4) {
- case 0:
- gen_helper_fsts_ST0(s->tmp2_i32, cpu_env);
- tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUL);
+ case 0x0f: /* grp d9/7 */
+ switch (rm) {
+ case 0: /* fprem */
+ gen_helper_fprem(cpu_env);
break;
- case 1:
- gen_helper_fistl_ST0(s->tmp2_i32, cpu_env);
- tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUL);
+ case 1: /* fyl2xp1 */
+ gen_helper_fyl2xp1(cpu_env);
break;
- case 2:
- gen_helper_fstl_ST0(s->tmp1_i64, cpu_env);
- tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
- s->mem_index, MO_LEQ);
+ case 2: /* fsqrt */
+ gen_helper_fsqrt(cpu_env);
+ break;
+ case 3: /* fsincos */
+ gen_helper_fsincos(cpu_env);
+ break;
+ case 5: /* fscale */
+ gen_helper_fscale(cpu_env);
+ break;
+ case 4: /* frndint */
+ gen_helper_frndint(cpu_env);
+ break;
+ case 6: /* fsin */
+ gen_helper_fsin(cpu_env);
break;
- case 3:
default:
- gen_helper_fist_ST0(s->tmp2_i32, cpu_env);
- tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUW);
+ case 7: /* fcos */
+ gen_helper_fcos(cpu_env);
break;
}
- if ((op & 7) == 3)
- gen_helper_fpop(cpu_env);
- break;
- }
- break;
- case 0x0c: /* fldenv mem */
- gen_helper_fldenv(cpu_env, s->A0, tcg_const_i32(dflag - 1));
- break;
- case 0x0d: /* fldcw mem */
- tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUW);
- gen_helper_fldcw(cpu_env, s->tmp2_i32);
- break;
- case 0x0e: /* fnstenv mem */
- gen_helper_fstenv(cpu_env, s->A0, tcg_const_i32(dflag - 1));
- break;
- case 0x0f: /* fnstcw mem */
- gen_helper_fnstcw(s->tmp2_i32, cpu_env);
- tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUW);
- break;
- case 0x1d: /* fldt mem */
- gen_helper_fldt_ST0(cpu_env, s->A0);
- break;
- case 0x1f: /* fstpt mem */
- gen_helper_fstt_ST0(cpu_env, s->A0);
- gen_helper_fpop(cpu_env);
- break;
- case 0x2c: /* frstor mem */
- gen_helper_frstor(cpu_env, s->A0, tcg_const_i32(dflag - 1));
- break;
- case 0x2e: /* fnsave mem */
- gen_helper_fsave(cpu_env, s->A0, tcg_const_i32(dflag - 1));
- break;
- case 0x2f: /* fnstsw mem */
- gen_helper_fnstsw(s->tmp2_i32, cpu_env);
- tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
- s->mem_index, MO_LEUW);
- break;
- case 0x3c: /* fbld */
- gen_helper_fbld_ST0(cpu_env, s->A0);
- break;
- case 0x3e: /* fbstp */
- gen_helper_fbst_ST0(cpu_env, s->A0);
- gen_helper_fpop(cpu_env);
- break;
- case 0x3d: /* fildll */
- tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEQ);
- gen_helper_fildll_ST0(cpu_env, s->tmp1_i64);
- break;
- case 0x3f: /* fistpll */
- gen_helper_fistll_ST0(s->tmp1_i64, cpu_env);
- tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEQ);
- gen_helper_fpop(cpu_env);
- break;
- default:
- goto unknown_op;
- }
- } else {
- /* register float ops */
- opreg = rm;
-
- switch(op) {
- case 0x08: /* fld sti */
- gen_helper_fpush(cpu_env);
- gen_helper_fmov_ST0_STN(cpu_env,
- tcg_const_i32((opreg + 1) & 7));
- break;
- case 0x09: /* fxchg sti */
- case 0x29: /* fxchg4 sti, undocumented op */
- case 0x39: /* fxchg7 sti, undocumented op */
- gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
- break;
- case 0x0a: /* grp d9/2 */
- switch(rm) {
- case 0: /* fnop */
- /* check exceptions (FreeBSD FPU probe) */
- gen_helper_fwait(cpu_env);
- break;
- default:
- goto unknown_op;
- }
- break;
- case 0x0c: /* grp d9/4 */
- switch(rm) {
- case 0: /* fchs */
- gen_helper_fchs_ST0(cpu_env);
break;
- case 1: /* fabs */
- gen_helper_fabs_ST0(cpu_env);
+ case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
+ case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
+ case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
+ {
+ int op1;
+
+ op1 = op & 7;
+ if (op >= 0x20) {
+ gen_helper_fp_arith_STN_ST0(op1, opreg);
+ if (op >= 0x30) {
+ gen_helper_fpop(cpu_env);
+ }
+ } else {
+ gen_helper_fmov_FT0_STN(cpu_env,
+ tcg_const_i32(opreg));
+ gen_helper_fp_arith_ST0_FT0(op1);
+ }
+ }
break;
- case 4: /* ftst */
- gen_helper_fldz_FT0(cpu_env);
+ case 0x02: /* fcom */
+ case 0x22: /* fcom2, undocumented op */
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
gen_helper_fcom_ST0_FT0(cpu_env);
break;
- case 5: /* fxam */
- gen_helper_fxam_ST0(cpu_env);
+ case 0x03: /* fcomp */
+ case 0x23: /* fcomp3, undocumented op */
+ case 0x32: /* fcomp5, undocumented op */
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fcom_ST0_FT0(cpu_env);
+ gen_helper_fpop(cpu_env);
break;
- default:
- goto unknown_op;
- }
- break;
- case 0x0d: /* grp d9/5 */
- {
- switch(rm) {
- case 0:
- gen_helper_fpush(cpu_env);
- gen_helper_fld1_ST0(cpu_env);
- break;
- case 1:
- gen_helper_fpush(cpu_env);
- gen_helper_fldl2t_ST0(cpu_env);
+ case 0x15: /* da/5 */
+ switch (rm) {
+ case 1: /* fucompp */
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
+ gen_helper_fucom_ST0_FT0(cpu_env);
+ gen_helper_fpop(cpu_env);
+ gen_helper_fpop(cpu_env);
break;
- case 2:
- gen_helper_fpush(cpu_env);
- gen_helper_fldl2e_ST0(cpu_env);
+ default:
+ goto unknown_op;
+ }
+ break;
+ case 0x1c:
+ switch (rm) {
+ case 0: /* feni (287 only, just do nop here) */
break;
- case 3:
- gen_helper_fpush(cpu_env);
- gen_helper_fldpi_ST0(cpu_env);
+ case 1: /* fdisi (287 only, just do nop here) */
break;
- case 4:
- gen_helper_fpush(cpu_env);
- gen_helper_fldlg2_ST0(cpu_env);
+ case 2: /* fclex */
+ gen_helper_fclex(cpu_env);
+ update_fip = false;
break;
- case 5:
- gen_helper_fpush(cpu_env);
- gen_helper_fldln2_ST0(cpu_env);
+ case 3: /* fninit */
+ gen_helper_fninit(cpu_env);
+ update_fip = false;
break;
- case 6:
- gen_helper_fpush(cpu_env);
- gen_helper_fldz_ST0(cpu_env);
+ case 4: /* fsetpm (287 only, just do nop here) */
break;
default:
goto unknown_op;
}
- }
- break;
- case 0x0e: /* grp d9/6 */
- switch(rm) {
- case 0: /* f2xm1 */
- gen_helper_f2xm1(cpu_env);
- break;
- case 1: /* fyl2x */
- gen_helper_fyl2x(cpu_env);
- break;
- case 2: /* fptan */
- gen_helper_fptan(cpu_env);
- break;
- case 3: /* fpatan */
- gen_helper_fpatan(cpu_env);
- break;
- case 4: /* fxtract */
- gen_helper_fxtract(cpu_env);
- break;
- case 5: /* fprem1 */
- gen_helper_fprem1(cpu_env);
- break;
- case 6: /* fdecstp */
- gen_helper_fdecstp(cpu_env);
break;
- default:
- case 7: /* fincstp */
- gen_helper_fincstp(cpu_env);
- break;
- }
- break;
- case 0x0f: /* grp d9/7 */
- switch(rm) {
- case 0: /* fprem */
- gen_helper_fprem(cpu_env);
- break;
- case 1: /* fyl2xp1 */
- gen_helper_fyl2xp1(cpu_env);
- break;
- case 2: /* fsqrt */
- gen_helper_fsqrt(cpu_env);
+ case 0x1d: /* fucomi */
+ if (!(s->cpuid_features & CPUID_CMOV)) {
+ goto illegal_op;
+ }
+ gen_update_cc_op(s);
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fucomi_ST0_FT0(cpu_env);
+ set_cc_op(s, CC_OP_EFLAGS);
break;
- case 3: /* fsincos */
- gen_helper_fsincos(cpu_env);
+ case 0x1e: /* fcomi */
+ if (!(s->cpuid_features & CPUID_CMOV)) {
+ goto illegal_op;
+ }
+ gen_update_cc_op(s);
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fcomi_ST0_FT0(cpu_env);
+ set_cc_op(s, CC_OP_EFLAGS);
break;
- case 5: /* fscale */
- gen_helper_fscale(cpu_env);
+ case 0x28: /* ffree sti */
+ gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
break;
- case 4: /* frndint */
- gen_helper_frndint(cpu_env);
+ case 0x2a: /* fst sti */
+ gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
break;
- case 6: /* fsin */
- gen_helper_fsin(cpu_env);
+ case 0x2b: /* fstp sti */
+ case 0x0b: /* fstp1 sti, undocumented op */
+ case 0x3a: /* fstp8 sti, undocumented op */
+ case 0x3b: /* fstp9 sti, undocumented op */
+ gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fpop(cpu_env);
break;
- default:
- case 7: /* fcos */
- gen_helper_fcos(cpu_env);
+ case 0x2c: /* fucom st(i) */
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fucom_ST0_FT0(cpu_env);
break;
- }
- break;
- case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
- case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
- case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
- {
- int op1;
-
- op1 = op & 7;
- if (op >= 0x20) {
- gen_helper_fp_arith_STN_ST0(op1, opreg);
- if (op >= 0x30)
- gen_helper_fpop(cpu_env);
- } else {
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
- gen_helper_fp_arith_ST0_FT0(op1);
- }
- }
- break;
- case 0x02: /* fcom */
- case 0x22: /* fcom2, undocumented op */
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
- gen_helper_fcom_ST0_FT0(cpu_env);
- break;
- case 0x03: /* fcomp */
- case 0x23: /* fcomp3, undocumented op */
- case 0x32: /* fcomp5, undocumented op */
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
- gen_helper_fcom_ST0_FT0(cpu_env);
- gen_helper_fpop(cpu_env);
- break;
- case 0x15: /* da/5 */
- switch(rm) {
- case 1: /* fucompp */
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
+ case 0x2d: /* fucomp st(i) */
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
gen_helper_fucom_ST0_FT0(cpu_env);
gen_helper_fpop(cpu_env);
- gen_helper_fpop(cpu_env);
break;
- default:
- goto unknown_op;
- }
- break;
- case 0x1c:
- switch(rm) {
- case 0: /* feni (287 only, just do nop here) */
- break;
- case 1: /* fdisi (287 only, just do nop here) */
- break;
- case 2: /* fclex */
- gen_helper_fclex(cpu_env);
+ case 0x33: /* de/3 */
+ switch (rm) {
+ case 1: /* fcompp */
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
+ gen_helper_fcom_ST0_FT0(cpu_env);
+ gen_helper_fpop(cpu_env);
+ gen_helper_fpop(cpu_env);
+ break;
+ default:
+ goto unknown_op;
+ }
break;
- case 3: /* fninit */
- gen_helper_fninit(cpu_env);
+ case 0x38: /* ffreep sti, undocumented op */
+ gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fpop(cpu_env);
break;
- case 4: /* fsetpm (287 only, just do nop here) */
+ case 0x3c: /* df/4 */
+ switch (rm) {
+ case 0:
+ gen_helper_fnstsw(s->tmp2_i32, cpu_env);
+ tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
+ gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
+ break;
+ default:
+ goto unknown_op;
+ }
break;
- default:
- goto unknown_op;
- }
- break;
- case 0x1d: /* fucomi */
- if (!(s->cpuid_features & CPUID_CMOV)) {
- goto illegal_op;
- }
- gen_update_cc_op(s);
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
- gen_helper_fucomi_ST0_FT0(cpu_env);
- set_cc_op(s, CC_OP_EFLAGS);
- break;
- case 0x1e: /* fcomi */
- if (!(s->cpuid_features & CPUID_CMOV)) {
- goto illegal_op;
- }
- gen_update_cc_op(s);
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
- gen_helper_fcomi_ST0_FT0(cpu_env);
- set_cc_op(s, CC_OP_EFLAGS);
- break;
- case 0x28: /* ffree sti */
- gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
- break;
- case 0x2a: /* fst sti */
- gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
- break;
- case 0x2b: /* fstp sti */
- case 0x0b: /* fstp1 sti, undocumented op */
- case 0x3a: /* fstp8 sti, undocumented op */
- case 0x3b: /* fstp9 sti, undocumented op */
- gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
- gen_helper_fpop(cpu_env);
- break;
- case 0x2c: /* fucom st(i) */
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
- gen_helper_fucom_ST0_FT0(cpu_env);
- break;
- case 0x2d: /* fucomp st(i) */
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
- gen_helper_fucom_ST0_FT0(cpu_env);
- gen_helper_fpop(cpu_env);
- break;
- case 0x33: /* de/3 */
- switch(rm) {
- case 1: /* fcompp */
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
- gen_helper_fcom_ST0_FT0(cpu_env);
+ case 0x3d: /* fucomip */
+ if (!(s->cpuid_features & CPUID_CMOV)) {
+ goto illegal_op;
+ }
+ gen_update_cc_op(s);
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fucomi_ST0_FT0(cpu_env);
gen_helper_fpop(cpu_env);
+ set_cc_op(s, CC_OP_EFLAGS);
+ break;
+ case 0x3e: /* fcomip */
+ if (!(s->cpuid_features & CPUID_CMOV)) {
+ goto illegal_op;
+ }
+ gen_update_cc_op(s);
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fcomi_ST0_FT0(cpu_env);
gen_helper_fpop(cpu_env);
+ set_cc_op(s, CC_OP_EFLAGS);
break;
- default:
- goto unknown_op;
- }
- break;
- case 0x38: /* ffreep sti, undocumented op */
- gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
- gen_helper_fpop(cpu_env);
- break;
- case 0x3c: /* df/4 */
- switch(rm) {
- case 0:
- gen_helper_fnstsw(s->tmp2_i32, cpu_env);
- tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
- gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
+ case 0x10 ... 0x13: /* fcmovxx */
+ case 0x18 ... 0x1b:
+ {
+ int op1;
+ TCGLabel *l1;
+ static const uint8_t fcmov_cc[8] = {
+ (JCC_B << 1),
+ (JCC_Z << 1),
+ (JCC_BE << 1),
+ (JCC_P << 1),
+ };
+
+ if (!(s->cpuid_features & CPUID_CMOV)) {
+ goto illegal_op;
+ }
+ op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
+ l1 = gen_new_label();
+ gen_jcc1_noeob(s, op1, l1);
+ gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_set_label(l1);
+ }
break;
default:
goto unknown_op;
}
- break;
- case 0x3d: /* fucomip */
- if (!(s->cpuid_features & CPUID_CMOV)) {
- goto illegal_op;
- }
- gen_update_cc_op(s);
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
- gen_helper_fucomi_ST0_FT0(cpu_env);
- gen_helper_fpop(cpu_env);
- set_cc_op(s, CC_OP_EFLAGS);
- break;
- case 0x3e: /* fcomip */
- if (!(s->cpuid_features & CPUID_CMOV)) {
- goto illegal_op;
- }
- gen_update_cc_op(s);
- gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
- gen_helper_fcomi_ST0_FT0(cpu_env);
- gen_helper_fpop(cpu_env);
- set_cc_op(s, CC_OP_EFLAGS);
- break;
- case 0x10 ... 0x13: /* fcmovxx */
- case 0x18 ... 0x1b:
- {
- int op1;
- TCGLabel *l1;
- static const uint8_t fcmov_cc[8] = {
- (JCC_B << 1),
- (JCC_Z << 1),
- (JCC_BE << 1),
- (JCC_P << 1),
- };
+ }
- if (!(s->cpuid_features & CPUID_CMOV)) {
- goto illegal_op;
- }
- op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
- l1 = gen_new_label();
- gen_jcc1_noeob(s, op1, l1);
- gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
- gen_set_label(l1);
- }
- break;
- default:
- goto unknown_op;
+ if (update_fip) {
+ tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
+ offsetof(CPUX86State, segs[R_CS].selector));
+ tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
+ offsetof(CPUX86State, fpcs));
+ tcg_gen_st_tl(tcg_constant_tl(pc_start - s->cs_base),
+ cpu_env, offsetof(CPUX86State, fpip));
}
}
break;
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 37c3e3e0a3..059da48475 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -52,6 +52,8 @@ typedef struct DisasContext {
/* The temporary corresponding to register 0 for this compilation. */
TCGv R0;
+ /* The constant zero. */
+ TCGv zero;
} DisasContext;
static inline bool is_user(DisasContext *dc)
@@ -129,9 +131,7 @@ void openrisc_translate_init(void)
static void gen_exception(DisasContext *dc, unsigned int excp)
{
- TCGv_i32 tmp = tcg_const_i32(excp);
- gen_helper_exception(cpu_env, tmp);
- tcg_temp_free_i32(tmp);
+ gen_helper_exception(cpu_env, tcg_constant_i32(excp));
}
static void gen_illegal_exception(DisasContext *dc)
@@ -199,10 +199,10 @@ static void gen_ove_cyov(DisasContext *dc)
static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
{
- TCGv t0 = tcg_const_tl(0);
+ TCGv t0 = tcg_temp_new();
TCGv res = tcg_temp_new();
- tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, srcb, t0);
+ tcg_gen_add2_tl(res, cpu_sr_cy, srca, dc->zero, srcb, dc->zero);
tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
tcg_gen_xor_tl(t0, res, srcb);
tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
@@ -216,11 +216,11 @@ static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
{
- TCGv t0 = tcg_const_tl(0);
+ TCGv t0 = tcg_temp_new();
TCGv res = tcg_temp_new();
- tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, cpu_sr_cy, t0);
- tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, t0);
+ tcg_gen_add2_tl(res, cpu_sr_cy, srca, dc->zero, cpu_sr_cy, dc->zero);
+ tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, dc->zero);
tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
tcg_gen_xor_tl(t0, res, srcb);
tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
@@ -538,13 +538,9 @@ static bool trans_l_extbz(DisasContext *dc, arg_da *a)
static bool trans_l_cmov(DisasContext *dc, arg_dab *a)
{
- TCGv zero;
-
check_r0_write(dc, a->d);
- zero = tcg_const_tl(0);
- tcg_gen_movcond_tl(TCG_COND_NE, cpu_R(dc, a->d), cpu_sr_f, zero,
+ tcg_gen_movcond_tl(TCG_COND_NE, cpu_R(dc, a->d), cpu_sr_f, dc->zero,
cpu_R(dc, a->a), cpu_R(dc, a->b));
- tcg_temp_free(zero);
return true;
}
@@ -632,15 +628,10 @@ static bool trans_l_jal(DisasContext *dc, arg_l_jal *a)
static void do_bf(DisasContext *dc, arg_l_bf *a, TCGCond cond)
{
target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
- TCGv t_next = tcg_const_tl(dc->base.pc_next + 8);
- TCGv t_true = tcg_const_tl(tmp_pc);
- TCGv t_zero = tcg_const_tl(0);
-
- tcg_gen_movcond_tl(cond, jmp_pc, cpu_sr_f, t_zero, t_true, t_next);
+ TCGv t_next = tcg_constant_tl(dc->base.pc_next + 8);
+ TCGv t_true = tcg_constant_tl(tmp_pc);
- tcg_temp_free(t_next);
- tcg_temp_free(t_true);
- tcg_temp_free(t_zero);
+ tcg_gen_movcond_tl(cond, jmp_pc, cpu_sr_f, dc->zero, t_true, t_next);
dc->delayed_branch = 2;
}
@@ -740,12 +731,6 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a)
ea = tcg_temp_new();
tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i);
- /* For TB_FLAGS_R0_0, the branch below invalidates the temporary assigned
- to cpu_regs[0]. Since l.swa is quite often immediately followed by a
- branch, don't bother reallocating; finish the TB using the "real" R0.
- This also takes care of RB input across the branch. */
- dc->R0 = cpu_regs[0];
-
lab_fail = gen_new_label();
lab_done = gen_new_label();
tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);
@@ -753,7 +738,7 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a)
val = tcg_temp_new();
tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,
- cpu_regs[a->b], dc->mem_idx, MO_TEUL);
+ cpu_R(dc, a->b), dc->mem_idx, MO_TEUL);
tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value);
tcg_temp_free(val);
@@ -813,44 +798,28 @@ static bool trans_l_adrp(DisasContext *dc, arg_l_adrp *a)
static bool trans_l_addi(DisasContext *dc, arg_rri *a)
{
- TCGv t0;
-
check_r0_write(dc, a->d);
- t0 = tcg_const_tl(a->i);
- gen_add(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), t0);
- tcg_temp_free(t0);
+ gen_add(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), tcg_constant_tl(a->i));
return true;
}
static bool trans_l_addic(DisasContext *dc, arg_rri *a)
{
- TCGv t0;
-
check_r0_write(dc, a->d);
- t0 = tcg_const_tl(a->i);
- gen_addc(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), t0);
- tcg_temp_free(t0);
+ gen_addc(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), tcg_constant_tl(a->i));
return true;
}
static bool trans_l_muli(DisasContext *dc, arg_rri *a)
{
- TCGv t0;
-
check_r0_write(dc, a->d);
- t0 = tcg_const_tl(a->i);
- gen_mul(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), t0);
- tcg_temp_free(t0);
+ gen_mul(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), tcg_constant_tl(a->i));
return true;
}
static bool trans_l_maci(DisasContext *dc, arg_l_maci *a)
{
- TCGv t0;
-
- t0 = tcg_const_tl(a->i);
- gen_mac(dc, cpu_R(dc, a->a), t0);
- tcg_temp_free(t0);
+ gen_mac(dc, cpu_R(dc, a->a), tcg_constant_tl(a->i));
return true;
}
@@ -1624,8 +1593,9 @@ static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs)
/* Allow the TCG optimizer to see that R0 == 0,
when it's true, which is the common case. */
+ dc->zero = tcg_constant_tl(0);
if (dc->tb_flags & TB_FLAGS_R0_0) {
- dc->R0 = tcg_const_tl(0);
+ dc->R0 = dc->zero;
} else {
dc->R0 = cpu_regs[0];
}
diff --git a/tests/Makefile.include b/tests/Makefile.include
index e4dcb17329..6e16c05f10 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -96,7 +96,7 @@ AVOCADO_TAGS=$(patsubst %-softmmu,-t arch:%, $(filter %-softmmu,$(TARGETS)))
$(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
$(call quiet-command, \
- $(PYTHON) -m venv --system-site-packages $@, \
+ $(PYTHON) -m venv $@, \
VENV, $@)
$(call quiet-command, \
$(TESTS_VENV_DIR)/bin/python -m pip -q install -r $(TESTS_VENV_REQ), \
diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
index 93c4b9851f..2c4fef3e14 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -86,14 +86,17 @@ def _console_interaction(test, success_message, failure_message,
assert not keep_sending or send_string
if vm is None:
vm = test.vm
- console = vm.console_socket.makefile()
+ console = vm.console_socket.makefile(mode='rb', encoding='utf-8')
console_logger = logging.getLogger('console')
while True:
if send_string:
vm.console_socket.sendall(send_string.encode())
if not keep_sending:
send_string = None # send only once
- msg = console.readline().strip()
+ try:
+ msg = console.readline().decode().strip()
+ except UnicodeDecodeError:
+ msg = None
if not msg:
continue
console_logger.debug(msg)
@@ -210,6 +213,9 @@ class Test(avocado.Test):
self.arch = self.params.get('arch',
default=self._get_unique_tag_val('arch'))
+ self.cpu = self.params.get('cpu',
+ default=self._get_unique_tag_val('cpu'))
+
self.machine = self.params.get('machine',
default=self._get_unique_tag_val('machine'))
@@ -219,9 +225,13 @@ class Test(avocado.Test):
if self.qemu_bin is None:
self.cancel("No QEMU binary defined or found in the build tree")
- def _new_vm(self, *args):
+ def _new_vm(self, name, *args):
self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_")
- vm = QEMUMachine(self.qemu_bin, sock_dir=self._sd.name)
+ vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir,
+ sock_dir=self._sd.name, log_dir=self.logdir)
+ self.log.debug('QEMUMachine "%s" created', name)
+ self.log.debug('QEMUMachine "%s" temp_dir: %s', name, vm.temp_dir)
+ self.log.debug('QEMUMachine "%s" log_dir: %s', name, vm.log_dir)
if args:
vm.add_args(*args)
return vm
@@ -234,11 +244,34 @@ class Test(avocado.Test):
if not name:
name = str(uuid.uuid4())
if self._vms.get(name) is None:
- self._vms[name] = self._new_vm(*args)
+ self._vms[name] = self._new_vm(name, *args)
+ if self.cpu is not None:
+ self._vms[name].add_args('-cpu', self.cpu)
if self.machine is not None:
self._vms[name].set_machine(self.machine)
return self._vms[name]
+ def set_vm_arg(self, arg, value):
+ """
+ Set an argument to list of extra arguments to be given to the QEMU
+ binary. If the argument already exists then its value is replaced.
+
+ :param arg: the QEMU argument, such as "-cpu" in "-cpu host"
+ :type arg: str
+ :param value: the argument value, such as "host" in "-cpu host"
+ :type value: str
+ """
+ if not arg or not value:
+ return
+ if arg not in self.vm.args:
+ self.vm.args.extend([arg, value])
+ else:
+ idx = self.vm.args.index(arg) + 1
+ if idx < len(self.vm.args):
+ self.vm.args[idx] = value
+ else:
+ self.vm.args.append(value)
+
def tearDown(self):
for vm in self._vms.values():
vm.shutdown()
@@ -299,6 +332,103 @@ class LinuxSSHMixIn:
f'Guest command failed: {command}')
return stdout_lines, stderr_lines
+class LinuxDistro:
+ """Represents a Linux distribution
+
+ Holds information of known distros.
+ """
+ #: A collection of known distros and their respective image checksum
+ KNOWN_DISTROS = {
+ 'fedora': {
+ '31': {
+ 'x86_64':
+ {'checksum': ('e3c1b309d9203604922d6e255c2c5d09'
+ '8a309c2d46215d8fc026954f3c5c27a0'),
+ 'pxeboot_url': ('https://archives.fedoraproject.org/'
+ 'pub/archive/fedora/linux/releases/31/'
+ 'Everything/x86_64/os/images/pxeboot/'),
+ 'kernel_params': ('root=UUID=b1438b9b-2cab-4065-a99a-'
+ '08a96687f73c ro no_timer_check '
+ 'net.ifnames=0 console=tty1 '
+ 'console=ttyS0,115200n8'),
+ },
+ 'aarch64':
+ {'checksum': ('1e18d9c0cf734940c4b5d5ec592facae'
+ 'd2af0ad0329383d5639c997fdf16fe49'),
+ 'pxeboot_url': 'https://archives.fedoraproject.org/'
+ 'pub/archive/fedora/linux/releases/31/'
+ 'Everything/aarch64/os/images/pxeboot/',
+ 'kernel_params': ('root=UUID=b6950a44-9f3c-4076-a9c2-'
+ '355e8475b0a7 ro earlyprintk=pl011,0x9000000'
+ ' ignore_loglevel no_timer_check'
+ ' printk.time=1 rd_NO_PLYMOUTH'
+ ' console=ttyAMA0'),
+ },
+ 'ppc64':
+ {'checksum': ('7c3528b85a3df4b2306e892199a9e1e4'
+ '3f991c506f2cc390dc4efa2026ad2f58')},
+ 's390x':
+ {'checksum': ('4caaab5a434fd4d1079149a072fdc789'
+ '1e354f834d355069ca982fdcaf5a122d')},
+ },
+ '32': {
+ 'aarch64':
+ {'checksum': ('b367755c664a2d7a26955bbfff985855'
+ 'adfa2ca15e908baf15b4b176d68d3967'),
+ 'pxeboot_url': ('http://dl.fedoraproject.org/pub/fedora/linux/'
+ 'releases/32/Server/aarch64/os/images/'
+ 'pxeboot/'),
+ 'kernel_params': ('root=UUID=3df75b65-be8d-4db4-8655-'
+ '14d95c0e90c5 ro no_timer_check net.ifnames=0'
+ ' console=tty1 console=ttyS0,115200n8'),
+ },
+ },
+ '33': {
+ 'aarch64':
+ {'checksum': ('e7f75cdfd523fe5ac2ca9eeece68edc1'
+ 'a81f386a17f969c1d1c7c87031008a6b'),
+ 'pxeboot_url': ('http://dl.fedoraproject.org/pub/fedora/linux/'
+ 'releases/33/Server/aarch64/os/images/'
+ 'pxeboot/'),
+ 'kernel_params': ('root=UUID=d20b3ffa-6397-4a63-a734-'
+ '1126a0208f8a ro no_timer_check net.ifnames=0'
+ ' console=tty1 console=ttyS0,115200n8'
+ ' console=tty0'),
+ },
+ },
+ }
+ }
+
+ def __init__(self, name, version, arch):
+ self.name = name
+ self.version = version
+ self.arch = arch
+ try:
+ info = self.KNOWN_DISTROS.get(name).get(version).get(arch)
+ except AttributeError:
+ # Unknown distro
+ info = None
+ self._info = info or {}
+
+ @property
+ def checksum(self):
+ """Gets the cloud-image file checksum"""
+ return self._info.get('checksum', None)
+
+ @checksum.setter
+ def checksum(self, value):
+ self._info['checksum'] = value
+
+ @property
+ def pxeboot_url(self):
+ """Gets the repository url where pxeboot files can be found"""
+ return self._info.get('pxeboot_url', None)
+
+ @property
+ def default_kernel_params(self):
+ """Gets the default kernel parameters"""
+ return self._info.get('kernel_params', None)
+
class LinuxTest(Test, LinuxSSHMixIn):
"""Facilitates having a cloud-image Linux based available.
@@ -308,12 +438,39 @@ class LinuxTest(Test, LinuxSSHMixIn):
"""
timeout = 900
- chksum = None
+ distro = None
username = 'root'
password = 'password'
+ def _set_distro(self):
+ distro_name = self.params.get(
+ 'distro',
+ default=self._get_unique_tag_val('distro'))
+ if not distro_name:
+ distro_name = 'fedora'
+
+ distro_version = self.params.get(
+ 'distro_version',
+ default=self._get_unique_tag_val('distro_version'))
+ if not distro_version:
+ distro_version = '31'
+
+ self.distro = LinuxDistro(distro_name, distro_version, self.arch)
+
+ # The distro checksum behaves differently than distro name and
+ # version. First, it does not respect a tag with the same
+ # name, given that it's not expected to be used for filtering
+ # (distro name versions are the natural choice). Second, the
+ # order of precedence is: parameter, attribute and then value
+ # from KNOWN_DISTROS.
+ distro_checksum = self.params.get('distro_checksum',
+ default=None)
+ if distro_checksum:
+ self.distro.checksum = distro_checksum
+
def setUp(self, ssh_pubkey=None, network_device_type='virtio-net'):
super(LinuxTest, self).setUp()
+ self._set_distro()
self.vm.add_args('-smp', '2')
self.vm.add_args('-m', '1024')
# The following network device allows for SSH connections
@@ -351,12 +508,14 @@ class LinuxTest(Test, LinuxSSHMixIn):
self.log.info('Downloading/preparing boot image')
# Fedora 31 only provides ppc64le images
image_arch = self.arch
- if image_arch == 'ppc64':
- image_arch = 'ppc64le'
+ if self.distro.name == 'fedora':
+ if image_arch == 'ppc64':
+ image_arch = 'ppc64le'
+
try:
boot = vmimage.get(
- 'fedora', arch=image_arch, version='31',
- checksum=self.chksum,
+ self.distro.name, arch=image_arch, version=self.distro.version,
+ checksum=self.distro.checksum,
algorithm='sha256',
cache_dir=self.cache_dirs[0],
snapshot_dir=self.workdir)
diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py
index 4c8a5994b2..ab19146d1e 100644
--- a/tests/acceptance/boot_linux.py
+++ b/tests/acceptance/boot_linux.py
@@ -20,8 +20,6 @@ class BootLinuxX8664(LinuxTest):
:avocado: tags=arch:x86_64
"""
- chksum = 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0'
-
def test_pc_i440fx_tcg(self):
"""
:avocado: tags=machine:pc
@@ -66,8 +64,6 @@ class BootLinuxAarch64(LinuxTest):
:avocado: tags=machine:gic-version=2
"""
- chksum = '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49'
-
def add_common_args(self):
self.vm.add_args('-bios',
os.path.join(BUILD_DIR, 'pc-bios',
@@ -83,7 +79,6 @@ class BootLinuxAarch64(LinuxTest):
"""
self.require_accelerator("tcg")
self.vm.add_args("-accel", "tcg")
- self.vm.add_args("-cpu", "max")
self.vm.add_args("-machine", "virt,gic-version=2")
self.add_common_args()
self.launch_and_wait(set_up_ssh_connection=False)
@@ -96,7 +91,6 @@ class BootLinuxAarch64(LinuxTest):
"""
self.require_accelerator("tcg")
self.vm.add_args("-accel", "tcg")
- self.vm.add_args("-cpu", "max")
self.vm.add_args("-machine", "virt,gic-version=3")
self.add_common_args()
self.launch_and_wait(set_up_ssh_connection=False)
@@ -108,7 +102,6 @@ class BootLinuxAarch64(LinuxTest):
"""
self.require_accelerator("kvm")
self.vm.add_args("-accel", "kvm")
- self.vm.add_args("-cpu", "host")
self.vm.add_args("-machine", "virt,gic-version=host")
self.add_common_args()
self.launch_and_wait(set_up_ssh_connection=False)
@@ -119,8 +112,6 @@ class BootLinuxPPC64(LinuxTest):
:avocado: tags=arch:ppc64
"""
- chksum = '7c3528b85a3df4b2306e892199a9e1e43f991c506f2cc390dc4efa2026ad2f58'
-
def test_pseries_tcg(self):
"""
:avocado: tags=machine:pseries
@@ -136,8 +127,6 @@ class BootLinuxS390X(LinuxTest):
:avocado: tags=arch:s390x
"""
- chksum = '4caaab5a434fd4d1079149a072fdc7891e354f834d355069ca982fdcaf5a122d'
-
@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
def test_s390_ccw_virtio_tcg(self):
"""
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
index 3ae11a7a8f..5248c8097d 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -239,6 +239,7 @@ class BootLinuxConsole(LinuxKernelTest):
:avocado: tags=arch:mips64el
:avocado: tags=machine:malta
:avocado: tags=endian:little
+ :avocado: tags=cpu:5KEc
"""
kernel_url = ('https://github.com/philmd/qemu-testing-blob/'
'raw/9ad2df38/mips/malta/mips64el/'
@@ -258,8 +259,7 @@ class BootLinuxConsole(LinuxKernelTest):
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ 'console=ttyS0 console=tty '
+ 'rdinit=/sbin/init noreboot')
- self.vm.add_args('-cpu', '5KEc',
- '-kernel', kernel_path,
+ self.vm.add_args('-kernel', kernel_path,
'-initrd', initrd_path,
'-append', kernel_command_line,
'-no-reboot')
@@ -287,7 +287,6 @@ class BootLinuxConsole(LinuxKernelTest):
+ 'mem=256m@@0x0 '
+ 'console=ttyS0')
self.vm.add_args('-no-reboot',
- '-cpu', 'I7200',
'-kernel', kernel_path,
'-append', kernel_command_line)
self.vm.launch()
@@ -299,6 +298,7 @@ class BootLinuxConsole(LinuxKernelTest):
:avocado: tags=arch:mipsel
:avocado: tags=machine:malta
:avocado: tags=endian:little
+ :avocado: tags=cpu:I7200
"""
kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
@@ -311,6 +311,7 @@ class BootLinuxConsole(LinuxKernelTest):
:avocado: tags=arch:mipsel
:avocado: tags=machine:malta
:avocado: tags=endian:little
+ :avocado: tags=cpu:I7200
"""
kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
@@ -323,6 +324,7 @@ class BootLinuxConsole(LinuxKernelTest):
:avocado: tags=arch:mipsel
:avocado: tags=machine:malta
:avocado: tags=endian:little
+ :avocado: tags=cpu:I7200
"""
kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
@@ -335,6 +337,7 @@ class BootLinuxConsole(LinuxKernelTest):
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
:avocado: tags=accel:tcg
+ :avocado: tags=cpu:cortex-a53
"""
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
'/linux/releases/29/Everything/aarch64/os/images/pxeboot'
@@ -905,6 +908,7 @@ class BootLinuxConsole(LinuxKernelTest):
:avocado: tags=arch:arm
:avocado: tags=machine:orangepi-pc
:avocado: tags=device:sd
+ :avocado: tags=os:netbsd
"""
# This test download a 304MB compressed image and expand it to 2GB
deb_url = ('http://snapshot.debian.org/archive/debian/'
@@ -1167,9 +1171,9 @@ class BootLinuxConsole(LinuxKernelTest):
"""
:avocado: tags=arch:ppc64
:avocado: tags=machine:ppce500
+ :avocado: tags=cpu:e5500
"""
tar_hash = '6951d86d644b302898da2fd701739c9406527fe1'
- self.vm.add_args('-cpu', 'e5500')
self.do_test_advcal_2018('19', tar_hash, 'uImage')
def test_ppc_g3beige(self):
@@ -1211,7 +1215,7 @@ class BootLinuxConsole(LinuxKernelTest):
"""
:avocado: tags=arch:xtensa
:avocado: tags=machine:lx60
+ :avocado: tags=cpu:dc233c
"""
tar_hash = '49e88d9933742f0164b60839886c9739cb7a0d34'
- self.vm.add_args('-cpu', 'dc233c')
self.do_test_advcal_2018('02', tar_hash, 'santas-sleigh-ride.elf')
diff --git a/tests/acceptance/boot_xen.py b/tests/acceptance/boot_xen.py
index 75c2d44492..3479b5233b 100644
--- a/tests/acceptance/boot_xen.py
+++ b/tests/acceptance/boot_xen.py
@@ -48,7 +48,6 @@ class BootXenBase(LinuxKernelTest):
xen_command_line = self.XEN_COMMON_COMMAND_LINE
self.vm.add_args('-machine', 'virtualization=on',
- '-cpu', 'cortex-a57',
'-m', '768',
'-kernel', xen_path,
'-append', xen_command_line,
diff --git a/tests/acceptance/cpu_queries.py b/tests/acceptance/cpu_queries.py
index 293dccb89a..cc9e380cc7 100644
--- a/tests/acceptance/cpu_queries.py
+++ b/tests/acceptance/cpu_queries.py
@@ -8,8 +8,6 @@
# This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory.
-import logging
-
from avocado_qemu import Test
class QueryCPUModelExpansion(Test):
@@ -27,7 +25,7 @@ class QueryCPUModelExpansion(Test):
cpus = self.vm.command('query-cpu-definitions')
for c in cpus:
- print(repr(c))
+ self.log.info("Checking CPU: %s", c)
self.assertNotIn('', c['unavailable-features'], c['name'])
for c in cpus:
diff --git a/tests/acceptance/intel_iommu.py b/tests/acceptance/intel_iommu.py
new file mode 100644
index 0000000000..474d62f6bf
--- /dev/null
+++ b/tests/acceptance/intel_iommu.py
@@ -0,0 +1,119 @@
+# INTEL_IOMMU Functional tests
+#
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# Author:
+# Eric Auger <eric.auger@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+import os
+
+from avocado import skipIf
+from avocado_qemu import LinuxTest
+
+@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
+class IntelIOMMU(LinuxTest):
+ """
+ :avocado: tags=arch:x86_64
+ :avocado: tags=distro:fedora
+ :avocado: tags=distro_version:31
+ :avocado: tags=machine:q35
+ :avocado: tags=accel:kvm
+ :avocado: tags=intel_iommu
+ """
+
+ IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on'
+ kernel_path = None
+ initrd_path = None
+ kernel_params = None
+
+ def set_up_boot(self):
+ path = self.download_boot()
+ self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,scsi=off,' +
+ 'drive=drv0,id=virtio-disk0,bootindex=1,'
+ 'werror=stop,rerror=stop' + self.IOMMU_ADDON)
+ self.vm.add_args('-device', 'virtio-gpu-pci' + self.IOMMU_ADDON)
+ self.vm.add_args('-drive',
+ 'file=%s,if=none,cache=writethrough,id=drv0' % path)
+
+ def setUp(self):
+ super(IntelIOMMU, self).setUp(None, 'virtio-net-pci' + self.IOMMU_ADDON)
+
+ def add_common_args(self):
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
+ self.vm.add_args('-object',
+ 'rng-random,id=rng0,filename=/dev/urandom')
+
+ def common_vm_setup(self, custom_kernel=None):
+ self.require_accelerator("kvm")
+ self.add_common_args()
+ self.vm.add_args("-accel", "kvm")
+
+ if custom_kernel is None:
+ return
+
+ kernel_url = self.distro.pxeboot_url + 'vmlinuz'
+ initrd_url = self.distro.pxeboot_url + 'initrd.img'
+ self.kernel_path = self.fetch_asset(kernel_url)
+ self.initrd_path = self.fetch_asset(initrd_url)
+
+ def run_and_check(self):
+ if self.kernel_path:
+ self.vm.add_args('-kernel', self.kernel_path,
+ '-append', self.kernel_params,
+ '-initrd', self.initrd_path)
+ self.launch_and_wait()
+ self.ssh_command('cat /proc/cmdline')
+ self.ssh_command('dmesg | grep -e DMAR -e IOMMU')
+ self.ssh_command('find /sys/kernel/iommu_groups/ -type l')
+ self.ssh_command('dnf -y install numactl-devel')
+
+ def test_intel_iommu(self):
+ """
+ :avocado: tags=intel_iommu_intremap
+ """
+
+ self.common_vm_setup(True)
+ self.vm.add_args('-device', 'intel-iommu,intremap=on')
+ self.vm.add_args('-machine', 'kernel_irqchip=split')
+
+ self.kernel_params = (self.distro.default_kernel_params +
+ ' quiet intel_iommu=on')
+ self.run_and_check()
+
+ def test_intel_iommu_strict(self):
+ """
+ :avocado: tags=intel_iommu_strict
+ """
+
+ self.common_vm_setup(True)
+ self.vm.add_args('-device', 'intel-iommu,intremap=on')
+ self.vm.add_args('-machine', 'kernel_irqchip=split')
+ self.kernel_params = (self.distro.default_kernel_params +
+ ' quiet intel_iommu=on,strict')
+ self.run_and_check()
+
+ def test_intel_iommu_strict_cm(self):
+ """
+ :avocado: tags=intel_iommu_strict_cm
+ """
+
+ self.common_vm_setup(True)
+ self.vm.add_args('-device', 'intel-iommu,intremap=on,caching-mode=on')
+ self.vm.add_args('-machine', 'kernel_irqchip=split')
+ self.kernel_params = (self.distro.default_kernel_params +
+ ' quiet intel_iommu=on,strict')
+ self.run_and_check()
+
+ def test_intel_iommu_pt(self):
+ """
+ :avocado: tags=intel_iommu_pt
+ """
+
+ self.common_vm_setup(True)
+ self.vm.add_args('-device', 'intel-iommu,intremap=on')
+ self.vm.add_args('-machine', 'kernel_irqchip=split')
+ self.kernel_params = (self.distro.default_kernel_params +
+ ' quiet intel_iommu=on iommu=pt')
+ self.run_and_check()
diff --git a/tests/acceptance/linux_ssh_mips_malta.py b/tests/acceptance/linux_ssh_mips_malta.py
index 61c9079d04..4de1947418 100644
--- a/tests/acceptance/linux_ssh_mips_malta.py
+++ b/tests/acceptance/linux_ssh_mips_malta.py
@@ -19,6 +19,8 @@ from avocado.utils import archive
from avocado.utils import ssh
+@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
+@skipUnless(ssh.SSH_CLIENT_BINARY, 'No SSH client available')
class LinuxSSH(Test, LinuxSSHMixIn):
timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg'
@@ -65,11 +67,6 @@ class LinuxSSH(Test, LinuxSSHMixIn):
kernel_hash = self.IMAGE_INFO[endianess]['kernel_hash'][wordsize]
return kernel_url, kernel_hash
- @skipUnless(ssh.SSH_CLIENT_BINARY, 'No SSH client available')
- @skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
- def setUp(self):
- super(LinuxSSH, self).setUp()
-
def ssh_disconnect_vm(self):
self.ssh_session.quit()
diff --git a/tests/acceptance/machine_mips_malta.py b/tests/acceptance/machine_mips_malta.py
index 7c9a4ee4d2..b67d8cb141 100644
--- a/tests/acceptance/machine_mips_malta.py
+++ b/tests/acceptance/machine_mips_malta.py
@@ -62,7 +62,6 @@ class MaltaMachineFramebuffer(Test):
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'clocksource=GIC console=tty0 console=ttyS0')
self.vm.add_args('-kernel', kernel_path,
- '-cpu', 'I6400',
'-smp', '%u' % cpu_cores_count,
'-vga', 'std',
'-append', kernel_command_line)
@@ -96,7 +95,7 @@ class MaltaMachineFramebuffer(Test):
"""
:avocado: tags=arch:mips64el
:avocado: tags=machine:malta
- :avocado: tags=cpu:i6400
+ :avocado: tags=cpu:I6400
"""
self.do_test_i6400_framebuffer_logo(1)
@@ -105,7 +104,7 @@ class MaltaMachineFramebuffer(Test):
"""
:avocado: tags=arch:mips64el
:avocado: tags=machine:malta
- :avocado: tags=cpu:i6400
+ :avocado: tags=cpu:I6400
:avocado: tags=mips:smp
"""
self.do_test_i6400_framebuffer_logo(7)
@@ -115,7 +114,7 @@ class MaltaMachineFramebuffer(Test):
"""
:avocado: tags=arch:mips64el
:avocado: tags=machine:malta
- :avocado: tags=cpu:i6400
+ :avocado: tags=cpu:I6400
:avocado: tags=mips:smp
"""
self.do_test_i6400_framebuffer_logo(8)
diff --git a/tests/acceptance/pc_cpu_hotplug_props.py b/tests/acceptance/pc_cpu_hotplug_props.py
index f48f68fc6b..2e86d5017a 100644
--- a/tests/acceptance/pc_cpu_hotplug_props.py
+++ b/tests/acceptance/pc_cpu_hotplug_props.py
@@ -25,11 +25,11 @@ from avocado_qemu import Test
class OmittedCPUProps(Test):
"""
:avocado: tags=arch:x86_64
+ :avocado: tags=cpu:qemu64
"""
def test_no_die_id(self):
self.vm.add_args('-nodefaults', '-S')
self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8')
- self.vm.add_args('-cpu', 'qemu64')
self.vm.add_args('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0')
self.vm.launch()
self.assertEquals(len(self.vm.command('query-cpus-fast')), 2)
diff --git a/tests/acceptance/ppc_prep_40p.py b/tests/acceptance/ppc_prep_40p.py
index 96ba13b894..2993ee3b07 100644
--- a/tests/acceptance/ppc_prep_40p.py
+++ b/tests/acceptance/ppc_prep_40p.py
@@ -27,6 +27,7 @@ class IbmPrep40pMachine(Test):
"""
:avocado: tags=arch:ppc
:avocado: tags=machine:40p
+ :avocado: tags=os:netbsd
:avocado: tags=slowness:high
"""
bios_url = ('http://ftpmirror.your.org/pub/misc/'
@@ -64,6 +65,7 @@ class IbmPrep40pMachine(Test):
"""
:avocado: tags=arch:ppc
:avocado: tags=machine:40p
+ :avocado: tags=os:netbsd
"""
drive_url = ('https://cdn.netbsd.org/pub/NetBSD/iso/7.1.2/'
'NetBSD-7.1.2-prep.iso')
diff --git a/tests/acceptance/replay_kernel.py b/tests/acceptance/replay_kernel.py
index 71facdaa75..bb32b31240 100644
--- a/tests/acceptance/replay_kernel.py
+++ b/tests/acceptance/replay_kernel.py
@@ -156,8 +156,7 @@ class ReplayKernelNormal(ReplayKernelBase):
'console=ttyAMA0')
console_pattern = 'VFS: Cannot open root device'
- self.run_rr(kernel_path, kernel_command_line, console_pattern,
- args=('-cpu', 'cortex-a53'))
+ self.run_rr(kernel_path, kernel_command_line, console_pattern)
def test_arm_virt(self):
"""
@@ -301,7 +300,7 @@ class ReplayKernelNormal(ReplayKernelBase):
tar_url = ('https://www.qemu-advent-calendar.org'
'/2018/download/day19.tar.xz')
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
- self.do_test_advcal_2018(file_path, 'uImage', ('-cpu', 'e5500'))
+ self.do_test_advcal_2018(file_path, 'uImage')
def test_ppc_g3beige(self):
"""
@@ -348,8 +347,7 @@ class ReplayKernelNormal(ReplayKernelBase):
tar_url = ('https://www.qemu-advent-calendar.org'
'/2018/download/day02.tar.xz')
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
- self.do_test_advcal_2018(file_path, 'santas-sleigh-ride.elf',
- args=('-cpu', 'dc233c'))
+ self.do_test_advcal_2018(file_path, 'santas-sleigh-ride.elf')
@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
class ReplayKernelSlow(ReplayKernelBase):
@@ -394,6 +392,7 @@ class ReplayKernelSlow(ReplayKernelBase):
:avocado: tags=machine:malta
:avocado: tags=endian:little
:avocado: tags=slowness:high
+ :avocado: tags=cpu:5KEc
"""
kernel_url = ('https://github.com/philmd/qemu-testing-blob/'
'raw/9ad2df38/mips/malta/mips64el/'
@@ -414,7 +413,7 @@ class ReplayKernelSlow(ReplayKernelBase):
'rdinit=/sbin/init noreboot')
console_pattern = 'Boot successful.'
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5,
- args=('-initrd', initrd_path, '-cpu', '5KEc'))
+ args=('-initrd', initrd_path))
def do_test_mips_malta32el_nanomips(self, kernel_path_xz):
kernel_path = self.workdir + "kernel"
@@ -426,14 +425,14 @@ class ReplayKernelSlow(ReplayKernelBase):
'mem=256m@@0x0 '
'console=ttyS0')
console_pattern = 'Kernel command line: %s' % kernel_command_line
- self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5,
- args=('-cpu', 'I7200'))
+ self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
def test_mips_malta32el_nanomips_4k(self):
"""
:avocado: tags=arch:mipsel
:avocado: tags=machine:malta
:avocado: tags=endian:little
+ :avocado: tags=cpu:I7200
"""
kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
@@ -447,6 +446,7 @@ class ReplayKernelSlow(ReplayKernelBase):
:avocado: tags=arch:mipsel
:avocado: tags=machine:malta
:avocado: tags=endian:little
+ :avocado: tags=cpu:I7200
"""
kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
@@ -460,6 +460,7 @@ class ReplayKernelSlow(ReplayKernelBase):
:avocado: tags=arch:mipsel
:avocado: tags=machine:malta
:avocado: tags=endian:little
+ :avocado: tags=cpu:I7200
"""
kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
diff --git a/tests/acceptance/reverse_debugging.py b/tests/acceptance/reverse_debugging.py
index be01aca217..d2921e70c3 100644
--- a/tests/acceptance/reverse_debugging.py
+++ b/tests/acceptance/reverse_debugging.py
@@ -207,4 +207,4 @@ class ReverseDebugging_AArch64(ReverseDebugging):
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
self.reverse_debugging(
- args=('-kernel', kernel_path, '-cpu', 'cortex-a53'))
+ args=('-kernel', kernel_path))
diff --git a/tests/acceptance/smmu.py b/tests/acceptance/smmu.py
new file mode 100644
index 0000000000..b3c4de6bf4
--- /dev/null
+++ b/tests/acceptance/smmu.py
@@ -0,0 +1,137 @@
+# SMMUv3 Functional tests
+#
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# Author:
+# Eric Auger <eric.auger@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+import os
+
+from avocado import skipIf
+from avocado_qemu import LinuxTest, BUILD_DIR
+
+@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
+class SMMU(LinuxTest):
+ """
+ :avocado: tags=accel:kvm
+ :avocado: tags=cpu:host
+ :avocado: tags=arch:aarch64
+ :avocado: tags=machine:virt
+ :avocado: tags=distro:fedora
+ :avocado: tags=smmu
+ """
+
+ IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on'
+ kernel_path = None
+ initrd_path = None
+ kernel_params = None
+
+ def set_up_boot(self):
+ path = self.download_boot()
+ self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,scsi=off,' +
+ 'drive=drv0,id=virtio-disk0,bootindex=1,'
+ 'werror=stop,rerror=stop' + self.IOMMU_ADDON)
+ self.vm.add_args('-drive',
+ 'file=%s,if=none,cache=writethrough,id=drv0' % path)
+
+ def setUp(self):
+ super(SMMU, self).setUp(None, 'virtio-net-pci' + self.IOMMU_ADDON)
+
+ def common_vm_setup(self, custom_kernel=False):
+ self.require_accelerator("kvm")
+ self.vm.add_args("-accel", "kvm")
+ self.vm.add_args("-cpu", "host")
+ self.vm.add_args("-machine", "iommu=smmuv3")
+ self.vm.add_args("-d", "guest_errors")
+ self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios',
+ 'edk2-aarch64-code.fd'))
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
+ self.vm.add_args('-object',
+ 'rng-random,id=rng0,filename=/dev/urandom')
+
+ if custom_kernel is False:
+ return
+
+ kernel_url = self.distro.pxeboot_url + 'vmlinuz'
+ initrd_url = self.distro.pxeboot_url + 'initrd.img'
+ self.kernel_path = self.fetch_asset(kernel_url)
+ self.initrd_path = self.fetch_asset(initrd_url)
+
+ def run_and_check(self):
+ if self.kernel_path:
+ self.vm.add_args('-kernel', self.kernel_path,
+ '-append', self.kernel_params,
+ '-initrd', self.initrd_path)
+ self.launch_and_wait()
+ self.ssh_command('cat /proc/cmdline')
+ self.ssh_command('dnf -y install numactl-devel')
+
+
+ # 5.3 kernel without RIL #
+
+ def test_smmu_noril(self):
+ """
+ :avocado: tags=smmu_noril
+ :avocado: tags=smmu_noril_tests
+ :avocado: tags=distro_version:31
+ """
+ self.common_vm_setup()
+ self.run_and_check()
+
+ def test_smmu_noril_passthrough(self):
+ """
+ :avocado: tags=smmu_noril_passthrough
+ :avocado: tags=smmu_noril_tests
+ :avocado: tags=distro_version:31
+ """
+ self.common_vm_setup(True)
+ self.kernel_params = (self.distro.default_kernel_params +
+ ' iommu.passthrough=on')
+ self.run_and_check()
+
+ def test_smmu_noril_nostrict(self):
+ """
+ :avocado: tags=smmu_noril_nostrict
+ :avocado: tags=smmu_noril_tests
+ :avocado: tags=distro_version:31
+ """
+ self.common_vm_setup(True)
+ self.kernel_params = (self.distro.default_kernel_params +
+ ' iommu.strict=0')
+ self.run_and_check()
+
+ # 5.8 kernel featuring range invalidation
+ # >= v5.7 kernel
+
+ def test_smmu_ril(self):
+ """
+ :avocado: tags=smmu_ril
+ :avocado: tags=smmu_ril_tests
+ :avocado: tags=distro_version:33
+ """
+ self.common_vm_setup()
+ self.run_and_check()
+
+ def test_smmu_ril_passthrough(self):
+ """
+ :avocado: tags=smmu_ril_passthrough
+ :avocado: tags=smmu_ril_tests
+ :avocado: tags=distro_version:33
+ """
+ self.common_vm_setup(True)
+ self.kernel_params = (self.distro.default_kernel_params +
+ ' iommu.passthrough=on')
+ self.run_and_check()
+
+ def test_smmu_ril_nostrict(self):
+ """
+ :avocado: tags=smmu_ril_nostrict
+ :avocado: tags=smmu_ril_tests
+ :avocado: tags=distro_version:33
+ """
+ self.common_vm_setup(True)
+ self.kernel_params = (self.distro.default_kernel_params +
+ ' iommu.strict=0')
+ self.run_and_check()
diff --git a/tests/acceptance/tcg_plugins.py b/tests/acceptance/tcg_plugins.py
index c21bf9e52a..9ca1515c3b 100644
--- a/tests/acceptance/tcg_plugins.py
+++ b/tests/acceptance/tcg_plugins.py
@@ -25,7 +25,7 @@ class PluginKernelBase(LinuxKernelTest):
KERNEL_COMMON_COMMAND_LINE = 'printk.time=1 panic=-1 '
def run_vm(self, kernel_path, kernel_command_line,
- plugin, plugin_log, console_pattern, args):
+ plugin, plugin_log, console_pattern, args=None):
vm = self.get_vm()
vm.set_console()
@@ -68,7 +68,7 @@ class PluginKernelNormal(PluginKernelBase):
:avocado: tags=accel:tcg
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
- :avocado: tags=cpu:cortex-a57
+ :avocado: tags=cpu:cortex-a53
"""
kernel_path = self._grab_aarch64_kernel()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
@@ -80,8 +80,7 @@ class PluginKernelNormal(PluginKernelBase):
self.run_vm(kernel_path, kernel_command_line,
"tests/plugin/libinsn.so", plugin_log.name,
- console_pattern,
- args=('-cpu', 'cortex-a53'))
+ console_pattern)
with plugin_log as lf, \
mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s:
@@ -95,7 +94,7 @@ class PluginKernelNormal(PluginKernelBase):
:avocado: tags=accel:tcg
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
- :avocado: tags=cpu:cortex-a57
+ :avocado: tags=cpu:cortex-a53
"""
kernel_path = self._grab_aarch64_kernel()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
@@ -108,7 +107,7 @@ class PluginKernelNormal(PluginKernelBase):
self.run_vm(kernel_path, kernel_command_line,
"tests/plugin/libinsn.so", plugin_log.name,
console_pattern,
- args=('-cpu', 'cortex-a53', '-icount', 'shift=1'))
+ args=('-icount', 'shift=1'))
with plugin_log as lf, \
mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s:
@@ -121,7 +120,7 @@ class PluginKernelNormal(PluginKernelBase):
:avocado: tags=accel:tcg
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
- :avocado: tags=cpu:cortex-a57
+ :avocado: tags=cpu:cortex-a53
"""
kernel_path = self._grab_aarch64_kernel()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
@@ -134,7 +133,7 @@ class PluginKernelNormal(PluginKernelBase):
self.run_vm(kernel_path, kernel_command_line,
"tests/plugin/libmem.so,arg=both", plugin_log.name,
console_pattern,
- args=('-cpu', 'cortex-a53', '-icount', 'shift=1'))
+ args=('-icount', 'shift=1'))
with plugin_log as lf, \
mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s:
diff --git a/tests/acceptance/virtio-gpu.py b/tests/acceptance/virtio-gpu.py
index e7979343e9..589332c1b7 100644
--- a/tests/acceptance/virtio-gpu.py
+++ b/tests/acceptance/virtio-gpu.py
@@ -60,6 +60,7 @@ class VirtioGPUx86(Test):
"""
:avocado: tags=arch:x86_64
:avocado: tags=device:virtio-vga
+ :avocado: tags=cpu:host
"""
kernel_command_line = (
self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash"
@@ -72,7 +73,6 @@ class VirtioGPUx86(Test):
initrd_path = self.fetch_asset(self.INITRD_URL)
self.vm.set_console()
- self.vm.add_args("-cpu", "host")
self.vm.add_args("-m", "2G")
self.vm.add_args("-machine", "pc,accel=kvm")
self.vm.add_args("-device", "virtio-vga,virgl=on")
@@ -101,6 +101,7 @@ class VirtioGPUx86(Test):
"""
:avocado: tags=arch:x86_64
:avocado: tags=device:vhost-user-vga
+ :avocado: tags=cpu:host
"""
kernel_command_line = (
self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash"
@@ -140,7 +141,6 @@ class VirtioGPUx86(Test):
)
self.vm.set_console()
- self.vm.add_args("-cpu", "host")
self.vm.add_args("-m", "2G")
self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G")
self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm")
diff --git a/tests/acceptance/x86_cpu_model_versions.py b/tests/acceptance/x86_cpu_model_versions.py
index 77ed8597a4..0e9feda62d 100644
--- a/tests/acceptance/x86_cpu_model_versions.py
+++ b/tests/acceptance/x86_cpu_model_versions.py
@@ -252,10 +252,13 @@ class CascadelakeArchCapabilities(avocado_qemu.Test):
def test_4_1(self):
"""
:avocado: tags=machine:pc-i440fx-4.1
+ :avocado: tags=cpu:Cascadelake-Server
"""
# machine-type only:
self.vm.add_args('-S')
- self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off')
+ self.set_vm_arg('-cpu',
+ 'Cascadelake-Server,x-force-features=on,check=off,'
+ 'enforce=off')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')
@@ -263,9 +266,12 @@ class CascadelakeArchCapabilities(avocado_qemu.Test):
def test_4_0(self):
"""
:avocado: tags=machine:pc-i440fx-4.0
+ :avocado: tags=cpu:Cascadelake-Server
"""
self.vm.add_args('-S')
- self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off')
+ self.set_vm_arg('-cpu',
+ 'Cascadelake-Server,x-force-features=on,check=off,'
+ 'enforce=off')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')
@@ -273,10 +279,13 @@ class CascadelakeArchCapabilities(avocado_qemu.Test):
def test_set_4_0(self):
"""
:avocado: tags=machine:pc-i440fx-4.0
+ :avocado: tags=cpu:Cascadelake-Server
"""
# command line must override machine-type if CPU model is not versioned:
self.vm.add_args('-S')
- self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off,+arch-capabilities')
+ self.set_vm_arg('-cpu',
+ 'Cascadelake-Server,x-force-features=on,check=off,'
+ 'enforce=off,+arch-capabilities')
self.vm.launch()
self.assertTrue(self.get_cpu_prop('arch-capabilities'),
'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')
@@ -284,9 +293,12 @@ class CascadelakeArchCapabilities(avocado_qemu.Test):
def test_unset_4_1(self):
"""
:avocado: tags=machine:pc-i440fx-4.1
+ :avocado: tags=cpu:Cascadelake-Server
"""
self.vm.add_args('-S')
- self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off,-arch-capabilities')
+ self.set_vm_arg('-cpu',
+ 'Cascadelake-Server,x-force-features=on,check=off,'
+ 'enforce=off,-arch-capabilities')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
@@ -294,10 +306,13 @@ class CascadelakeArchCapabilities(avocado_qemu.Test):
def test_v1_4_0(self):
"""
:avocado: tags=machine:pc-i440fx-4.0
+ :avocado: tags=cpu:Cascadelake-Server
"""
# versioned CPU model overrides machine-type:
self.vm.add_args('-S')
- self.vm.add_args('-cpu', 'Cascadelake-Server-v1,x-force-features=on,check=off,enforce=off')
+ self.set_vm_arg('-cpu',
+ 'Cascadelake-Server-v1,x-force-features=on,check=off,'
+ 'enforce=off')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')
@@ -305,9 +320,12 @@ class CascadelakeArchCapabilities(avocado_qemu.Test):
def test_v2_4_0(self):
"""
:avocado: tags=machine:pc-i440fx-4.0
+ :avocado: tags=cpu:Cascadelake-Server
"""
self.vm.add_args('-S')
- self.vm.add_args('-cpu', 'Cascadelake-Server-v2,x-force-features=on,check=off,enforce=off')
+ self.set_vm_arg('-cpu',
+ 'Cascadelake-Server-v2,x-force-features=on,check=off,'
+ 'enforce=off')
self.vm.launch()
self.assertTrue(self.get_cpu_prop('arch-capabilities'),
'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')
@@ -315,10 +333,13 @@ class CascadelakeArchCapabilities(avocado_qemu.Test):
def test_v1_set_4_0(self):
"""
:avocado: tags=machine:pc-i440fx-4.0
+ :avocado: tags=cpu:Cascadelake-Server
"""
# command line must override machine-type and versioned CPU model:
self.vm.add_args('-S')
- self.vm.add_args('-cpu', 'Cascadelake-Server-v1,x-force-features=on,check=off,enforce=off,+arch-capabilities')
+ self.set_vm_arg('-cpu',
+ 'Cascadelake-Server-v1,x-force-features=on,check=off,'
+ 'enforce=off,+arch-capabilities')
self.vm.launch()
self.assertTrue(self.get_cpu_prop('arch-capabilities'),
'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')
@@ -326,9 +347,12 @@ class CascadelakeArchCapabilities(avocado_qemu.Test):
def test_v2_unset_4_1(self):
"""
:avocado: tags=machine:pc-i440fx-4.1
+ :avocado: tags=cpu:Cascadelake-Server
"""
self.vm.add_args('-S')
- self.vm.add_args('-cpu', 'Cascadelake-Server-v2,x-force-features=on,check=off,enforce=off,-arch-capabilities')
+ self.set_vm_arg('-cpu',
+ 'Cascadelake-Server-v2,x-force-features=on,check=off,'
+ 'enforce=off,-arch-capabilities')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')