diff options
-rw-r--r-- | .gitlab-ci.d/buildtest-template.yml | 4 | ||||
-rw-r--r-- | .gitlab-ci.d/buildtest.yml | 18 | ||||
-rw-r--r-- | .gitlab-ci.d/custom-runners.yml | 40 | ||||
-rw-r--r-- | .gitlab-ci.d/edk2.yml | 6 | ||||
-rw-r--r-- | .gitlab-ci.d/opensbi.yml | 8 | ||||
-rw-r--r-- | .gitlab-ci.yml | 19 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | accel/kvm/kvm-all.c | 6 | ||||
-rwxr-xr-x | configure | 7 | ||||
-rw-r--r-- | docs/devel/ci.rst | 40 | ||||
-rw-r--r-- | hw/i2c/smbus_eeprom.c | 2 | ||||
-rw-r--r-- | hw/ppc/pegasos2.c | 2 | ||||
-rw-r--r-- | hw/ppc/trace-events | 4 | ||||
-rw-r--r-- | hw/ppc/vof.c | 139 | ||||
-rw-r--r-- | include/hw/ppc/vof.h | 2 | ||||
-rw-r--r-- | softmmu/vl.c | 2 | ||||
l--------- | subprojects/libvhost-user/include/atomic.h | 1 | ||||
-rw-r--r-- | subprojects/libvhost-user/libvhost-user.c | 10 | ||||
-rw-r--r-- | subprojects/libvhost-user/meson.build | 6 | ||||
l--------- | subprojects/libvhost-user/standard-headers/linux | 1 | ||||
-rw-r--r-- | target/i386/kvm/kvm.c | 14 | ||||
-rw-r--r-- | target/i386/tcg/sysemu/svm_helper.c | 8 | ||||
-rw-r--r-- | target/ppc/translate/fixedpoint-impl.c.inc | 58 | ||||
-rw-r--r-- | tests/qtest/migration-test.c | 5 |
24 files changed, 278 insertions, 132 deletions
diff --git a/.gitlab-ci.d/buildtest-template.yml b/.gitlab-ci.d/buildtest-template.yml index 3e3e19d96b..fcbcc4e627 100644 --- a/.gitlab-ci.d/buildtest-template.yml +++ b/.gitlab-ci.d/buildtest-template.yml @@ -73,9 +73,9 @@ # in its namespace setting or via git-push option, see documentation # in /.gitlab-ci.yml of this repository). - if: '$CI_PROJECT_NAMESPACE == "qemu-project"' - when: always + when: on_success - if: '$QEMU_CI_AVOCADO_TESTING' - when: always + when: on_success # Otherwise, set to manual (the jobs are created but not run). - when: manual allow_failure: true diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml index ee0c83b600..903ee65f32 100644 --- a/.gitlab-ci.d/buildtest.yml +++ b/.gitlab-ci.d/buildtest.yml @@ -305,10 +305,10 @@ build-tcg-disabled: - cd tests/qemu-iotests/ - ./check -raw 001 002 003 004 005 008 009 010 011 012 021 025 032 033 048 052 063 077 086 101 104 106 113 148 150 151 152 157 159 160 163 - 170 171 183 184 192 194 197 208 215 221 222 226 227 236 253 277 + 170 171 183 184 192 194 208 221 222 226 227 236 253 277 - ./check -qcow2 028 051 056 057 058 065 068 082 085 091 095 096 102 122 - 124 132 139 142 144 145 151 152 155 157 165 194 196 197 200 202 - 208 209 215 216 218 222 227 234 246 247 248 250 254 255 257 258 + 124 132 139 142 144 145 151 152 155 157 165 194 196 200 202 + 208 209 216 218 222 227 234 246 247 248 250 254 255 257 258 260 261 262 263 264 270 272 273 277 279 build-user: @@ -416,6 +416,12 @@ build-cfi-aarch64: expire_in: 2 days paths: - build + rules: + # FIXME: This job is often failing, likely due to out-of-memory problems in + # the constrained containers of the shared runners. Thus this is marked as + # manual until the situation has been solved. + - when: manual + allow_failure: true check-cfi-aarch64: extends: .native_test_job_template @@ -452,6 +458,12 @@ build-cfi-ppc64-s390x: expire_in: 2 days paths: - build + rules: + # FIXME: This job is often failing, likely due to out-of-memory problems in + # the constrained containers of the shared runners. Thus this is marked as + # manual until the situation has been solved. + - when: manual + allow_failure: true check-cfi-ppc64-s390x: extends: .native_test_job_template diff --git a/.gitlab-ci.d/custom-runners.yml b/.gitlab-ci.d/custom-runners.yml index 061d3cdfed..564b94565d 100644 --- a/.gitlab-ci.d/custom-runners.yml +++ b/.gitlab-ci.d/custom-runners.yml @@ -24,7 +24,8 @@ ubuntu-18.04-s390x-all-linux-static: - ubuntu_18.04 - s390x rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$S390X_RUNNER_AVAILABLE" script: # --disable-libssh is needed because of https://bugs.launchpad.net/qemu/+bug/1838763 # --disable-glusterfs is needed because there's no static version of those libs in distro supplied packages @@ -43,7 +44,8 @@ ubuntu-18.04-s390x-all: - ubuntu_18.04 - s390x rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$S390X_RUNNER_AVAILABLE" script: - mkdir build - cd build @@ -59,7 +61,8 @@ ubuntu-18.04-s390x-alldbg: - ubuntu_18.04 - s390x rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$S390X_RUNNER_AVAILABLE" script: - mkdir build - cd build @@ -76,7 +79,9 @@ ubuntu-18.04-s390x-clang: - ubuntu_18.04 - s390x rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + - if: "$S390X_RUNNER_AVAILABLE" when: manual script: - mkdir build @@ -93,7 +98,8 @@ ubuntu-18.04-s390x-tci: - ubuntu_18.04 - s390x rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$S390X_RUNNER_AVAILABLE" script: - mkdir build - cd build @@ -108,7 +114,9 @@ ubuntu-18.04-s390x-notcg: - ubuntu_18.04 - s390x rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + - if: "$S390X_RUNNER_AVAILABLE" when: manual script: - mkdir build @@ -128,7 +136,8 @@ ubuntu-20.04-aarch64-all-linux-static: - ubuntu_20.04 - aarch64 rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$S390X_RUNNER_AVAILABLE" script: # --disable-libssh is needed because of https://bugs.launchpad.net/qemu/+bug/1838763 # --disable-glusterfs is needed because there's no static version of those libs in distro supplied packages @@ -147,7 +156,8 @@ ubuntu-20.04-aarch64-all: - ubuntu_20.04 - aarch64 rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$S390X_RUNNER_AVAILABLE" script: - mkdir build - cd build @@ -163,7 +173,8 @@ ubuntu-20.04-aarch64-alldbg: - ubuntu_20.04 - aarch64 rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$S390X_RUNNER_AVAILABLE" script: - mkdir build - cd build @@ -180,7 +191,9 @@ ubuntu-20.04-aarch64-clang: - ubuntu_20.04 - aarch64 rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + - if: "$S390X_RUNNER_AVAILABLE" when: manual script: - mkdir build @@ -197,7 +210,8 @@ ubuntu-20.04-aarch64-tci: - ubuntu_20.04 - aarch64 rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$S390X_RUNNER_AVAILABLE" script: - mkdir build - cd build @@ -212,7 +226,9 @@ ubuntu-20.04-aarch64-notcg: - ubuntu_20.04 - aarch64 rules: - - if: '$CI_COMMIT_BRANCH =~ /^staging/' + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + - if: "$S390X_RUNNER_AVAILABLE" when: manual script: - mkdir build diff --git a/.gitlab-ci.d/edk2.yml b/.gitlab-ci.d/edk2.yml index aae2f7ad88..62497ba47f 100644 --- a/.gitlab-ci.d/edk2.yml +++ b/.gitlab-ci.d/edk2.yml @@ -8,11 +8,11 @@ - .gitlab-ci.d/edk2/Dockerfile # or roms/edk2/ is modified (submodule updated) - roms/edk2/* - when: always + when: on_success - if: '$CI_COMMIT_REF_NAME =~ /^edk2/' # or the branch/tag starts with 'edk2' - when: always + when: on_success - if: '$CI_COMMIT_MESSAGE =~ /edk2/i' # or last commit description contains 'EDK2' - when: always + when: on_success docker-edk2: extends: .edk2_job_rules diff --git a/.gitlab-ci.d/opensbi.yml b/.gitlab-ci.d/opensbi.yml index d8a0456679..5e0a2477c5 100644 --- a/.gitlab-ci.d/opensbi.yml +++ b/.gitlab-ci.d/opensbi.yml @@ -6,14 +6,14 @@ - .gitlab-ci.d/opensbi.yml # or the Dockerfile is modified - .gitlab-ci.d/opensbi/Dockerfile - when: always + when: on_success - changes: # or roms/opensbi/ is modified (submodule updated) - roms/opensbi/* - when: always + when: on_success - if: '$CI_COMMIT_REF_NAME =~ /^opensbi/' # or the branch/tag starts with 'opensbi' - when: always + when: on_success - if: '$CI_COMMIT_MESSAGE =~ /opensbi/i' # or last commit description contains 'OpenSBI' - when: always + when: on_success docker-opensbi: extends: .opensbi_job_rules diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6dc5385e69..9762dda2ee 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,24 +16,9 @@ # QEMU CI jobs are based on templates. Some templates provide # user-configurable options, modifiable via configuration variables. # -# These variables can be set globally in the user's CI namespace -# setting: -# https://docs.gitlab.com/ee/ci/variables/#create-a-custom-variable-in-the-ui -# or set manually each time a branch/tag is pushed, as a git-push -# command line argument: -# https://docs.gitlab.com/ee/user/project/push_options.html#push-options-for-gitlab-cicd +# See https://qemu-project.gitlab.io/qemu/devel/ci.html#custom-ci-cd-variables +# for more information. # -# Example setting the QEMU_CI_EXAMPLE_VAR variable: -# -# git push -o ci.variable="QEMU_CI_EXAMPLE_VAR=value" myrepo mybranch -# -# ---------------------------------------------------------------------- -# -# List of environment variables that can be use to modify the set -# of jobs selected: -# -# - QEMU_CI_AVOCADO_TESTING -# If set, tests using the Avocado framework will be run include: - local: '/.gitlab-ci.d/qemu-project.yml' @@ -129,9 +129,11 @@ endif # 4. Rules to bridge to other makefiles ifneq ($(NINJA),) -MAKE.n = $(findstring n,$(firstword $(MAKEFLAGS))) -MAKE.k = $(findstring k,$(firstword $(MAKEFLAGS))) -MAKE.q = $(findstring q,$(firstword $(MAKEFLAGS))) +# Filter out long options to avoid flags like --no-print-directory which +# may result in false positive match for MAKE.n +MAKE.n = $(findstring n,$(firstword $(filter-out --%,$(MAKEFLAGS)))) +MAKE.k = $(findstring k,$(firstword $(filter-out --%,$(MAKEFLAGS)))) +MAKE.q = $(findstring q,$(firstword $(filter-out --%,$(MAKEFLAGS)))) MAKE.nq = $(if $(word 2, $(MAKE.n) $(MAKE.q)),nq) NINJAFLAGS = $(if $V,-v) $(if $(MAKE.n), -n) $(if $(MAKE.k), -k0) \ $(filter-out -j, $(lastword -j1 $(filter -l% -j%, $(MAKEFLAGS)))) \ diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index e5b10dd129..0125c17edb 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2397,6 +2397,12 @@ static int kvm_init(MachineState *ms) "- for kernels supporting the vm.allocate_pgste sysctl, " "whether it is enabled\n"); } +#elif defined(TARGET_PPC) + if (ret == -EINVAL) { + fprintf(stderr, + "PPC KVM module is not loaded. Try modprobe kvm_%s.\n", + (type == 2) ? "pr" : "hv"); + } #endif goto err; } @@ -770,7 +770,8 @@ SunOS) ;; Haiku) haiku="yes" - QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS -D_BSD_SOURCE $QEMU_CFLAGS" + pie="no" + QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS -D_BSD_SOURCE -fPIC $QEMU_CFLAGS" ;; Linux) audio_drv_list="try-pa oss" @@ -3881,7 +3882,7 @@ static int bar(void *a) { } int main(int argc, char *argv[]) { return bar(argv[0]); } EOF - if compile_object "" ; then + if compile_object "-Werror" ; then avx2_opt="yes" else avx2_opt="no" @@ -3911,7 +3912,7 @@ int main(int argc, char *argv[]) return bar(argv[0]); } EOF - if ! compile_object "" ; then + if ! compile_object "-Werror" ; then avx512f_opt="no" fi else diff --git a/docs/devel/ci.rst b/docs/devel/ci.rst index b3bf3ef615..205572510c 100644 --- a/docs/devel/ci.rst +++ b/docs/devel/ci.rst @@ -8,6 +8,46 @@ found at:: https://wiki.qemu.org/Testing/CI +Custom CI/CD variables +====================== + +QEMU CI pipelines can be tuned by setting some CI environment variables. + +Set variable globally in the user's CI namespace +------------------------------------------------ + +Variables can be set globally in the user's CI namespace setting. + +For further information about how to set these variables, please refer to:: + + https://docs.gitlab.com/ee/ci/variables/#add-a-cicd-variable-to-a-project + +Set variable manually when pushing a branch or tag to the user's repository +--------------------------------------------------------------------------- + +Variables can be set manually when pushing a branch or tag, using +git-push command line arguments. + +Example setting the QEMU_CI_EXAMPLE_VAR variable: + +.. code:: + + git push -o ci.variable="QEMU_CI_EXAMPLE_VAR=value" myrepo mybranch + +For further information about how to set these variables, please refer to:: + + https://docs.gitlab.com/ee/user/project/push_options.html#push-options-for-gitlab-cicd + +Here is a list of the most used variables: + +QEMU_CI_AVOCADO_TESTING +~~~~~~~~~~~~~~~~~~~~~~~ +By default, tests using the Avocado framework are not run automatically in +the pipelines (because multiple artifacts have to be downloaded, and if +these artifacts are not already cached, downloading them make the jobs +reach the timeout limit). Set this variable to have the tests using the +Avocado framework run automatically. + Jobs on Custom Runners ====================== diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c index 4d2bf99207..12c5741f38 100644 --- a/hw/i2c/smbus_eeprom.c +++ b/hw/i2c/smbus_eeprom.c @@ -276,7 +276,7 @@ uint8_t *spd_data_generate(enum sdram_type type, ram_addr_t ram_size) spd[18] = 12; /* ~CAS latencies supported */ spd[19] = (type == DDR2 ? 0 : 1); /* reserved / ~CS latencies supported */ spd[20] = 2; /* DIMM type / ~WE latencies */ - /* module features */ + spd[21] = (type < DDR2 ? 0x20 : 0); /* module features */ /* memory chip features */ spd[23] = 0x12; /* clock cycle time @ medium CAS latency */ /* data access time */ diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 9fad1854b1..b8ce859f1a 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -191,7 +191,7 @@ static void pegasos2_init(MachineState *machine) warn_report("Option -kernel may be ineffective with -bios."); } } - if (machine->kernel_cmdline && !pm->vof) { + if (!pm->vof && machine->kernel_cmdline && machine->kernel_cmdline[0]) { warn_report("Option -append may be ineffective with -bios."); } } diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index 6e90a01072..da6e74b80d 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -88,8 +88,8 @@ vof_getproplen(uint32_t ph, const char *prop, uint32_t ret) "ph=0x%x \"%s\" => l vof_setprop(uint32_t ph, const char *prop, const char *val, uint32_t vallen, uint32_t ret) "ph=0x%x \"%s\" [%s] len=%d => ret=%d" vof_open(const char *path, uint32_t ph, uint32_t ih) "%s ph=0x%x => ih=0x%x" vof_interpret(const char *cmd, uint32_t param1, uint32_t param2, uint32_t ret, uint32_t ret2) "[%s] 0x%x 0x%x => 0x%x 0x%x" -vof_package_to_path(uint32_t ph, const char *tmp, uint32_t ret) "ph=0x%x => %s len=%d" -vof_instance_to_path(uint32_t ih, uint32_t ph, const char *tmp, uint32_t ret) "ih=0x%x ph=0x%x => %s len=%d" +vof_package_to_path(uint32_t ph, const char *tmp, int ret) "ph=0x%x => %s len=%d" +vof_instance_to_path(uint32_t ih, uint32_t ph, const char *tmp, int ret) "ih=0x%x ph=0x%x => %s len=%d" vof_instance_to_package(uint32_t ih, uint32_t ph) "ih=0x%x => ph=0x%x" vof_write(uint32_t ih, unsigned cb, const char *msg) "ih=0x%x [%u] \"%s\"" vof_avail(uint64_t start, uint64_t end, uint64_t size) "0x%"PRIx64"..0x%"PRIx64" size=0x%"PRIx64 diff --git a/hw/ppc/vof.c b/hw/ppc/vof.c index 81f6596215..73adc44ec2 100644 --- a/hw/ppc/vof.c +++ b/hw/ppc/vof.c @@ -160,7 +160,7 @@ static int path_offset(const void *fdt, const char *path) static uint32_t vof_finddevice(const void *fdt, uint32_t nodeaddr) { char fullnode[VOF_MAX_PATH]; - uint32_t ret = -1; + uint32_t ret = PROM_ERROR; int offset; if (readstr(nodeaddr, fullnode, sizeof(fullnode))) { @@ -172,7 +172,7 @@ static uint32_t vof_finddevice(const void *fdt, uint32_t nodeaddr) ret = fdt_get_phandle(fdt, offset); } trace_vof_finddevice(fullnode, ret); - return (uint32_t) ret; + return ret; } static const void *getprop(const void *fdt, int nodeoff, const char *propname, @@ -229,10 +229,10 @@ static uint32_t vof_getprop(const void *fdt, uint32_t nodeph, uint32_t pname, bool write0; if (nodeoff < 0) { - return -1; + return PROM_ERROR; } if (readstr(pname, propname, sizeof(propname))) { - return -1; + return PROM_ERROR; } prop = getprop(fdt, nodeoff, propname, &proplen, &write0); if (prop) { @@ -244,7 +244,7 @@ static uint32_t vof_getprop(const void *fdt, uint32_t nodeph, uint32_t pname, (write0 && cb == proplen && VOF_MEM_WRITE(valaddr + cb - 1, &zero, 1) != MEMTX_OK)) { - ret = -1; + ret = PROM_ERROR; } else { /* * OF1275 says: @@ -259,7 +259,7 @@ static uint32_t vof_getprop(const void *fdt, uint32_t nodeph, uint32_t pname, } } } else { - ret = -1; + ret = PROM_ERROR; } trace_vof_getprop(nodeph, propname, ret, trval); @@ -275,16 +275,16 @@ static uint32_t vof_getproplen(const void *fdt, uint32_t nodeph, uint32_t pname) int nodeoff = fdt_node_offset_by_phandle(fdt, nodeph); if (nodeoff < 0) { - return -1; + return PROM_ERROR; } if (readstr(pname, propname, sizeof(propname))) { - return -1; + return PROM_ERROR; } prop = getprop(fdt, nodeoff, propname, &proplen, NULL); if (prop) { ret = proplen; } else { - ret = -1; + ret = PROM_ERROR; } trace_vof_getproplen(nodeph, propname, ret); @@ -296,8 +296,8 @@ static uint32_t vof_setprop(MachineState *ms, void *fdt, Vof *vof, uint32_t valaddr, uint32_t vallen) { char propname[OF_PROPNAME_LEN_MAX + 1]; - uint32_t ret = -1; - int offset; + uint32_t ret = PROM_ERROR; + int offset, rc; char trval[64] = ""; char nodepath[VOF_MAX_PATH] = ""; Object *vmo = object_dynamic_cast(OBJECT(ms), TYPE_VOF_MACHINE_IF); @@ -314,8 +314,8 @@ static uint32_t vof_setprop(MachineState *ms, void *fdt, Vof *vof, if (offset < 0) { goto trace_exit; } - ret = get_path(fdt, offset, nodepath, sizeof(nodepath)); - if (ret <= 0) { + rc = get_path(fdt, offset, nodepath, sizeof(nodepath)); + if (rc <= 0) { goto trace_exit; } @@ -333,8 +333,8 @@ static uint32_t vof_setprop(MachineState *ms, void *fdt, Vof *vof, goto trace_exit; } - ret = fdt_setprop(fdt, offset, propname, val, vallen); - if (ret) { + rc = fdt_setprop(fdt, offset, propname, val, vallen); + if (rc) { goto trace_exit; } @@ -358,7 +358,7 @@ static uint32_t vof_nextprop(const void *fdt, uint32_t phandle, const char *tmp; if (readstr(prevaddr, prev, sizeof(prev))) { - return -1; + return PROM_ERROR; } fdt_for_each_property_offset(offset, fdt, nodeoff) { @@ -377,7 +377,7 @@ static uint32_t vof_nextprop(const void *fdt, uint32_t phandle, } if (VOF_MEM_WRITE(nameaddr, tmp, strlen(tmp) + 1) != MEMTX_OK) { - return -1; + return PROM_ERROR; } return 1; } @@ -388,18 +388,17 @@ static uint32_t vof_nextprop(const void *fdt, uint32_t phandle, static uint32_t vof_peer(const void *fdt, uint32_t phandle) { - int ret; + uint32_t ret = 0; + int rc; if (phandle == 0) { - ret = fdt_path_offset(fdt, "/"); + rc = fdt_path_offset(fdt, "/"); } else { - ret = fdt_next_subnode(fdt, fdt_node_offset_by_phandle(fdt, phandle)); + rc = fdt_next_subnode(fdt, fdt_node_offset_by_phandle(fdt, phandle)); } - if (ret < 0) { - ret = 0; - } else { - ret = fdt_get_phandle(fdt, ret); + if (rc >= 0) { + ret = fdt_get_phandle(fdt, rc); } return ret; @@ -407,12 +406,11 @@ static uint32_t vof_peer(const void *fdt, uint32_t phandle) static uint32_t vof_child(const void *fdt, uint32_t phandle) { - int ret = fdt_first_subnode(fdt, fdt_node_offset_by_phandle(fdt, phandle)); + uint32_t ret = 0; + int rc = fdt_first_subnode(fdt, fdt_node_offset_by_phandle(fdt, phandle)); - if (ret < 0) { - ret = 0; - } else { - ret = fdt_get_phandle(fdt, ret); + if (rc >= 0) { + ret = fdt_get_phandle(fdt, rc); } return ret; @@ -420,12 +418,11 @@ static uint32_t vof_child(const void *fdt, uint32_t phandle) static uint32_t vof_parent(const void *fdt, uint32_t phandle) { - int ret = fdt_parent_offset(fdt, fdt_node_offset_by_phandle(fdt, phandle)); + uint32_t ret = 0; + int rc = fdt_parent_offset(fdt, fdt_node_offset_by_phandle(fdt, phandle)); - if (ret < 0) { - ret = 0; - } else { - ret = fdt_get_phandle(fdt, ret); + if (rc >= 0) { + ret = fdt_get_phandle(fdt, rc); } return ret; @@ -433,7 +430,7 @@ static uint32_t vof_parent(const void *fdt, uint32_t phandle) static uint32_t vof_do_open(void *fdt, Vof *vof, int offset, const char *path) { - uint32_t ret = -1; + uint32_t ret = PROM_ERROR; OfInstance *inst = NULL; if (vof->of_instance_last == 0xFFFFFFFF) { @@ -461,18 +458,18 @@ trace_exit: uint32_t vof_client_open_store(void *fdt, Vof *vof, const char *nodename, const char *prop, const char *path) { - int node = fdt_path_offset(fdt, nodename); - int inst, offset; + int offset, node = fdt_path_offset(fdt, nodename); + uint32_t inst; offset = fdt_path_offset(fdt, path); if (offset < 0) { trace_vof_error_unknown_path(path); - return offset; + return PROM_ERROR; } inst = vof_do_open(fdt, vof, offset, path); - return fdt_setprop_cell(fdt, node, prop, inst); + return fdt_setprop_cell(fdt, node, prop, inst) >= 0 ? 0 : PROM_ERROR; } static uint32_t vof_open(void *fdt, Vof *vof, uint32_t pathaddr) @@ -481,13 +478,13 @@ static uint32_t vof_open(void *fdt, Vof *vof, uint32_t pathaddr) int offset; if (readstr(pathaddr, path, sizeof(path))) { - return -1; + return PROM_ERROR; } offset = path_offset(fdt, path); if (offset < 0) { trace_vof_error_unknown_path(path); - return offset; + return PROM_ERROR; } return vof_do_open(fdt, vof, offset, path); @@ -504,7 +501,7 @@ static uint32_t vof_instance_to_package(Vof *vof, uint32_t ihandle) { gpointer instp = g_hash_table_lookup(vof->of_instances, GINT_TO_POINTER(ihandle)); - uint32_t ret = -1; + uint32_t ret = PROM_ERROR; if (instp) { ret = ((OfInstance *)instp)->phandle; @@ -517,39 +514,39 @@ static uint32_t vof_instance_to_package(Vof *vof, uint32_t ihandle) static uint32_t vof_package_to_path(const void *fdt, uint32_t phandle, uint32_t buf, uint32_t len) { - uint32_t ret = -1; + int rc; char tmp[VOF_MAX_PATH] = ""; - ret = phandle_to_path(fdt, phandle, tmp, sizeof(tmp)); - if (ret > 0) { - if (VOF_MEM_WRITE(buf, tmp, ret) != MEMTX_OK) { - ret = -1; + rc = phandle_to_path(fdt, phandle, tmp, sizeof(tmp)); + if (rc > 0) { + if (VOF_MEM_WRITE(buf, tmp, rc) != MEMTX_OK) { + rc = -1; } } - trace_vof_package_to_path(phandle, tmp, ret); + trace_vof_package_to_path(phandle, tmp, rc); - return ret; + return rc > 0 ? (uint32_t)rc : PROM_ERROR; } static uint32_t vof_instance_to_path(void *fdt, Vof *vof, uint32_t ihandle, uint32_t buf, uint32_t len) { - uint32_t ret = -1; + int rc = -1; uint32_t phandle = vof_instance_to_package(vof, ihandle); char tmp[VOF_MAX_PATH] = ""; if (phandle != -1) { - ret = phandle_to_path(fdt, phandle, tmp, sizeof(tmp)); - if (ret > 0) { - if (VOF_MEM_WRITE(buf, tmp, ret) != MEMTX_OK) { - ret = -1; + rc = phandle_to_path(fdt, phandle, tmp, sizeof(tmp)); + if (rc > 0) { + if (VOF_MEM_WRITE(buf, tmp, rc) != MEMTX_OK) { + rc = -1; } } } - trace_vof_instance_to_path(ihandle, phandle, tmp, ret); + trace_vof_instance_to_path(ihandle, phandle, tmp, rc); - return ret; + return rc > 0 ? (uint32_t)rc : PROM_ERROR; } static uint32_t vof_write(Vof *vof, uint32_t ihandle, uint32_t buf, @@ -562,13 +559,13 @@ static uint32_t vof_write(Vof *vof, uint32_t ihandle, uint32_t buf, if (!inst) { trace_vof_error_write(ihandle); - return -1; + return PROM_ERROR; } for ( ; len > 0; len -= cb) { cb = MIN(len, sizeof(tmp) - 1); if (VOF_MEM_READ(buf, tmp, cb) != MEMTX_OK) { - return -1; + return PROM_ERROR; } /* FIXME: there is no backend(s) yet so just call a trace */ @@ -747,7 +744,7 @@ uint64_t vof_claim(Vof *vof, uint64_t virt, uint64_t size, static uint32_t vof_release(Vof *vof, uint64_t virt, uint64_t size) { - uint32_t ret = -1; + uint32_t ret = PROM_ERROR; int i; GArray *claimed = vof->claimed; OfClaimed c; @@ -776,7 +773,7 @@ static uint32_t vof_call_method(MachineState *ms, Vof *vof, uint32_t methodaddr, uint32_t param2, uint32_t param3, uint32_t param4, uint32_t *ret2) { - uint32_t ret = -1; + uint32_t ret = PROM_ERROR; char method[VOF_MAX_METHODLEN] = ""; OfInstance *inst; @@ -802,7 +799,8 @@ static uint32_t vof_call_method(MachineState *ms, Vof *vof, uint32_t methodaddr, VofMachineIfClass *vmc = VOF_MACHINE_GET_CLASS(vmo); g_assert(vmc->client_architecture_support); - ret = vmc->client_architecture_support(ms, first_cpu, param1); + ret = (uint32_t)vmc->client_architecture_support(ms, first_cpu, + param1); } *ret2 = 0; @@ -826,7 +824,7 @@ trace_exit: static uint32_t vof_call_interpret(uint32_t cmdaddr, uint32_t param1, uint32_t param2, uint32_t *ret2) { - uint32_t ret = -1; + uint32_t ret = PROM_ERROR; char cmd[VOF_MAX_FORTHCODE] = ""; /* No interpret implemented so just call a trace */ @@ -895,13 +893,20 @@ static uint32_t vof_client_handle(MachineState *ms, void *fdt, Vof *vof, } else if (cmpserv("write", 3, 1)) { ret = vof_write(vof, args[0], args[1], args[2]); } else if (cmpserv("claim", 3, 1)) { - ret = vof_claim(vof, args[0], args[1], args[2]); - if (ret != -1) { + uint64_t ret64 = vof_claim(vof, args[0], args[1], args[2]); + + if (ret64 < 0x100000000UL) { vof_dt_memory_available(fdt, vof->claimed, vof->claimed_base); + ret = (uint32_t)ret64; + } else { + if (ret64 != -1) { + vof_release(vof, ret, args[1]); + } + ret = PROM_ERROR; } } else if (cmpserv("release", 2, 0)) { ret = vof_release(vof, args[0], args[1]); - if (ret != -1) { + if (ret != PROM_ERROR) { vof_dt_memory_available(fdt, vof->claimed, vof->claimed_base); } } else if (cmpserv("call-method", 0, 0)) { @@ -965,11 +970,15 @@ int vof_client_call(MachineState *ms, Vof *vof, void *fdt, } nret = be32_to_cpu(args_be.nret); + if (nret > ARRAY_SIZE(args_be.args) - nargs) { + return -EINVAL; + } ret = vof_client_handle(ms, fdt, vof, service, args, nargs, rets, nret); if (!nret) { return 0; } + /* @nrets includes the value which this function returns */ args_be.args[nargs] = cpu_to_be32(ret); for (i = 1; i < nret; ++i) { args_be.args[nargs + i] = cpu_to_be32(rets[i - 1]); diff --git a/include/hw/ppc/vof.h b/include/hw/ppc/vof.h index 640be46163..97fdef758b 100644 --- a/include/hw/ppc/vof.h +++ b/include/hw/ppc/vof.h @@ -55,4 +55,6 @@ struct VofMachineIfClass { address_space_write(&address_space_memory, \ (pa), MEMTXATTRS_UNSPECIFIED, (buf), (size)) +#define PROM_ERROR (~0U) + #endif /* HW_VOF_H */ diff --git a/softmmu/vl.c b/softmmu/vl.c index f815acccaa..4dee472c79 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -1545,7 +1545,7 @@ machine_parse_property_opt(QemuOptsList *opts_list, const char *propname, prop = keyval_parse(arg, opts_list->implied_opt_name, &help, errp); if (help) { qemu_opts_print_help(opts_list, true); - return; + exit(0); } opts = qdict_new(); qdict_put(opts, propname, prop); diff --git a/subprojects/libvhost-user/include/atomic.h b/subprojects/libvhost-user/include/atomic.h new file mode 120000 index 0000000000..8c2be64f7b --- /dev/null +++ b/subprojects/libvhost-user/include/atomic.h @@ -0,0 +1 @@ +../../../include/qemu/atomic.h
\ No newline at end of file diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c index fab7ca17ee..bf09693255 100644 --- a/subprojects/libvhost-user/libvhost-user.c +++ b/subprojects/libvhost-user/libvhost-user.c @@ -40,7 +40,7 @@ #endif -#include "qemu/atomic.h" +#include "include/atomic.h" #include "libvhost-user.h" @@ -1067,10 +1067,10 @@ vu_set_vring_addr_exec(VuDev *dev, VhostUserMsg *vmsg) DPRINT("vhost_vring_addr:\n"); DPRINT(" index: %d\n", vra->index); DPRINT(" flags: %d\n", vra->flags); - DPRINT(" desc_user_addr: 0x%016" PRIx64 "\n", vra->desc_user_addr); - DPRINT(" used_user_addr: 0x%016" PRIx64 "\n", vra->used_user_addr); - DPRINT(" avail_user_addr: 0x%016" PRIx64 "\n", vra->avail_user_addr); - DPRINT(" log_guest_addr: 0x%016" PRIx64 "\n", vra->log_guest_addr); + DPRINT(" desc_user_addr: 0x%016" PRIx64 "\n", (uint64_t)vra->desc_user_addr); + DPRINT(" used_user_addr: 0x%016" PRIx64 "\n", (uint64_t)vra->used_user_addr); + DPRINT(" avail_user_addr: 0x%016" PRIx64 "\n", (uint64_t)vra->avail_user_addr); + DPRINT(" log_guest_addr: 0x%016" PRIx64 "\n", (uint64_t)vra->log_guest_addr); vq->vra = *vra; vq->vring.flags = vra->flags; diff --git a/subprojects/libvhost-user/meson.build b/subprojects/libvhost-user/meson.build index b03446e7cd..39825d9404 100644 --- a/subprojects/libvhost-user/meson.build +++ b/subprojects/libvhost-user/meson.build @@ -4,21 +4,17 @@ project('libvhost-user', 'c', threads = dependency('threads') glib = dependency('glib-2.0') -inc = include_directories('../../include', '../../linux-headers') vhost_user = static_library('vhost-user', files('libvhost-user.c'), - include_directories: inc, dependencies: threads, c_args: '-D_GNU_SOURCE') executable('link-test', files('link-test.c'), - link_whole: vhost_user, - include_directories: inc) + link_whole: vhost_user) vhost_user_glib = static_library('vhost-user-glib', files('libvhost-user-glib.c'), - include_directories: inc, link_with: vhost_user, dependencies: glib) diff --git a/subprojects/libvhost-user/standard-headers/linux b/subprojects/libvhost-user/standard-headers/linux new file mode 120000 index 0000000000..15a2378139 --- /dev/null +++ b/subprojects/libvhost-user/standard-headers/linux @@ -0,0 +1 @@ +../../../include/standard-headers/linux
\ No newline at end of file diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 59ed8327ac..e69abe48e3 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -975,6 +975,12 @@ static struct kvm_cpuid2 *get_supported_hv_cpuid(CPUState *cs) kvm_check_extension(kvm_state, KVM_CAP_SYS_HYPERV_CPUID) > 0; /* + * Non-empty KVM context is needed when KVM_CAP_SYS_HYPERV_CPUID is + * unsupported, kvm_hyperv_expand_features() checks for that. + */ + assert(do_sys_ioctl || cs->kvm_state); + + /* * When the buffer is too small, KVM_GET_SUPPORTED_HV_CPUID fails with * -E2BIG, however, it doesn't report back the right size. Keep increasing * it and re-trying until we succeed. @@ -1105,6 +1111,14 @@ static uint32_t hv_cpuid_get_host(CPUState *cs, uint32_t func, int reg) if (kvm_check_extension(kvm_state, KVM_CAP_HYPERV_CPUID) > 0) { cpuid = get_supported_hv_cpuid(cs); } else { + /* + * 'cs->kvm_state' may be NULL when Hyper-V features are expanded + * before KVM context is created but this is only done when + * KVM_CAP_SYS_HYPERV_CPUID is supported and it implies + * KVM_CAP_HYPERV_CPUID. + */ + assert(cs->kvm_state); + cpuid = get_supported_hv_cpuid_legacy(cs); } hv_cpuid_cache = cpuid; diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c index 145511d635..e151104b4e 100644 --- a/target/i386/tcg/sysemu/svm_helper.c +++ b/target/i386/tcg/sysemu/svm_helper.c @@ -70,7 +70,7 @@ static inline bool ctl_has_irq(uint32_t int_ctl) uint32_t int_prio; uint32_t tpr; - int_prio = (int_ctl & V_INTR_PRIO_MASK) >> V_INTR_MASKING_SHIFT; + int_prio = (int_ctl & V_INTR_PRIO_MASK) >> V_INTR_PRIO_SHIFT; tpr = int_ctl & V_TPR_MASK; return (int_ctl & V_IRQ_MASK) && (int_prio >= tpr); } @@ -383,6 +383,9 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend) cpu_loop_exit(cs); break; case SVM_EVTINJ_TYPE_EXEPT: + if (vector == EXCP02_NMI || vector >= 31) { + cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC()); + } cs->exception_index = vector; env->error_code = event_inj_err; env->exception_is_int = 0; @@ -398,6 +401,9 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend) qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT"); cpu_loop_exit(cs); break; + default: + cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC()); + break; } qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", cs->exception_index, env->error_code); diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc index 8864ac4516..2e2518ee15 100644 --- a/target/ppc/translate/fixedpoint-impl.c.inc +++ b/target/ppc/translate/fixedpoint-impl.c.inc @@ -171,8 +171,35 @@ TRANS64(PSTD, do_ldst_PLS_D, false, true, MO_Q) static bool do_cmp_X(DisasContext *ctx, arg_X_bfl *a, bool s) { + if ((ctx->insns_flags & PPC_64B) == 0) { + /* + * For 32-bit implementations, The Programming Environments Manual says + * that "the L field must be cleared, otherwise the instruction form is + * invalid." It seems, however, that most 32-bit CPUs ignore invalid + * forms (e.g., section "Instruction Formats" of the 405 and 440 + * manuals, "Integer Compare Instructions" of the 601 manual), with the + * notable exception of the e500 and e500mc, where L=1 was reported to + * cause an exception. + */ + if (a->l) { + if ((ctx->insns_flags2 & PPC2_BOOKE206)) { + /* + * For 32-bit Book E v2.06 implementations (i.e. e500/e500mc), + * generate an illegal instruction exception. + */ + return false; + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "Invalid form of CMP%s at 0x" TARGET_FMT_lx ", L = 1\n", + s ? "" : "L", ctx->cia); + } + } + gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf); + return true; + } + + /* For 64-bit implementations, deal with bit L accordingly. */ if (a->l) { - REQUIRE_64BIT(ctx); gen_op_cmp(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf); } else { gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf); @@ -182,8 +209,35 @@ static bool do_cmp_X(DisasContext *ctx, arg_X_bfl *a, bool s) static bool do_cmp_D(DisasContext *ctx, arg_D_bf *a, bool s) { + if ((ctx->insns_flags & PPC_64B) == 0) { + /* + * For 32-bit implementations, The Programming Environments Manual says + * that "the L field must be cleared, otherwise the instruction form is + * invalid." It seems, however, that most 32-bit CPUs ignore invalid + * forms (e.g., section "Instruction Formats" of the 405 and 440 + * manuals, "Integer Compare Instructions" of the 601 manual), with the + * notable exception of the e500 and e500mc, where L=1 was reported to + * cause an exception. + */ + if (a->l) { + if ((ctx->insns_flags2 & PPC2_BOOKE206)) { + /* + * For 32-bit Book E v2.06 implementations (i.e. e500/e500mc), + * generate an illegal instruction exception. + */ + return false; + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "Invalid form of CMP%s at 0x" TARGET_FMT_lx ", L = 1\n", + s ? "I" : "LI", ctx->cia); + } + } + gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf); + return true; + } + + /* For 64-bit implementations, deal with bit L accordingly. */ if (a->l) { - REQUIRE_64BIT(ctx); gen_op_cmp(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf); } else { gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf); diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index 1e8b7784ef..cc5e83d98a 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -27,7 +27,8 @@ #include "migration-helpers.h" #include "tests/migration/migration-test.h" -#if defined(__linux__) +/* For dirty ring test; so far only x86_64 is supported */ +#if defined(__linux__) && defined(HOST_X86_64) #include "linux/kvm.h" #endif @@ -1395,7 +1396,7 @@ static void test_multifd_tcp_cancel(void) static bool kvm_dirty_ring_supported(void) { -#if defined(__linux__) +#if defined(__linux__) && defined(HOST_X86_64) int ret, kvm_fd = open("/dev/kvm", O_RDONLY); if (kvm_fd < 0) { |