All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
@ 2020-07-06 16:41 Paolo Bonzini
  2020-07-06 16:41 ` [PULL 01/53] tcg/svm: use host cr4 during NPT page table walk Paolo Bonzini
                   ` (54 more replies)
  0 siblings, 55 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel

The following changes since commit fc1bff958998910ec8d25db86cd2f53ff125f7ab:

  hw/misc/pca9552: Add missing TypeInfo::class_size field (2020-06-29 21:16:10 +0100)

are available in the Git repository at:

  git://github.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to 80270507070ec73ea82741ce24cb7909a9258ea3:

  scripts: improve message when TAP based tests fail (2020-07-06 12:14:25 -0400)

----------------------------------------------------------------
* Make checkpatch say 'qemu' instead of 'kernel' (Aleksandar)
* Fix PSE guests with emulated NPT (Alexander B. #1)
* Fix leak (Alexander B. #2)
* HVF fixes (Roman, Cameron)
* New Sapphire Rapids CPUID bits (Cathy)
* cpus.c and softmmu/ cleanups (Claudio)
* TAP driver tweaks (Daniel, Havard)
* object-add bugfix and testcases (Eric A.)
* Fix Coverity MIN_CONST and MAX_CONST (Eric B.)
* SSE fixes (Joseph)
* "-msg guest-name" option (Mario)
* support for AMD nested live migration (myself)
* Small i386 TCG fixes (myself)
* improved error reporting for Xen (myself)
* fix "-cpu host -overcommit cpu-pm=on" (myself)
* Add accel/Kconfig (Philippe)
* KVM API cleanup (Philippe)
* iscsi sense handling fixes (Yongji)
* Misc bugfixes

----------------------------------------------------------------
Aleksandar Markovic (1):
      checkpatch: Change occurences of 'kernel' to 'qemu' in user messages

Alexander Boettcher (1):
      tcg/svm: use host cr4 during NPT page table walk

Alexander Bulekov (1):
      pc: fix leak in pc_system_flash_cleanup_unused

Cameron Esfahani (1):
      i386: hvf: Make long mode enter and exit clearer

Cathy Zhang (2):
      target/i386: Add SERIALIZE cpu feature
      target/i386: Enable TSX Suspend Load Address Tracking feature

Claudio Fontana (3):
      softmmu: move softmmu only files from root
      cpu-throttle: new module, extracted from cpus.c
      cpu-timers, icount: new modules

Daniel P. Berrangé (1):
      scripts: improve message when TAP based tests fail

Eric Auger (3):
      qom: Introduce object_property_try_add_child()
      tests/qmp-cmd-test: Add qmp/object-add-duplicate-id
      tests/qmp-cmd-test: Add qmp/object-add-failure-modes

Eric Blake (1):
      coverity: provide Coverity-friendly MIN_CONST and MAX_CONST

Havard Skinnemoen (1):
      tests: Inject test name also when the test fails

Joseph Myers (2):
      target/i386: set SSE FTZ in correct floating-point state
      target/i386: fix IEEE SSE floating-point exception raising

Luwei Kang (1):
      target/i386: Correct the warning message of Intel PT

Mario Smarduch (1):
      util/qemu-error: prepend guest name to error message to identify affected VM owner

Paolo Bonzini (7):
      KVM: add support for AMD nested live migration
      Makefile: simplify MINIKCONF rules
      target/i386: remove gen_io_end
      target/i386: implement undocumented "smsw r32" behavior
      KVM: x86: believe what KVM says about WAITPKG
      target/i386: sev: provide proper error reporting for query-sev-capabilities
      target/i386: sev: fail query-sev-capabilities if QEMU cannot use SEV

Philippe Mathieu-Daudé (16):
      hw/core/null-machine: Do not initialize unused chardev backends
      MAINTAINERS: Fix KVM path expansion glob
      MAINTAINERS: Add an 'overall' entry for accelerators
      MAINTAINERS: Cover the HAX accelerator stub
      Makefile: Remove dangerous EOL trailing backslash
      Makefile: Write MINIKCONF variables as one entry per line
      accel/Kconfig: Extract accel selectors into their own config
      accel/Kconfig: Add the TCG selector
      accel/tcg: Add stub for probe_access()
      cpus: Move CPU code from exec.c to cpus-common.c
      accel/kvm: Let kvm_check_extension use global KVM state
      accel/kvm: Simplify kvm_check_extension()
      accel/kvm: Simplify kvm_check_extension_list()
      target/i386/kvm: Simplify get_para_features()
      target/i386/kvm: Simplify kvm_get_mce_cap_supported()
      target/i386/kvm: Simplify kvm_get_supported_[feature]_msrs()

Roman Bolshakov (7):
      i386: hvf: Set env->eip in macvm_set_rip()
      i386: hvf: Move synchronize functions to sysemu
      i386: hvf: Add hvf_cpu_synchronize_pre_loadvm()
      i386: hvf: Move Guest LMA reset to macvm_set_cr0()
      i386: hvf: Don't duplicate register reset
      i386: hvf: Clean up synchronize functions
      MAINTAINERS: Add Cameron as HVF co-maintainer

Thomas Huth (1):
      softmmu/vl: Remove the check for colons in -accel parameters

Xie Yongji (2):
      iscsi: handle check condition status in retry loop
      iscsi: return -EIO when sense fields are meaningless

lichun (1):
      chardev/tcp: fix error message double free error

 Kconfig                                      |   4 +
 Kconfig.host                                 |   7 -
 MAINTAINERS                                  |  31 +-
 Makefile                                     |  12 +-
 Makefile.target                              |   7 +-
 accel/Kconfig                                |   9 +
 accel/kvm/kvm-all.c                          |  72 +--
 accel/qtest.c                                |   6 +-
 accel/stubs/tcg-stub.c                       |   7 +
 accel/tcg/cpu-exec.c                         |  43 +-
 accel/tcg/tcg-all.c                          |   7 +-
 accel/tcg/translate-all.c                    |   3 +-
 block/iscsi.c                                |  22 +-
 chardev/char-socket.c                        |   3 +-
 cpus-common.c                                |  18 +
 dma-helpers.c                                |   4 +-
 docs/replay.txt                              |   6 +-
 exec.c                                       |  26 -
 hw/core/null-machine.c                       |   5 +
 hw/core/ptimer.c                             |   8 +-
 hw/hyperv/hyperv.c                           |   2 +-
 hw/i386/kvm/clock.c                          |   2 +-
 hw/i386/kvm/i8254.c                          |   4 +-
 hw/i386/kvm/ioapic.c                         |   2 +-
 hw/i386/pc_sysfw.c                           |   5 +
 hw/i386/x86.c                                |   1 +
 hw/intc/arm_gic_kvm.c                        |   2 +-
 hw/intc/openpic_kvm.c                        |   2 +-
 hw/intc/xics_kvm.c                           |   2 +-
 hw/s390x/s390-stattrib-kvm.c                 |   2 +-
 include/exec/cpu-all.h                       |   4 +
 include/exec/exec-all.h                      |   4 +-
 include/hw/core/cpu.h                        |  37 --
 include/qemu/error-report.h                  |   2 +
 include/qemu/main-loop.h                     |   5 +
 include/qemu/osdep.h                         |  21 +-
 include/qemu/timer.h                         |  22 +-
 include/qom/object.h                         |  26 +-
 include/sysemu/cpu-throttle.h                |  68 +++
 include/sysemu/cpu-timers.h                  |  81 +++
 include/sysemu/cpus.h                        |  12 +-
 include/sysemu/hvf.h                         |   2 +-
 include/sysemu/hw_accel.h                    |  13 +
 include/sysemu/kvm.h                         |   2 +-
 include/sysemu/qtest.h                       |   2 +
 include/sysemu/replay.h                      |   4 +-
 migration/migration.c                        |   1 +
 migration/ram.c                              |   1 +
 qemu-options.hx                              |  12 +-
 qom/object.c                                 |  21 +-
 qom/object_interfaces.c                      |   7 +-
 replay/replay.c                              |   6 +-
 scripts/checkpatch.pl                        |   6 +-
 scripts/tap-driver.pl                        |   2 +-
 softmmu/Makefile.objs                        |  13 +
 arch_init.c => softmmu/arch_init.c           |   0
 balloon.c => softmmu/balloon.c               |   0
 softmmu/cpu-throttle.c                       | 122 ++++
 softmmu/cpu-timers.c                         | 284 +++++++++
 cpus.c => softmmu/cpus.c                     | 851 +--------------------------
 softmmu/icount.c                             | 499 ++++++++++++++++
 ioport.c => softmmu/ioport.c                 |   0
 memory.c => softmmu/memory.c                 |   0
 memory_mapping.c => softmmu/memory_mapping.c |   0
 qtest.c => softmmu/qtest.c                   |  34 +-
 softmmu/timers-state.h                       |  69 +++
 softmmu/vl.c                                 |  22 +-
 stubs/Makefile.objs                          |   3 +-
 stubs/clock-warp.c                           |   4 +-
 stubs/cpu-get-clock.c                        |   3 +-
 stubs/cpu-get-icount.c                       |  21 -
 stubs/icount.c                               |  22 +
 stubs/qemu-timer-notify-cb.c                 |   8 +
 stubs/qtest.c                                |   5 +
 target/alpha/translate.c                     |   3 +-
 target/arm/helper.c                          |   7 +-
 target/arm/kvm.c                             |  13 +-
 target/arm/kvm32.c                           |   2 +-
 target/arm/kvm64.c                           |  15 +-
 target/i386/cpu.c                            |  13 +-
 target/i386/cpu.h                            |  10 +
 target/i386/excp_helper.c                    |   4 +-
 target/i386/fpu_helper.c                     |  35 +-
 target/i386/gdbstub.c                        |   1 +
 target/i386/helper.c                         |   1 +
 target/i386/helper.h                         |   1 +
 target/i386/hvf/hvf.c                        | 137 +----
 target/i386/hvf/vmx.h                        |  17 +-
 target/i386/kvm.c                            | 143 +++--
 target/i386/kvm_i386.h                       |   1 +
 target/i386/machine.c                        |  31 +-
 target/i386/monitor.c                        |  10 +-
 target/i386/ops_sse.h                        |  28 +-
 target/i386/sev-stub.c                       |   3 +-
 target/i386/sev.c                            |  27 +-
 target/i386/sev_i386.h                       |   2 +-
 target/i386/svm.h                            |   1 +
 target/i386/svm_helper.c                     |   7 +-
 target/i386/translate.c                      |  36 +-
 target/mips/kvm.c                            |   4 +-
 target/ppc/kvm.c                             |  34 +-
 target/riscv/csr.c                           |   8 +-
 target/s390x/cpu_models.c                    |   3 +-
 target/s390x/kvm.c                           |  30 +-
 tests/Makefile.include                       |   2 +-
 tests/ptimer-test-stubs.c                    |   7 +-
 tests/qtest/qmp-cmd-test.c                   | 109 +++-
 tests/tcg/i386/Makefile.target               |   4 +
 tests/tcg/i386/test-i386-sse-exceptions.c    | 813 +++++++++++++++++++++++++
 tests/test-timed-average.c                   |   2 +-
 util/main-loop.c                             |   4 +-
 util/qemu-error.c                            |   7 +
 util/qemu-timer.c                            |  12 +-
 113 files changed, 2817 insertions(+), 1415 deletions(-)
 create mode 100644 Kconfig
 create mode 100644 accel/Kconfig
 create mode 100644 include/sysemu/cpu-throttle.h
 create mode 100644 include/sysemu/cpu-timers.h
 rename arch_init.c => softmmu/arch_init.c (100%)
 rename balloon.c => softmmu/balloon.c (100%)
 create mode 100644 softmmu/cpu-throttle.c
 create mode 100644 softmmu/cpu-timers.c
 rename cpus.c => softmmu/cpus.c (58%)
 create mode 100644 softmmu/icount.c
 rename ioport.c => softmmu/ioport.c (100%)
 rename memory.c => softmmu/memory.c (100%)
 rename memory_mapping.c => softmmu/memory_mapping.c (100%)
 rename qtest.c => softmmu/qtest.c (95%)
 create mode 100644 softmmu/timers-state.h
 delete mode 100644 stubs/cpu-get-icount.c
 create mode 100644 stubs/icount.c
 create mode 100644 stubs/qemu-timer-notify-cb.c
 create mode 100644 tests/tcg/i386/test-i386-sse-exceptions.c
-- 
2.26.2



^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PULL 01/53] tcg/svm: use host cr4 during NPT page table walk
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 02/53] tests: Inject test name also when the test fails Paolo Bonzini
                   ` (53 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alexander Boettcher

From: Alexander Boettcher <alexander.boettcher@genode-labs.com>

During a page table walk of TCG+SVM the code in target/i386/excp_helper.c
get_hphys() uses the cr4 register of the guest instead of the hypervisor
to check for the PSE bit. In the test case we have, the guest have not
enabled (yet) the PSE bit and so the page table walk results in a wrong
host physical address resolution and wrong content read by the guest.

Attached patch is against 4.2.1, but works also on 3.1.0. It fixes the
issue for our automated testcase, which is a 32bit hypervisor w/o PAE
support running a guest VM with tcg+svm.

The test worked beforehand up to qemu 2.12, started to fail with qemu 3.0
and later. The added TCG/SVM NPT commit seems to introduce the regression.

In case someone want to try to reproduce it, the iso is at [0], the good
case is [1] and the failing case is [2]. The used commandline is:

qemu-system-i386 -no-kvm -nographic -cpu phenom -m 512 -machine q35 -cdrom seoul-vmm-test.iso

[0] https://depot.genode.org/alex-ab/images/seoul-vmm-test.iso
[1] https://depot.genode.org/alex-ab/images/seoul-vmm-good.txt
[2] https://depot.genode.org/alex-ab/images/seoul-vmm-bad.txt

Signed-off-by: Alexander Boettcher <alexander.boettcher@genode-labs.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/excp_helper.c | 4 ++--
 target/i386/svm.h         | 1 +
 target/i386/svm_helper.c  | 7 ++++++-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/target/i386/excp_helper.c b/target/i386/excp_helper.c
index 1447bda7a9..b10c7ecbcc 100644
--- a/target/i386/excp_helper.c
+++ b/target/i386/excp_helper.c
@@ -262,8 +262,8 @@ static hwaddr get_hphys(CPUState *cs, hwaddr gphys, MMUAccessType access_type,
         }
         ptep = pde | PG_NX_MASK;
 
-        /* if PSE bit is set, then we use a 4MB page */
-        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
+        /* if host cr4 PSE bit is set, then we use a 4MB page */
+        if ((pde & PG_PSE_MASK) && (env->nested_pg_mode & SVM_NPT_PSE)) {
             page_size = 4096 * 1024;
             pte_addr = pde_addr;
 
diff --git a/target/i386/svm.h b/target/i386/svm.h
index 23a3a040b8..ae30fc6f79 100644
--- a/target/i386/svm.h
+++ b/target/i386/svm.h
@@ -135,6 +135,7 @@
 #define SVM_NPT_PAE         (1 << 0)
 #define SVM_NPT_LMA         (1 << 1)
 #define SVM_NPT_NXE         (1 << 2)
+#define SVM_NPT_PSE         (1 << 3)
 
 #define SVM_NPTEXIT_P       (1ULL << 0)
 #define SVM_NPTEXIT_RW      (1ULL << 1)
diff --git a/target/i386/svm_helper.c b/target/i386/svm_helper.c
index 7b8105a1c3..6224387eab 100644
--- a/target/i386/svm_helper.c
+++ b/target/i386/svm_helper.c
@@ -209,16 +209,21 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
 
     nested_ctl = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                           control.nested_ctl));
+
+    env->nested_pg_mode = 0;
+
     if (nested_ctl & SVM_NPT_ENABLED) {
         env->nested_cr3 = x86_ldq_phys(cs,
                                 env->vm_vmcb + offsetof(struct vmcb,
                                                         control.nested_cr3));
         env->hflags2 |= HF2_NPT_MASK;
 
-        env->nested_pg_mode = 0;
         if (env->cr[4] & CR4_PAE_MASK) {
             env->nested_pg_mode |= SVM_NPT_PAE;
         }
+        if (env->cr[4] & CR4_PSE_MASK) {
+            env->nested_pg_mode |= SVM_NPT_PSE;
+        }
         if (env->hflags & HF_LMA_MASK) {
             env->nested_pg_mode |= SVM_NPT_LMA;
         }
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 02/53] tests: Inject test name also when the test fails
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
  2020-07-06 16:41 ` [PULL 01/53] tcg/svm: use host cr4 during NPT page table walk Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 03/53] util/qemu-error: prepend guest name to error message to identify affected VM owner Paolo Bonzini
                   ` (52 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Havard Skinnemoen

From: Havard Skinnemoen <hskinnemoen@google.com>

If a test is unsuccessful, the result is "not ok", which does not match
the regex because it includes a space.

This regex matches both "ok" and "not ok".

Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com>
Message-Id: <20200628213046.2028271-1-hskinnemoen@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tests/Makefile.include | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 3f4448a20b..09df2d3f86 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -637,7 +637,7 @@ define do_test_tap
           { export MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$(( $${RANDOM:-0} % 255 + 1))} $2; \
             $(foreach COMMAND, $1, \
 	      $(COMMAND) -m=$(SPEED) -k --tap < /dev/null \
-	      | sed "s/^[a-z][a-z]* [0-9]* /&$(notdir $(COMMAND)) /" || true; ) } \
+	      | sed "s/^\(not \)\?ok [0-9]* /&$(notdir $(COMMAND)) /" || true; ) } \
 	      | ./scripts/tap-merge.pl | tee "$@" \
 	      | ./scripts/tap-driver.pl $(if $(V),, --show-failures-only), \
 	  "TAP","$@")
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 03/53] util/qemu-error: prepend guest name to error message to identify affected VM owner
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
  2020-07-06 16:41 ` [PULL 01/53] tcg/svm: use host cr4 during NPT page table walk Paolo Bonzini
  2020-07-06 16:41 ` [PULL 02/53] tests: Inject test name also when the test fails Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 04/53] qom: Introduce object_property_try_add_child() Paolo Bonzini
                   ` (51 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mario Smarduch

From: Mario Smarduch <msmarduch@digitalocean.com>

This is followup patch to the one submitted back in Oct, 19

https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg02102.html

My mistake here, I took my eyes of the mailing list after I got the
initial thumbs up. This patch follows up on Markus comments in the
above link.

Purpose of this patch:

We want to print guest name for errors, warnings and info messages. This
was the first of two patches the second being MCE errors targeting a VM
with guest name prepended. But in a large fleet we see many other
errors that disable a VM or crash it. In a large fleet and centralized
logging having the guest name enables identify of owner and customer.

Signed-off-by: Mario Smarduch <msmarduch@digitalocean.com>
Message-Id: <20200626201900.8876-1-msmarduch@digitalocean.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/error-report.h |  2 ++
 qemu-options.hx             | 12 +++++++++---
 softmmu/vl.c                |  9 +++++++++
 util/qemu-error.c           |  7 +++++++
 4 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h
index 87532d8596..a5ad95ff1b 100644
--- a/include/qemu/error-report.h
+++ b/include/qemu/error-report.h
@@ -75,5 +75,7 @@ void error_init(const char *argv0);
 const char *error_get_progname(void);
 
 extern bool error_with_timestamp;
+extern bool error_with_guestname;
+extern const char *error_guest_name;
 
 #endif
diff --git a/qemu-options.hx b/qemu-options.hx
index 196f468786..e5b5d6564a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4291,16 +4291,22 @@ HXCOMM Deprecated by -accel tcg
 DEF("no-kvm", 0, QEMU_OPTION_no_kvm, "", QEMU_ARCH_I386)
 
 DEF("msg", HAS_ARG, QEMU_OPTION_msg,
-    "-msg timestamp[=on|off]\n"
+    "-msg [timestamp[=on|off]][,guest-name=[on|off]]\n"
     "                control error message format\n"
-    "                timestamp=on enables timestamps (default: off)\n",
+    "                timestamp=on enables timestamps (default: off)\n"
+    "                guest-name=on enables guest name prefix but only if\n"
+    "                              -name guest option is set (default: off)\n",
     QEMU_ARCH_ALL)
 SRST
-``-msg timestamp[=on|off]``
+``-msg [timestamp[=on|off]][,guest-name[=on|off]]``
     Control error message format.
 
     ``timestamp=on|off``
         Prefix messages with a timestamp. Default is off.
+
+    ``guest-name=on|off``
+        Prefix messages with guest name but only if -name guest option is set
+        otherwise the option is ignored. Default is off.
 ERST
 
 DEF("dump-vmstate", HAS_ARG, QEMU_OPTION_dump_vmstate,
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 3e15ee2435..b003a49058 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -389,6 +389,12 @@ static QemuOptsList qemu_msg_opts = {
             .name = "timestamp",
             .type = QEMU_OPT_BOOL,
         },
+        {
+            .name = "guest-name",
+            .type = QEMU_OPT_BOOL,
+            .help = "Prepends guest name for error messages but only if "
+                    "-name guest is set otherwise option is ignored\n",
+        },
         { /* end of list */ }
     },
 };
@@ -1109,6 +1115,7 @@ static void realtime_init(void)
 static void configure_msg(QemuOpts *opts)
 {
     error_with_timestamp = qemu_opt_get_bool(opts, "timestamp", false);
+    error_with_guestname = qemu_opt_get_bool(opts, "guest-name", false);
 }
 
 
@@ -3578,6 +3585,8 @@ void qemu_init(int argc, char **argv, char **envp)
                 if (!opts) {
                     exit(1);
                 }
+                /* Capture guest name if -msg guest-name is used later */
+                error_guest_name = qemu_opt_get(opts, "guest");
                 break;
             case QEMU_OPTION_prom_env:
                 if (nb_prom_envs >= MAX_PROM_ENVS) {
diff --git a/util/qemu-error.c b/util/qemu-error.c
index dac7c7dc50..3ee41438e9 100644
--- a/util/qemu-error.c
+++ b/util/qemu-error.c
@@ -26,6 +26,8 @@ typedef enum {
 
 /* Prepend timestamp to messages */
 bool error_with_timestamp;
+bool error_with_guestname;
+const char *error_guest_name;
 
 int error_printf(const char *fmt, ...)
 {
@@ -213,6 +215,11 @@ static void vreport(report_type type, const char *fmt, va_list ap)
         g_free(timestr);
     }
 
+    /* Only prepend guest name if -msg guest-name and -name guest=... are set */
+    if (error_with_guestname && error_guest_name && !cur_mon) {
+        error_printf("%s ", error_guest_name);
+    }
+
     print_loc();
 
     switch (type) {
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 04/53] qom: Introduce object_property_try_add_child()
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (2 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 03/53] util/qemu-error: prepend guest name to error message to identify affected VM owner Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 05/53] tests/qmp-cmd-test: Add qmp/object-add-duplicate-id Paolo Bonzini
                   ` (50 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Eric Auger, Markus Armbruster, Greg Kurz

From: Eric Auger <eric.auger@redhat.com>

object_property_add() does not allow object_property_try_add()
to gracefully fail as &error_abort is passed as an error handle.

However such failure can easily be triggered from the QMP shell when,
for instance, one attempts to create an object with an id that already
exists. This is achieved from the following call path:

qmp_object_add -> user_creatable_add_dict -> user_creatable_add_type ->
object_property_add_child -> object_property_add

For instance, from the qmp-shell, call twice:
object-add qom-type=memory-backend-ram id=mem1 props.size=1073741824
and QEMU aborts.

This behavior is undesired as a user/management application mistake
in reusing a property ID shouldn't result in loss of the VM and live
data within.

This patch introduces a new function, object_property_try_add_child()
which takes an error handle and turn object_property_try_add() into
a non-static one.

Now the call path becomes:

user_creatable_add_type -> object_property_try_add_child ->
object_property_try_add

and the error is returned gracefully to the QMP client.

(QEMU) object-add qom-type=memory-backend-ram id=mem2  props.size=4294967296
{"return": {}}
(QEMU) object-add qom-type=memory-backend-ram id=mem2  props.size=4294967296
{"error": {"class": "GenericError", "desc": "attempt to add duplicate property
'mem2' to object (type 'container')"}}

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Fixes: d2623129a7de ("qom: Drop parameter @errp of object_property_add() & friends")
Reviewed-by: Markus Armbruster <armbru@redhat.com>

Reviewed-by: Greg Kurz <groug@kaod.org>
Tested-by: Greg Kurz <groug@kaod.org>
Message-Id: <20200629193424.30280-2-eric.auger@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qom/object.h    | 26 ++++++++++++++++++++++++--
 qom/object.c            | 21 ++++++++++++++++-----
 qom/object_interfaces.c |  7 +++++--
 3 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 94a61ccc3f..1c5cdcd0e3 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1039,7 +1039,7 @@ Object *object_ref(Object *obj);
 void object_unref(Object *obj);
 
 /**
- * object_property_add:
+ * object_property_try_add:
  * @obj: the object to add a property to
  * @name: the name of the property.  This can contain any character except for
  *  a forward slash.  In general, you should use hyphens '-' instead of
@@ -1056,10 +1056,23 @@ void object_unref(Object *obj);
  *   meant to allow a property to free its opaque upon object
  *   destruction.  This may be NULL.
  * @opaque: an opaque pointer to pass to the callbacks for the property
+ * @errp: pointer to error object
  *
  * Returns: The #ObjectProperty; this can be used to set the @resolve
  * callback for child and link properties.
  */
+ObjectProperty *object_property_try_add(Object *obj, const char *name,
+                                        const char *type,
+                                        ObjectPropertyAccessor *get,
+                                        ObjectPropertyAccessor *set,
+                                        ObjectPropertyRelease *release,
+                                        void *opaque, Error **errp);
+
+/**
+ * object_property_add:
+ * Same as object_property_try_add() with @errp hardcoded to
+ * &error_abort.
+ */
 ObjectProperty *object_property_add(Object *obj, const char *name,
                                     const char *type,
                                     ObjectPropertyAccessor *get,
@@ -1495,10 +1508,11 @@ Object *object_resolve_path_type(const char *path, const char *typename,
 Object *object_resolve_path_component(Object *parent, const char *part);
 
 /**
- * object_property_add_child:
+ * object_property_try_add_child:
  * @obj: the object to add a property to
  * @name: the name of the property
  * @child: the child object
+ * @errp: pointer to error object
  *
  * Child properties form the composition tree.  All objects need to be a child
  * of another object.  Objects can only be a child of one object.
@@ -1512,6 +1526,14 @@ Object *object_resolve_path_component(Object *parent, const char *part);
  *
  * Returns: The newly added property on success, or %NULL on failure.
  */
+ObjectProperty *object_property_try_add_child(Object *obj, const char *name,
+                                              Object *child, Error **errp);
+
+/**
+ * object_property_add_child:
+ * Same as object_property_try_add_child() with @errp hardcoded to
+ * &error_abort
+ */
 ObjectProperty *object_property_add_child(Object *obj, const char *name,
                                           Object *child);
 
diff --git a/qom/object.c b/qom/object.c
index 6ece96bc2b..dc10bb1889 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1132,7 +1132,7 @@ void object_unref(Object *obj)
     }
 }
 
-static ObjectProperty *
+ObjectProperty *
 object_property_try_add(Object *obj, const char *name, const char *type,
                         ObjectPropertyAccessor *get,
                         ObjectPropertyAccessor *set,
@@ -1651,8 +1651,8 @@ static void object_finalize_child_property(Object *obj, const char *name,
 }
 
 ObjectProperty *
-object_property_add_child(Object *obj, const char *name,
-                          Object *child)
+object_property_try_add_child(Object *obj, const char *name,
+                              Object *child, Error **errp)
 {
     g_autofree char *type = NULL;
     ObjectProperty *op;
@@ -1661,14 +1661,25 @@ object_property_add_child(Object *obj, const char *name,
 
     type = g_strdup_printf("child<%s>", object_get_typename(child));
 
-    op = object_property_add(obj, name, type, object_get_child_property, NULL,
-                             object_finalize_child_property, child);
+    op = object_property_try_add(obj, name, type, object_get_child_property,
+                                 NULL, object_finalize_child_property,
+                                 child, errp);
+    if (!op) {
+        return NULL;
+    }
     op->resolve = object_resolve_child_property;
     object_ref(child);
     child->parent = obj;
     return op;
 }
 
+ObjectProperty *
+object_property_add_child(Object *obj, const char *name,
+                          Object *child)
+{
+    return object_property_try_add_child(obj, name, child, &error_abort);
+}
+
 void object_property_allow_set_link(const Object *obj, const char *name,
                                     Object *val, Error **errp)
 {
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 7e26f86fa6..1e05e41d2f 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -82,8 +82,11 @@ Object *user_creatable_add_type(const char *type, const char *id,
     }
 
     if (id != NULL) {
-        object_property_add_child(object_get_objects_root(),
-                                  id, obj);
+        object_property_try_add_child(object_get_objects_root(),
+                                      id, obj, &local_err);
+        if (local_err) {
+            goto out;
+        }
     }
 
     user_creatable_complete(USER_CREATABLE(obj), &local_err);
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 05/53] tests/qmp-cmd-test: Add qmp/object-add-duplicate-id
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (3 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 04/53] qom: Introduce object_property_try_add_child() Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 06/53] tests/qmp-cmd-test: Add qmp/object-add-failure-modes Paolo Bonzini
                   ` (49 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Eric Auger, Thomas Huth, Markus Armbruster

From: Eric Auger <eric.auger@redhat.com>

This new test checks that attempting to create an object
with an existing ID gracefully fails.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Acked-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>

Message-Id: <20200629193424.30280-3-eric.auger@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tests/qtest/qmp-cmd-test.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c
index 9f5228cd99..fc65fa3726 100644
--- a/tests/qtest/qmp-cmd-test.c
+++ b/tests/qtest/qmp-cmd-test.c
@@ -213,6 +213,23 @@ static void test_object_add_without_props(void)
     qtest_quit(qts);
 }
 
+static void test_object_add_with_duplicate_id(void)
+{
+    QTestState *qts;
+    QDict *resp;
+
+    qts = qtest_init(common_args);
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                    " {'qom-type': 'memory-backend-ram', 'id': 'ram1', 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                    " {'qom-type': 'memory-backend-ram', 'id': 'ram1', 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+    qtest_quit(qts);
+}
+
 int main(int argc, char *argv[])
 {
     QmpSchema schema;
@@ -225,6 +242,8 @@ int main(int argc, char *argv[])
 
     qtest_add_func("qmp/object-add-without-props",
                    test_object_add_without_props);
+    qtest_add_func("qmp/object-add-duplicate-id",
+                   test_object_add_with_duplicate_id);
     /* TODO: add coverage of generic object-add failure modes */
 
     ret = g_test_run();
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 06/53] tests/qmp-cmd-test: Add qmp/object-add-failure-modes
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (4 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 05/53] tests/qmp-cmd-test: Add qmp/object-add-duplicate-id Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 07/53] hw/core/null-machine: Do not initialize unused chardev backends Paolo Bonzini
                   ` (48 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Eric Auger

From: Eric Auger <eric.auger@redhat.com>

Merge the existing object-add test cases into a single test
functions and cover more failure cases.

Signed-off-by: Eric Auger <eric.auger@redhat.com>

Message-Id: <20200629193424.30280-4-eric.auger@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tests/qtest/qmp-cmd-test.c | 112 +++++++++++++++++++++++++++++++------
 1 file changed, 96 insertions(+), 16 deletions(-)

diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c
index fc65fa3726..c68f99f659 100644
--- a/tests/qtest/qmp-cmd-test.c
+++ b/tests/qtest/qmp-cmd-test.c
@@ -200,33 +200,116 @@ static void add_query_tests(QmpSchema *schema)
     }
 }
 
-static void test_object_add_without_props(void)
+static void test_object_add_failure_modes(void)
 {
     QTestState *qts;
     QDict *resp;
 
+    /* attempt to create an object without props */
     qts = qtest_init(common_args);
     resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
-                    " {'qom-type': 'memory-backend-ram', 'id': 'ram1' } }");
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1' } }");
     g_assert_nonnull(resp);
     qmp_assert_error_class(resp, "GenericError");
-    qtest_quit(qts);
-}
 
-static void test_object_add_with_duplicate_id(void)
-{
-    QTestState *qts;
-    QDict *resp;
+    /* attempt to create an object without qom-type */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
 
-    qts = qtest_init(common_args);
+    /* attempt to delete an object that does not exist */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+
+    /* attempt to create 2 objects with duplicate id */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
     resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
-                    " {'qom-type': 'memory-backend-ram', 'id': 'ram1', 'props': {'size': 1048576 } } }");
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+
+    /* delete ram1 object */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
     g_assert_nonnull(resp);
     g_assert(qdict_haskey(resp, "return"));
+
+    /* attempt to create an object with a property of a wrong type */
     resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
-                    " {'qom-type': 'memory-backend-ram', 'id': 'ram1', 'props': {'size': 1048576 } } }");
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': '1048576' } } }");
     g_assert_nonnull(resp);
+    /* now do it right */
     qmp_assert_error_class(resp, "GenericError");
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* delete ram1 object */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* attempt to create an object without the id */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+    /* now do it right */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* delete ram1 object */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* attempt to set a non existing property */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'sized': 1048576 } } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+    /* now do it right */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* delete ram1 object without id */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'ida': 'ram1' } }");
+    g_assert_nonnull(resp);
+
+    /* delete ram1 object */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* delete ram1 object that does not exist anymore*/
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+
     qtest_quit(qts);
 }
 
@@ -240,11 +323,8 @@ int main(int argc, char *argv[])
     qmp_schema_init(&schema);
     add_query_tests(&schema);
 
-    qtest_add_func("qmp/object-add-without-props",
-                   test_object_add_without_props);
-    qtest_add_func("qmp/object-add-duplicate-id",
-                   test_object_add_with_duplicate_id);
-    /* TODO: add coverage of generic object-add failure modes */
+    qtest_add_func("qmp/object-add-failure-modes",
+                   test_object_add_failure_modes);
 
     ret = g_test_run();
 
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 07/53] hw/core/null-machine: Do not initialize unused chardev backends
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (5 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 06/53] tests/qmp-cmd-test: Add qmp/object-add-failure-modes Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 08/53] target/i386: set SSE FTZ in correct floating-point state Paolo Bonzini
                   ` (47 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Thomas Huth, Richard Henderson, Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <f4bug@amsat.org>

The MachineClass uses an inverted logic (inherited from the
PC machines [*]) to create the chardev backends for the default
devices (see commits 998bbd74b9d..aa40fc9c964 and ac33f8fad14).

As the none-machine doesn't have any hardware device, it is
pointless to initialize chardev backends. Fix by setting the
'no_defaults' bits in its MachineClass.

Suggested-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20200624105611.1049-1-f4bug@amsat.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/null-machine.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index cb47d9d4f8..7e693523d7 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -50,6 +50,11 @@ static void machine_none_machine_init(MachineClass *mc)
     mc->max_cpus = 1;
     mc->default_ram_size = 0;
     mc->default_ram_id = "ram";
+    mc->no_serial = 1;
+    mc->no_parallel = 1;
+    mc->no_floppy = 1;
+    mc->no_cdrom = 1;
+    mc->no_sdcard = 1;
 }
 
 DEFINE_MACHINE("none", machine_none_machine_init)
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 08/53] target/i386: set SSE FTZ in correct floating-point state
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (6 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 07/53] hw/core/null-machine: Do not initialize unused chardev backends Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 09/53] target/i386: fix IEEE SSE floating-point exception raising Paolo Bonzini
                   ` (46 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joseph Myers

From: Joseph Myers <joseph@codesourcery.com>

The code to set floating-point state when MXCSR changes calls
set_flush_to_zero on &env->fp_status, so affecting the x87
floating-point state rather than the SSE state.  Fix to call it for
&env->sse_status instead.

Signed-off-by: Joseph Myers <joseph@codesourcery.com>
Message-Id: <alpine.DEB.2.21.2006252357170.3832@digraph.polyomino.org.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/fpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c
index 71cec3962f..ec5b9db8b9 100644
--- a/target/i386/fpu_helper.c
+++ b/target/i386/fpu_helper.c
@@ -2972,7 +2972,7 @@ void update_mxcsr_status(CPUX86State *env)
     set_flush_inputs_to_zero((mxcsr & SSE_DAZ) ? 1 : 0, &env->sse_status);
 
     /* set flush to zero */
-    set_flush_to_zero((mxcsr & SSE_FZ) ? 1 : 0, &env->fp_status);
+    set_flush_to_zero((mxcsr & SSE_FZ) ? 1 : 0, &env->sse_status);
 }
 
 void helper_ldmxcsr(CPUX86State *env, uint32_t val)
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 09/53] target/i386: fix IEEE SSE floating-point exception raising
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (7 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 08/53] target/i386: set SSE FTZ in correct floating-point state Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 10/53] KVM: add support for AMD nested live migration Paolo Bonzini
                   ` (45 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joseph Myers

From: Joseph Myers <joseph@codesourcery.com>

The SSE instruction implementations all fail to raise the expected
IEEE floating-point exceptions because they do nothing to convert the
exception state from the softfloat machinery into the exception flags
in MXCSR.

Fix this by adding such conversions.  Unlike for x87, emulated SSE
floating-point operations might be optimized using hardware floating
point on the host, and so a different approach is taken that is
compatible with such optimizations.  The required invariant is that
all exceptions set in env->sse_status (other than "denormal operand",
for which the SSE semantics are different from those in the softfloat
code) are ones that are set in the MXCSR; the emulated MXCSR is
updated lazily when code reads MXCSR, while when code sets MXCSR, the
exceptions in env->sse_status are set accordingly.

A few instructions do not raise all the exceptions that would be
raised by the softfloat code, and those instructions are made to save
and restore the softfloat exception state accordingly.

Nothing is done about "denormal operand"; setting that (only for the
case when input denormals are *not* flushed to zero, the opposite of
the logic in the softfloat code for such an exception) will require
custom code for relevant instructions, or else architecture-specific
conditionals in the softfloat code for when to set such an exception
together with custom code for various SSE conversion and rounding
instructions that do not set that exception.

Nothing is done about trapping exceptions (for which there is minimal
and largely broken support in QEMU's emulation in the x87 case and no
support at all in the SSE case).

Signed-off-by: Joseph Myers <joseph@codesourcery.com>
Message-Id: <alpine.DEB.2.21.2006252358000.3832@digraph.polyomino.org.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.h                         |   1 +
 target/i386/fpu_helper.c                  |  33 +
 target/i386/gdbstub.c                     |   1 +
 target/i386/helper.c                      |   1 +
 target/i386/helper.h                      |   1 +
 target/i386/ops_sse.h                     |  28 +-
 target/i386/translate.c                   |   1 +
 tests/tcg/i386/Makefile.target            |   4 +
 tests/tcg/i386/test-i386-sse-exceptions.c | 813 ++++++++++++++++++++++
 9 files changed, 871 insertions(+), 12 deletions(-)
 create mode 100644 tests/tcg/i386/test-i386-sse-exceptions.c

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 7d77efd9e4..06b2e3a5c6 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2143,6 +2143,7 @@ static inline bool cpu_vmx_maybe_enabled(CPUX86State *env)
 /* fpu_helper.c */
 void update_fp_status(CPUX86State *env);
 void update_mxcsr_status(CPUX86State *env);
+void update_mxcsr_from_sse_status(CPUX86State *env);
 
 static inline void cpu_set_mxcsr(CPUX86State *env, uint32_t mxcsr)
 {
diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c
index ec5b9db8b9..2ae4f30b99 100644
--- a/target/i386/fpu_helper.c
+++ b/target/i386/fpu_helper.c
@@ -2539,6 +2539,7 @@ static void do_xsave_fpu(CPUX86State *env, target_ulong ptr, uintptr_t ra)
 
 static void do_xsave_mxcsr(CPUX86State *env, target_ulong ptr, uintptr_t ra)
 {
+    update_mxcsr_from_sse_status(env);
     cpu_stl_data_ra(env, ptr + XO(legacy.mxcsr), env->mxcsr, ra);
     cpu_stl_data_ra(env, ptr + XO(legacy.mxcsr_mask), 0x0000ffff, ra);
 }
@@ -2968,6 +2969,14 @@ void update_mxcsr_status(CPUX86State *env)
     }
     set_float_rounding_mode(rnd_type, &env->sse_status);
 
+    /* Set exception flags.  */
+    set_float_exception_flags((mxcsr & FPUS_IE ? float_flag_invalid : 0) |
+                              (mxcsr & FPUS_ZE ? float_flag_divbyzero : 0) |
+                              (mxcsr & FPUS_OE ? float_flag_overflow : 0) |
+                              (mxcsr & FPUS_UE ? float_flag_underflow : 0) |
+                              (mxcsr & FPUS_PE ? float_flag_inexact : 0),
+                              &env->sse_status);
+
     /* set denormals are zero */
     set_flush_inputs_to_zero((mxcsr & SSE_DAZ) ? 1 : 0, &env->sse_status);
 
@@ -2975,6 +2984,30 @@ void update_mxcsr_status(CPUX86State *env)
     set_flush_to_zero((mxcsr & SSE_FZ) ? 1 : 0, &env->sse_status);
 }
 
+void update_mxcsr_from_sse_status(CPUX86State *env)
+{
+    uint8_t flags = get_float_exception_flags(&env->sse_status);
+    /*
+     * The MXCSR denormal flag has opposite semantics to
+     * float_flag_input_denormal (the softfloat code sets that flag
+     * only when flushing input denormals to zero, but SSE sets it
+     * only when not flushing them to zero), so is not converted
+     * here.
+     */
+    env->mxcsr |= ((flags & float_flag_invalid ? FPUS_IE : 0) |
+                   (flags & float_flag_divbyzero ? FPUS_ZE : 0) |
+                   (flags & float_flag_overflow ? FPUS_OE : 0) |
+                   (flags & float_flag_underflow ? FPUS_UE : 0) |
+                   (flags & float_flag_inexact ? FPUS_PE : 0) |
+                   (flags & float_flag_output_denormal ? FPUS_UE | FPUS_PE :
+                    0));
+}
+
+void helper_update_mxcsr(CPUX86State *env)
+{
+    update_mxcsr_from_sse_status(env);
+}
+
 void helper_ldmxcsr(CPUX86State *env, uint32_t val)
 {
     cpu_set_mxcsr(env, val);
diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index b98a99500a..9ae43bda0f 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -184,6 +184,7 @@ int x86_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
             return gdb_get_reg32(mem_buf, 0); /* fop */
 
         case IDX_MXCSR_REG:
+            update_mxcsr_from_sse_status(env);
             return gdb_get_reg32(mem_buf, env->mxcsr);
 
         case IDX_CTL_CR0_REG:
diff --git a/target/i386/helper.c b/target/i386/helper.c
index c3a6e4fabe..fa2a1dcdda 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -544,6 +544,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, int flags)
         for(i = 0; i < 8; i++) {
             fptag |= ((!env->fptags[i]) << i);
         }
+        update_mxcsr_from_sse_status(env);
         qemu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
                      env->fpuc,
                      (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
diff --git a/target/i386/helper.h b/target/i386/helper.h
index 8f9e1905c3..c2ae2f7e61 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -207,6 +207,7 @@ DEF_HELPER_FLAGS_2(pext, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 /* MMX/SSE */
 
 DEF_HELPER_2(ldmxcsr, void, env, i32)
+DEF_HELPER_1(update_mxcsr, void, env)
 DEF_HELPER_1(enter_mmx, void, env)
 DEF_HELPER_1(emms, void, env)
 DEF_HELPER_3(movq, void, env, ptr, ptr)
diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h
index 14f2b16abd..c7614f8b0b 100644
--- a/target/i386/ops_sse.h
+++ b/target/i386/ops_sse.h
@@ -843,6 +843,7 @@ int64_t helper_cvttsd2sq(CPUX86State *env, ZMMReg *s)
 
 void helper_rsqrtps(CPUX86State *env, ZMMReg *d, ZMMReg *s)
 {
+    uint8_t old_flags = get_float_exception_flags(&env->sse_status);
     d->ZMM_S(0) = float32_div(float32_one,
                               float32_sqrt(s->ZMM_S(0), &env->sse_status),
                               &env->sse_status);
@@ -855,26 +856,33 @@ void helper_rsqrtps(CPUX86State *env, ZMMReg *d, ZMMReg *s)
     d->ZMM_S(3) = float32_div(float32_one,
                               float32_sqrt(s->ZMM_S(3), &env->sse_status),
                               &env->sse_status);
+    set_float_exception_flags(old_flags, &env->sse_status);
 }
 
 void helper_rsqrtss(CPUX86State *env, ZMMReg *d, ZMMReg *s)
 {
+    uint8_t old_flags = get_float_exception_flags(&env->sse_status);
     d->ZMM_S(0) = float32_div(float32_one,
                               float32_sqrt(s->ZMM_S(0), &env->sse_status),
                               &env->sse_status);
+    set_float_exception_flags(old_flags, &env->sse_status);
 }
 
 void helper_rcpps(CPUX86State *env, ZMMReg *d, ZMMReg *s)
 {
+    uint8_t old_flags = get_float_exception_flags(&env->sse_status);
     d->ZMM_S(0) = float32_div(float32_one, s->ZMM_S(0), &env->sse_status);
     d->ZMM_S(1) = float32_div(float32_one, s->ZMM_S(1), &env->sse_status);
     d->ZMM_S(2) = float32_div(float32_one, s->ZMM_S(2), &env->sse_status);
     d->ZMM_S(3) = float32_div(float32_one, s->ZMM_S(3), &env->sse_status);
+    set_float_exception_flags(old_flags, &env->sse_status);
 }
 
 void helper_rcpss(CPUX86State *env, ZMMReg *d, ZMMReg *s)
 {
+    uint8_t old_flags = get_float_exception_flags(&env->sse_status);
     d->ZMM_S(0) = float32_div(float32_one, s->ZMM_S(0), &env->sse_status);
+    set_float_exception_flags(old_flags, &env->sse_status);
 }
 
 static inline uint64_t helper_extrq(uint64_t src, int shift, int len)
@@ -1764,6 +1772,7 @@ void glue(helper_phminposuw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
 void glue(helper_roundps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
                                   uint32_t mode)
 {
+    uint8_t old_flags = get_float_exception_flags(&env->sse_status);
     signed char prev_rounding_mode;
 
     prev_rounding_mode = env->sse_status.float_rounding_mode;
@@ -1789,19 +1798,18 @@ void glue(helper_roundps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
     d->ZMM_S(2) = float32_round_to_int(s->ZMM_S(2), &env->sse_status);
     d->ZMM_S(3) = float32_round_to_int(s->ZMM_S(3), &env->sse_status);
 
-#if 0 /* TODO */
-    if (mode & (1 << 3)) {
+    if (mode & (1 << 3) && !(old_flags & float_flag_inexact)) {
         set_float_exception_flags(get_float_exception_flags(&env->sse_status) &
                                   ~float_flag_inexact,
                                   &env->sse_status);
     }
-#endif
     env->sse_status.float_rounding_mode = prev_rounding_mode;
 }
 
 void glue(helper_roundpd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
                                   uint32_t mode)
 {
+    uint8_t old_flags = get_float_exception_flags(&env->sse_status);
     signed char prev_rounding_mode;
 
     prev_rounding_mode = env->sse_status.float_rounding_mode;
@@ -1825,19 +1833,18 @@ void glue(helper_roundpd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
     d->ZMM_D(0) = float64_round_to_int(s->ZMM_D(0), &env->sse_status);
     d->ZMM_D(1) = float64_round_to_int(s->ZMM_D(1), &env->sse_status);
 
-#if 0 /* TODO */
-    if (mode & (1 << 3)) {
+    if (mode & (1 << 3) && !(old_flags & float_flag_inexact)) {
         set_float_exception_flags(get_float_exception_flags(&env->sse_status) &
                                   ~float_flag_inexact,
                                   &env->sse_status);
     }
-#endif
     env->sse_status.float_rounding_mode = prev_rounding_mode;
 }
 
 void glue(helper_roundss, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
                                   uint32_t mode)
 {
+    uint8_t old_flags = get_float_exception_flags(&env->sse_status);
     signed char prev_rounding_mode;
 
     prev_rounding_mode = env->sse_status.float_rounding_mode;
@@ -1860,19 +1867,18 @@ void glue(helper_roundss, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
 
     d->ZMM_S(0) = float32_round_to_int(s->ZMM_S(0), &env->sse_status);
 
-#if 0 /* TODO */
-    if (mode & (1 << 3)) {
+    if (mode & (1 << 3) && !(old_flags & float_flag_inexact)) {
         set_float_exception_flags(get_float_exception_flags(&env->sse_status) &
                                   ~float_flag_inexact,
                                   &env->sse_status);
     }
-#endif
     env->sse_status.float_rounding_mode = prev_rounding_mode;
 }
 
 void glue(helper_roundsd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
                                   uint32_t mode)
 {
+    uint8_t old_flags = get_float_exception_flags(&env->sse_status);
     signed char prev_rounding_mode;
 
     prev_rounding_mode = env->sse_status.float_rounding_mode;
@@ -1895,13 +1901,11 @@ void glue(helper_roundsd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
 
     d->ZMM_D(0) = float64_round_to_int(s->ZMM_D(0), &env->sse_status);
 
-#if 0 /* TODO */
-    if (mode & (1 << 3)) {
+    if (mode & (1 << 3) && !(old_flags & float_flag_inexact)) {
         set_float_exception_flags(get_float_exception_flags(&env->sse_status) &
                                   ~float_flag_inexact,
                                   &env->sse_status);
     }
-#endif
     env->sse_status.float_rounding_mode = prev_rounding_mode;
 }
 
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 5e5dbb41b0..b3fea54411 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -8157,6 +8157,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                 break;
             }
+            gen_helper_update_mxcsr(cpu_env);
             gen_lea_modrm(env, s, modrm);
             tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, mxcsr));
             gen_op_st_v(s, MO_32, s->T0, s->A0);
diff --git a/tests/tcg/i386/Makefile.target b/tests/tcg/i386/Makefile.target
index 1a6463a7dc..a66232a67d 100644
--- a/tests/tcg/i386/Makefile.target
+++ b/tests/tcg/i386/Makefile.target
@@ -10,6 +10,10 @@ ALL_X86_TESTS=$(I386_SRCS:.c=)
 SKIP_I386_TESTS=test-i386-ssse3
 X86_64_TESTS:=$(filter test-i386-ssse3, $(ALL_X86_TESTS))
 
+test-i386-sse-exceptions: CFLAGS += -msse4.1 -mfpmath=sse
+run-test-i386-sse-exceptions: QEMU_OPTS += -cpu max
+run-plugin-test-i386-sse-exceptions-%: QEMU_OPTS += -cpu max
+
 test-i386-pcmpistri: CFLAGS += -msse4.2
 run-test-i386-pcmpistri: QEMU_OPTS += -cpu max
 run-plugin-test-i386-pcmpistri-%: QEMU_OPTS += -cpu max
diff --git a/tests/tcg/i386/test-i386-sse-exceptions.c b/tests/tcg/i386/test-i386-sse-exceptions.c
new file mode 100644
index 0000000000..a104f46c11
--- /dev/null
+++ b/tests/tcg/i386/test-i386-sse-exceptions.c
@@ -0,0 +1,813 @@
+/* Test SSE exceptions.  */
+
+#include <float.h>
+#include <stdint.h>
+#include <stdio.h>
+
+volatile float f_res;
+volatile double d_res;
+
+volatile float f_snan = __builtin_nansf("");
+volatile float f_half = 0.5f;
+volatile float f_third = 1.0f / 3.0f;
+volatile float f_nan = __builtin_nanl("");
+volatile float f_inf = __builtin_inff();
+volatile float f_ninf = -__builtin_inff();
+volatile float f_one = 1.0f;
+volatile float f_two = 2.0f;
+volatile float f_zero = 0.0f;
+volatile float f_nzero = -0.0f;
+volatile float f_min = FLT_MIN;
+volatile float f_true_min = 0x1p-149f;
+volatile float f_max = FLT_MAX;
+volatile float f_nmax = -FLT_MAX;
+
+volatile double d_snan = __builtin_nans("");
+volatile double d_half = 0.5;
+volatile double d_third = 1.0 / 3.0;
+volatile double d_nan = __builtin_nan("");
+volatile double d_inf = __builtin_inf();
+volatile double d_ninf = -__builtin_inf();
+volatile double d_one = 1.0;
+volatile double d_two = 2.0;
+volatile double d_zero = 0.0;
+volatile double d_nzero = -0.0;
+volatile double d_min = DBL_MIN;
+volatile double d_true_min = 0x1p-1074;
+volatile double d_max = DBL_MAX;
+volatile double d_nmax = -DBL_MAX;
+
+volatile int32_t i32_max = INT32_MAX;
+
+#define IE (1 << 0)
+#define ZE (1 << 2)
+#define OE (1 << 3)
+#define UE (1 << 4)
+#define PE (1 << 5)
+#define EXC (IE | ZE | OE | UE | PE)
+
+uint32_t mxcsr_default = 0x1f80;
+uint32_t mxcsr_ftz = 0x9f80;
+
+int main(void)
+{
+    uint32_t mxcsr;
+    int32_t i32_res;
+    int ret = 0;
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = f_snan;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: widen float snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = d_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: narrow float underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = d_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: narrow float overflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: narrow float inexact\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = d_snan;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: narrow float snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundss $4, %0, %0" : "=x" (f_res) : "0" (f_min));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: roundss min\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundss $12, %0, %0" : "=x" (f_res) : "0" (f_min));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: roundss no-inexact min\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundss $4, %0, %0" : "=x" (f_res) : "0" (f_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: roundss snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundss $12, %0, %0" : "=x" (f_res) : "0" (f_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: roundss no-inexact snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundsd $4, %0, %0" : "=x" (d_res) : "0" (d_min));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: roundsd min\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundsd $12, %0, %0" : "=x" (d_res) : "0" (d_min));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: roundsd no-inexact min\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundsd $4, %0, %0" : "=x" (d_res) : "0" (d_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: roundsd snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundsd $12, %0, %0" : "=x" (d_res) : "0" (d_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: roundsd no-inexact snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("comiss %1, %0" : : "x" (f_nan), "x" (f_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: comiss nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("ucomiss %1, %0" : : "x" (f_nan), "x" (f_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: ucomiss nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("ucomiss %1, %0" : : "x" (f_snan), "x" (f_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: ucomiss snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("comisd %1, %0" : : "x" (d_nan), "x" (d_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: comisd nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("ucomisd %1, %0" : : "x" (d_nan), "x" (d_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: ucomisd nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("ucomisd %1, %0" : : "x" (d_snan), "x" (d_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: ucomisd snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max + f_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: float add overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max + f_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: float add inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_inf + f_ninf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float add inf -inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_snan + f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float add snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    f_res = f_true_min + f_true_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float add FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max + d_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: double add overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max + d_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: double add inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_inf + d_ninf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double add inf -inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_snan + d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double add snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    d_res = d_true_min + d_true_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double add FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max - f_nmax;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: float sub overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max - f_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: float sub inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_inf - f_inf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float sub inf inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_snan - f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float sub snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    f_res = f_min - f_true_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float sub FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max - d_nmax;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: double sub overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max - d_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: double sub inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_inf - d_inf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double sub inf inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_snan - d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double sub snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    d_res = d_min - d_true_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double sub FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max * f_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: float mul overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_third * f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: float mul inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_min * f_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float mul underflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_inf * f_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float mul inf 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_snan * f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float mul snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    f_res = f_min * f_half;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float mul FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max * d_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: double mul overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_third * d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: double mul inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_min * d_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double mul underflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_inf * d_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double mul inf 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_snan * d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double mul snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    d_res = d_min * d_half;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double mul FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max / f_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: float div overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_one / f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: float div inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_min / f_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float div underflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_one / f_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != ZE) {
+        printf("FAIL: float div 1 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_inf / f_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: float div inf 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_nan / f_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: float div nan 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_zero / f_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float div 0 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_inf / f_inf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float div inf inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_snan / f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float div snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    f_res = f_min / f_two;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float div FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max / d_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: double div overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_one / d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: double div inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_min / d_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double div underflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_one / d_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != ZE) {
+        printf("FAIL: double div 1 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_inf / d_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: double div inf 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_nan / d_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: double div nan 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_zero / d_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double div 0 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_inf / d_inf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double div inf inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_snan / d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double div snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    d_res = d_min / d_two;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double div FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) : "0" (f_max));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: sqrtss inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) : "0" (f_nmax));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtss -max\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) : "0" (f_ninf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtss -inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) : "0" (f_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtss snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) : "0" (f_nzero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: sqrtss -0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) :
+                      "0" (-__builtin_nanf("")));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: sqrtss -nan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) : "0" (d_max));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: sqrtsd inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) : "0" (d_nmax));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtsd -max\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) : "0" (d_ninf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtsd -inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) : "0" (d_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtsd snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) : "0" (d_nzero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: sqrtsd -0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) :
+                      "0" (-__builtin_nan("")));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: sqrtsd -nan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("maxss %1, %0" : : "x" (f_nan), "x" (f_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: maxss nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("minss %1, %0" : : "x" (f_nan), "x" (f_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: minss nan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("maxsd %1, %0" : : "x" (d_nan), "x" (d_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: maxsd nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("minsd %1, %0" : : "x" (d_nan), "x" (d_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: minsd nan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtsi2ss %1, %0" : "=x" (f_res) : "m" (i32_max));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: cvtsi2ss inexact\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtsi2sd %1, %0" : "=x" (d_res) : "m" (i32_max));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: cvtsi2sd exact\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtss2si %1, %0" : "=r" (i32_res) : "x" (1.5f));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: cvtss2si inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtss2si %1, %0" : "=r" (i32_res) : "x" (0x1p31f));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvtss2si 0x1p31\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtss2si %1, %0" : "=r" (i32_res) : "x" (f_inf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvtss2si inf\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtsd2si %1, %0" : "=r" (i32_res) : "x" (1.5));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: cvtsd2si inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtsd2si %1, %0" : "=r" (i32_res) : "x" (0x1p31));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvtsd2si 0x1p31\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtsd2si %1, %0" : "=r" (i32_res) : "x" (d_inf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvtsd2si inf\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttss2si %1, %0" : "=r" (i32_res) : "x" (1.5f));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: cvttss2si inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttss2si %1, %0" : "=r" (i32_res) : "x" (0x1p31f));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvttss2si 0x1p31\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttss2si %1, %0" : "=r" (i32_res) : "x" (f_inf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvttss2si inf\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttsd2si %1, %0" : "=r" (i32_res) : "x" (1.5));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: cvttsd2si inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttsd2si %1, %0" : "=r" (i32_res) : "x" (0x1p31));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvttsd2si 0x1p31\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttsd2si %1, %0" : "=r" (i32_res) : "x" (d_inf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvttsd2si inf\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("rcpss %0, %0" : "=x" (f_res) : "0" (f_snan));
+    f_res += f_one;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: rcpss snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("rsqrtss %0, %0" : "=x" (f_res) : "0" (f_snan));
+    f_res += f_one;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: rsqrtss snan\n");
+        ret = 1;
+    }
+
+    return ret;
+}
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 10/53] KVM: add support for AMD nested live migration
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (8 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 09/53] target/i386: fix IEEE SSE floating-point exception raising Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 11/53] coverity: provide Coverity-friendly MIN_CONST and MAX_CONST Paolo Bonzini
                   ` (44 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel

Support for nested guest live migration is part of Linux 5.8, add the
corresponding code to QEMU.  The migration format consists of a few
flags, is an opaque 4k blob.

The blob is in VMCB format (the control area represents the L1 VMCB
control fields, the save area represents the pre-vmentry state; KVM does
not use the host save area since the AMD manual allows that) but QEMU
does not really care about that.  However, the flags need to be
copied to hflags/hflags2 and back.

In addition, support for retrieving and setting the AMD nested virtualization
states allows the L1 guest to be reset while running a nested guest, but
a small bug in CPU reset needs to be fixed for that to work.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.c     |  1 +
 target/i386/cpu.h     |  5 +++++
 target/i386/kvm.c     | 42 ++++++++++++++++++++++++++++++++++--------
 target/i386/machine.c | 31 ++++++++++++++++++++++++++++++-
 4 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 36cbd3d027..f1cbac2fb5 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5987,6 +5987,7 @@ static void x86_cpu_reset(DeviceState *dev)
     /* init to reset state */
 
     env->hflags2 |= HF2_GIF_MASK;
+    env->hflags &= ~HF_GUEST_MASK;
 
     cpu_x86_update_cr0(env, 0x60000010);
     env->a20_mask = ~0x0;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 06b2e3a5c6..9284f96896 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2118,6 +2118,11 @@ static inline bool cpu_has_vmx(CPUX86State *env)
     return env->features[FEAT_1_ECX] & CPUID_EXT_VMX;
 }
 
+static inline bool cpu_has_svm(CPUX86State *env)
+{
+    return env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM;
+}
+
 /*
  * In order for a vCPU to enter VMX operation it must have CR4.VMXE set.
  * Since it was set, CR4.VMXE must remain set as long as vCPU is in
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 6adbff3d74..2b6b7443d2 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1840,16 +1840,18 @@ int kvm_arch_init_vcpu(CPUState *cs)
     if (max_nested_state_len > 0) {
         assert(max_nested_state_len >= offsetof(struct kvm_nested_state, data));
 
-        if (cpu_has_vmx(env)) {
+        if (cpu_has_vmx(env) || cpu_has_svm(env)) {
             struct kvm_vmx_nested_state_hdr *vmx_hdr;
 
             env->nested_state = g_malloc0(max_nested_state_len);
             env->nested_state->size = max_nested_state_len;
             env->nested_state->format = KVM_STATE_NESTED_FORMAT_VMX;
 
-            vmx_hdr = &env->nested_state->hdr.vmx;
-            vmx_hdr->vmxon_pa = -1ull;
-            vmx_hdr->vmcs12_pa = -1ull;
+            if (cpu_has_vmx(env)) {
+                    vmx_hdr = &env->nested_state->hdr.vmx;
+                    vmx_hdr->vmxon_pa = -1ull;
+                    vmx_hdr->vmcs12_pa = -1ull;
+            }
         }
     }
 
@@ -3873,6 +3875,20 @@ static int kvm_put_nested_state(X86CPU *cpu)
         return 0;
     }
 
+    /*
+     * Copy flags that are affected by reset from env->hflags and env->hflags2.
+     */
+    if (env->hflags & HF_GUEST_MASK) {
+        env->nested_state->flags |= KVM_STATE_NESTED_GUEST_MODE;
+    } else {
+        env->nested_state->flags &= ~KVM_STATE_NESTED_GUEST_MODE;
+    }
+    if (env->hflags2 & HF2_GIF_MASK) {
+        env->nested_state->flags |= KVM_STATE_NESTED_GIF_SET;
+    } else {
+        env->nested_state->flags &= ~KVM_STATE_NESTED_GIF_SET;
+    }
+
     assert(env->nested_state->size <= max_nested_state_len);
     return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_NESTED_STATE, env->nested_state);
 }
@@ -3901,11 +3917,19 @@ static int kvm_get_nested_state(X86CPU *cpu)
         return ret;
     }
 
+    /*
+     * Copy flags that are affected by reset to env->hflags and env->hflags2.
+     */
     if (env->nested_state->flags & KVM_STATE_NESTED_GUEST_MODE) {
         env->hflags |= HF_GUEST_MASK;
     } else {
         env->hflags &= ~HF_GUEST_MASK;
     }
+    if (env->nested_state->flags & KVM_STATE_NESTED_GIF_SET) {
+        env->hflags2 |= HF2_GIF_MASK;
+    } else {
+        env->hflags2 &= ~HF2_GIF_MASK;
+    }
 
     return ret;
 }
@@ -3917,6 +3941,12 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
 
     assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu));
 
+    /* must be before kvm_put_nested_state so that EFER.SVME is set */
+    ret = kvm_put_sregs(x86_cpu);
+    if (ret < 0) {
+        return ret;
+    }
+
     if (level >= KVM_PUT_RESET_STATE) {
         ret = kvm_put_nested_state(x86_cpu);
         if (ret < 0) {
@@ -3950,10 +3980,6 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
     if (ret < 0) {
         return ret;
     }
-    ret = kvm_put_sregs(x86_cpu);
-    if (ret < 0) {
-        return ret;
-    }
     /* must be before kvm_put_msrs */
     ret = kvm_inject_mce_oldstyle(x86_cpu);
     if (ret < 0) {
diff --git a/target/i386/machine.c b/target/i386/machine.c
index 0c96531a56..b1acf7d0ef 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -1071,13 +1071,41 @@ static const VMStateDescription vmstate_vmx_nested_state = {
     }
 };
 
+static bool svm_nested_state_needed(void *opaque)
+{
+    struct kvm_nested_state *nested_state = opaque;
+
+    /*
+     * HF_GUEST_MASK and HF2_GIF_MASK are already serialized
+     * via hflags and hflags2, all that's left is the opaque
+     * nested state blob.
+     */
+    return (nested_state->format == KVM_STATE_NESTED_FORMAT_SVM &&
+            nested_state->size > offsetof(struct kvm_nested_state, data));
+}
+
+static const VMStateDescription vmstate_svm_nested_state = {
+    .name = "cpu/kvm_nested_state/svm",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = svm_nested_state_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_U64(hdr.svm.vmcb_pa, struct kvm_nested_state),
+        VMSTATE_UINT8_ARRAY(data.svm[0].vmcb12,
+                            struct kvm_nested_state,
+                            KVM_STATE_NESTED_SVM_VMCB_SIZE),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static bool nested_state_needed(void *opaque)
 {
     X86CPU *cpu = opaque;
     CPUX86State *env = &cpu->env;
 
     return (env->nested_state &&
-            vmx_nested_state_needed(env->nested_state));
+            (vmx_nested_state_needed(env->nested_state) ||
+             svm_nested_state_needed(env->nested_state)));
 }
 
 static int nested_state_post_load(void *opaque, int version_id)
@@ -1139,6 +1167,7 @@ static const VMStateDescription vmstate_kvm_nested_state = {
     },
     .subsections = (const VMStateDescription*[]) {
         &vmstate_vmx_nested_state,
+        &vmstate_svm_nested_state,
         NULL
     }
 };
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 11/53] coverity: provide Coverity-friendly MIN_CONST and MAX_CONST
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (9 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 10/53] KVM: add support for AMD nested live migration Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 12/53] i386: hvf: Set env->eip in macvm_set_rip() Paolo Bonzini
                   ` (43 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Eric Blake <eblake@redhat.com>

Coverity has problems seeing through __builtin_choose_expr, which
result in it abandoning analysis of later functions that utilize a
definition that used MIN_CONST or MAX_CONST, such as in qemu-file.c:

 50    DECLARE_BITMAP(may_free, MAX_IOV_SIZE);

CID 1429992 (#1 of 1): Unrecoverable parse warning (PARSE_ERROR)1.
expr_not_constant: expression must have a constant value

As has been done in the past (see 07d66672), it's okay to dumb things
down when compiling for static analyzers.  (Of course, now the
syntax-checker has a false positive on our reference to
__COVERITY__...)

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Fixes: CID 1429992, CID 1429995, CID 1429997, CID 1429999
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20200629162804.1096180-1-eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/osdep.h | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 0d26a1b9bd..0fc206ae61 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -250,7 +250,8 @@ extern int daemon(int, int);
  * Note that neither form is usable as an #if condition; if you truly
  * need to write conditional code that depends on a minimum or maximum
  * determined by the pre-processor instead of the compiler, you'll
- * have to open-code it.
+ * have to open-code it.  Sadly, Coverity is severely confused by the
+ * constant variants, so we have to dumb things down there.
  */
 #undef MIN
 #define MIN(a, b)                                       \
@@ -258,22 +259,28 @@ extern int daemon(int, int);
         typeof(1 ? (a) : (b)) _a = (a), _b = (b);       \
         _a < _b ? _a : _b;                              \
     })
-#define MIN_CONST(a, b)                                         \
-    __builtin_choose_expr(                                      \
-        __builtin_constant_p(a) && __builtin_constant_p(b),     \
-        (a) < (b) ? (a) : (b),                                  \
-        ((void)0))
 #undef MAX
 #define MAX(a, b)                                       \
     ({                                                  \
         typeof(1 ? (a) : (b)) _a = (a), _b = (b);       \
         _a > _b ? _a : _b;                              \
     })
-#define MAX_CONST(a, b)                                         \
+
+#ifdef __COVERITY__
+# define MIN_CONST(a, b) ((a) < (b) ? (a) : (b))
+# define MAX_CONST(a, b) ((a) > (b) ? (a) : (b))
+#else
+# define MIN_CONST(a, b)                                        \
+    __builtin_choose_expr(                                      \
+        __builtin_constant_p(a) && __builtin_constant_p(b),     \
+        (a) < (b) ? (a) : (b),                                  \
+        ((void)0))
+# define MAX_CONST(a, b)                                        \
     __builtin_choose_expr(                                      \
         __builtin_constant_p(a) && __builtin_constant_p(b),     \
         (a) > (b) ? (a) : (b),                                  \
         ((void)0))
+#endif
 
 /*
  * Minimum function that returns zero only if both values are zero.
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 12/53] i386: hvf: Set env->eip in macvm_set_rip()
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (10 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 11/53] coverity: provide Coverity-friendly MIN_CONST and MAX_CONST Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 13/53] i386: hvf: Move synchronize functions to sysemu Paolo Bonzini
                   ` (42 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Roman Bolshakov, Cameron Esfahani

From: Roman Bolshakov <r.bolshakov@yadro.com>

cpu_synchronize_state() is currently no-op for hvf but BIOS will hang in
vAPIC option ROM when cpu_synchronize_state() is wired to
hvf_cpu_synchronize_state().

cpu_synchronize_state() state is called from vapic_write() during option
ROM initialization. It sets dirty flag on the cpu. macvm_set_rip() is
then invoked to advance IP after the I/O write to vAPIC port.

macvm_set_rip() only modifies VMCS, it doesn't change env->eip.
Therefore on the next iteration of vCPU loop, vcpu_dirty flag is checked
and hvf_put_registers() overwrites correct RIP in VMCS with the value of
env->eip that points to the I/O write instruction. Execution of the CPU
gets stuck on the instruction.

The issue can be avoided if eip doesn't contain stale value when dirty
flag is set on cpu.

Cc: Cameron Esfahani <dirty@apple.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Message-Id: <20200630102824.77604-2-r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/hvf/vmx.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h
index ce2a1532d5..1e8b29bf7d 100644
--- a/target/i386/hvf/vmx.h
+++ b/target/i386/hvf/vmx.h
@@ -173,6 +173,7 @@ static inline void macvm_set_rip(CPUState *cpu, uint64_t rip)
 
     /* BUG, should take considering overlap.. */
     wreg(cpu->hvf_fd, HV_X86_RIP, rip);
+    env->eip = rip;
 
     /* after moving forward in rip, we need to clean INTERRUPTABILITY */
    val = rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 13/53] i386: hvf: Move synchronize functions to sysemu
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (11 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 12/53] i386: hvf: Set env->eip in macvm_set_rip() Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 14/53] i386: hvf: Add hvf_cpu_synchronize_pre_loadvm() Paolo Bonzini
                   ` (41 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Roman Bolshakov, Cameron Esfahani

From: Roman Bolshakov <r.bolshakov@yadro.com>

Cc: Cameron Esfahani <dirty@apple.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Message-Id: <20200630102824.77604-3-r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus.c                    | 12 ------------
 include/sysemu/hw_accel.h | 10 ++++++++++
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/cpus.c b/cpus.c
index 41d1c5099f..d94456ed29 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1017,10 +1017,6 @@ void cpu_synchronize_all_states(void)
 
     CPU_FOREACH(cpu) {
         cpu_synchronize_state(cpu);
-        /* TODO: move to cpu_synchronize_state() */
-        if (hvf_enabled()) {
-            hvf_cpu_synchronize_state(cpu);
-        }
     }
 }
 
@@ -1030,10 +1026,6 @@ void cpu_synchronize_all_post_reset(void)
 
     CPU_FOREACH(cpu) {
         cpu_synchronize_post_reset(cpu);
-        /* TODO: move to cpu_synchronize_post_reset() */
-        if (hvf_enabled()) {
-            hvf_cpu_synchronize_post_reset(cpu);
-        }
     }
 }
 
@@ -1043,10 +1035,6 @@ void cpu_synchronize_all_post_init(void)
 
     CPU_FOREACH(cpu) {
         cpu_synchronize_post_init(cpu);
-        /* TODO: move to cpu_synchronize_post_init() */
-        if (hvf_enabled()) {
-            hvf_cpu_synchronize_post_init(cpu);
-        }
     }
 }
 
diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h
index 0ec2372477..80bce75921 100644
--- a/include/sysemu/hw_accel.h
+++ b/include/sysemu/hw_accel.h
@@ -14,6 +14,7 @@
 #include "hw/core/cpu.h"
 #include "sysemu/hax.h"
 #include "sysemu/kvm.h"
+#include "sysemu/hvf.h"
 #include "sysemu/whpx.h"
 
 static inline void cpu_synchronize_state(CPUState *cpu)
@@ -24,6 +25,9 @@ static inline void cpu_synchronize_state(CPUState *cpu)
     if (hax_enabled()) {
         hax_cpu_synchronize_state(cpu);
     }
+    if (hvf_enabled()) {
+        hvf_cpu_synchronize_state(cpu);
+    }
     if (whpx_enabled()) {
         whpx_cpu_synchronize_state(cpu);
     }
@@ -37,6 +41,9 @@ static inline void cpu_synchronize_post_reset(CPUState *cpu)
     if (hax_enabled()) {
         hax_cpu_synchronize_post_reset(cpu);
     }
+    if (hvf_enabled()) {
+        hvf_cpu_synchronize_post_reset(cpu);
+    }
     if (whpx_enabled()) {
         whpx_cpu_synchronize_post_reset(cpu);
     }
@@ -50,6 +57,9 @@ static inline void cpu_synchronize_post_init(CPUState *cpu)
     if (hax_enabled()) {
         hax_cpu_synchronize_post_init(cpu);
     }
+    if (hvf_enabled()) {
+        hvf_cpu_synchronize_post_init(cpu);
+    }
     if (whpx_enabled()) {
         whpx_cpu_synchronize_post_init(cpu);
     }
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 14/53] i386: hvf: Add hvf_cpu_synchronize_pre_loadvm()
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (12 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 13/53] i386: hvf: Move synchronize functions to sysemu Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 15/53] i386: hvf: Make long mode enter and exit clearer Paolo Bonzini
                   ` (40 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Roman Bolshakov, Cameron Esfahani

From: Roman Bolshakov <r.bolshakov@yadro.com>

hvf lacks an implementation of cpu_synchronize_pre_loadvm().

Cc: Cameron Esfahani <dirty@apple.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Message-Id: <20200630102824.77604-4-r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/sysemu/hvf.h      |  1 +
 include/sysemu/hw_accel.h |  3 +++
 target/i386/hvf/hvf.c     | 11 +++++++++++
 3 files changed, 15 insertions(+)

diff --git a/include/sysemu/hvf.h b/include/sysemu/hvf.h
index 5214ed5202..1d40a8ec01 100644
--- a/include/sysemu/hvf.h
+++ b/include/sysemu/hvf.h
@@ -28,6 +28,7 @@ int hvf_vcpu_exec(CPUState *);
 void hvf_cpu_synchronize_state(CPUState *);
 void hvf_cpu_synchronize_post_reset(CPUState *);
 void hvf_cpu_synchronize_post_init(CPUState *);
+void hvf_cpu_synchronize_pre_loadvm(CPUState *);
 void hvf_vcpu_destroy(CPUState *);
 void hvf_reset_vcpu(CPUState *);
 
diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h
index 80bce75921..e128f8b06b 100644
--- a/include/sysemu/hw_accel.h
+++ b/include/sysemu/hw_accel.h
@@ -73,6 +73,9 @@ static inline void cpu_synchronize_pre_loadvm(CPUState *cpu)
     if (hax_enabled()) {
         hax_cpu_synchronize_pre_loadvm(cpu);
     }
+    if (hvf_enabled()) {
+        hvf_cpu_synchronize_pre_loadvm(cpu);
+    }
     if (whpx_enabled()) {
         whpx_cpu_synchronize_pre_loadvm(cpu);
     }
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index be016b951a..efe9802962 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -325,6 +325,17 @@ void hvf_cpu_synchronize_post_init(CPUState *cpu_state)
     run_on_cpu(cpu_state, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
 }
 
+static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
+                                              run_on_cpu_data arg)
+{
+    cpu->vcpu_dirty = true;
+}
+
+void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
+{
+    run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
+}
+
 static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
 {
     int read, write;
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 15/53] i386: hvf: Make long mode enter and exit clearer
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (13 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 14/53] i386: hvf: Add hvf_cpu_synchronize_pre_loadvm() Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 16/53] i386: hvf: Move Guest LMA reset to macvm_set_cr0() Paolo Bonzini
                   ` (39 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Roman Bolshakov, Cameron Esfahani

From: Cameron Esfahani <dirty@apple.com>

Intel SDM "9.8.5 Initializing IA-32e Mode" and "9.8.5.4 Switching Out of
IA-32e Mode Operation" define activation and deactivation of long mode
only upon a change of CR0.PG but current code invokes exit_long_mode()
unconditionally until LME is cleared.

Signed-off-by: Cameron Esfahani <dirty@apple.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Message-Id: <20200630102824.77604-6-r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/hvf/vmx.h | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h
index 1e8b29bf7d..437238f11d 100644
--- a/target/i386/hvf/vmx.h
+++ b/target/i386/hvf/vmx.h
@@ -121,6 +121,7 @@ static inline void macvm_set_cr0(hv_vcpuid_t vcpu, uint64_t cr0)
     uint64_t pdpte[4] = {0, 0, 0, 0};
     uint64_t efer = rvmcs(vcpu, VMCS_GUEST_IA32_EFER);
     uint64_t old_cr0 = rvmcs(vcpu, VMCS_GUEST_CR0);
+    uint64_t changed_cr0 = old_cr0 ^ cr0;
     uint64_t mask = CR0_PG | CR0_CD | CR0_NW | CR0_NE | CR0_ET;
 
     if ((cr0 & CR0_PG) && (rvmcs(vcpu, VMCS_GUEST_CR4) & CR4_PAE) &&
@@ -138,11 +139,12 @@ static inline void macvm_set_cr0(hv_vcpuid_t vcpu, uint64_t cr0)
     wvmcs(vcpu, VMCS_CR0_SHADOW, cr0);
 
     if (efer & MSR_EFER_LME) {
-        if (!(old_cr0 & CR0_PG) && (cr0 & CR0_PG)) {
-            enter_long_mode(vcpu, cr0, efer);
-        }
-        if (/*(old_cr0 & CR0_PG) &&*/ !(cr0 & CR0_PG)) {
-            exit_long_mode(vcpu, cr0, efer);
+        if (changed_cr0 & CR0_PG) {
+            if (cr0 & CR0_PG) {
+                enter_long_mode(vcpu, cr0, efer);
+            } else {
+                exit_long_mode(vcpu, cr0, efer);
+            }
         }
     }
 
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 16/53] i386: hvf: Move Guest LMA reset to macvm_set_cr0()
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (14 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 15/53] i386: hvf: Make long mode enter and exit clearer Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 17/53] i386: hvf: Don't duplicate register reset Paolo Bonzini
                   ` (38 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Roman Bolshakov, Cameron Esfahani

From: Roman Bolshakov <r.bolshakov@yadro.com>

The only useful purpose of hvf_reset_vcpu() is to clear "IA-32e mode
guest" (LMA) VM-Entry control. But it can be moved to macvm_set_cr0()
which is indirectly used by post-init and post-reset to flush emulator
state. That enables clean removal of hvf_reset_vcpu().

LMA is set only if IA32_EFER.LME = 1, according to Intel SDM "9.8.5
Initializing IA-32e Mode" and "9.8.5.4 Switching Out of IA-32e Mode
Operation", otherwise the entry control can be safely cleared.

Cc: Cameron Esfahani <dirty@apple.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Message-Id: <20200630102824.77604-7-r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/hvf/hvf.c | 1 -
 target/i386/hvf/vmx.h | 4 ++++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index efe9802962..31980f9076 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -459,7 +459,6 @@ void hvf_reset_vcpu(CPUState *cpu) {
     /* TODO: this shouldn't be needed; there is already a call to
      * cpu_synchronize_all_post_reset in vl.c
      */
-    wvmcs(cpu->hvf_fd, VMCS_ENTRY_CTLS, 0);
     wvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER, 0);
 
     /* Initialize PDPTE */
diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h
index 437238f11d..75ba1e2a5f 100644
--- a/target/i386/hvf/vmx.h
+++ b/target/i386/hvf/vmx.h
@@ -123,6 +123,7 @@ static inline void macvm_set_cr0(hv_vcpuid_t vcpu, uint64_t cr0)
     uint64_t old_cr0 = rvmcs(vcpu, VMCS_GUEST_CR0);
     uint64_t changed_cr0 = old_cr0 ^ cr0;
     uint64_t mask = CR0_PG | CR0_CD | CR0_NW | CR0_NE | CR0_ET;
+    uint64_t entry_ctls;
 
     if ((cr0 & CR0_PG) && (rvmcs(vcpu, VMCS_GUEST_CR4) & CR4_PAE) &&
         !(efer & MSR_EFER_LME)) {
@@ -146,6 +147,9 @@ static inline void macvm_set_cr0(hv_vcpuid_t vcpu, uint64_t cr0)
                 exit_long_mode(vcpu, cr0, efer);
             }
         }
+    } else {
+        entry_ctls = rvmcs(vcpu, VMCS_ENTRY_CTLS);
+        wvmcs(vcpu, VMCS_ENTRY_CTLS, entry_ctls & ~VM_ENTRY_GUEST_LMA);
     }
 
     /* Filter new CR0 after we are finished examining it above. */
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 17/53] i386: hvf: Don't duplicate register reset
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (15 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 16/53] i386: hvf: Move Guest LMA reset to macvm_set_cr0() Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 18/53] i386: hvf: Clean up synchronize functions Paolo Bonzini
                   ` (37 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Roman Bolshakov, Cameron Esfahani

From: Roman Bolshakov <r.bolshakov@yadro.com>

hvf_reset_vcpu() duplicates actions performed by x86_cpu_reset(). The
difference is that hvf_reset_vcpu() stores initial values directly to
VMCS while x86_cpu_reset() stores it in CPUX86State and then
cpu_synchronize_all_post_init() or cpu_synchronize_all_post_reset()
flushes CPUX86State into VMCS. That makes hvf_reset_vcpu() a kind of
no-op.

Here's the trace of CPU state modifications during VM start:
  hvf_reset_vcpu (resets VMCS)
  cpu_synchronize_all_post_init (overwrites VMCS fields written by
                                 hvf_reset_vcpu())
  cpu_synchronize_all_states
  hvf_reset_vcpu (resets VMCS)
  cpu_synchronize_all_post_reset (overwrites VMCS fields written by
                                  hvf_reset_vcpu())

General purpose registers, system registers, segment descriptors, flags
and IP are set by hvf_put_segments() in post-init and post-reset,
therefore it's safe to remove them from hvf_reset_vcpu().

PDPTE initialization can be dropped because Intel SDM (26.3.1.6 Checks
on Guest Page-Directory-Pointer-Table Entries) doesn't require PDPTE to
be clear unless PAE is used: "A VM entry to a guest that does not use
PAE paging does not check the validity of any PDPTEs."
And if PAE is used, PDPTE's are initialized from CR3 in macvm_set_cr0().

Cc: Cameron Esfahani <dirty@apple.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Message-Id: <20200630102824.77604-8-r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/sysemu/hvf.h  |  1 -
 target/i386/cpu.c     |  3 --
 target/i386/hvf/hvf.c | 89 -------------------------------------------
 3 files changed, 93 deletions(-)

diff --git a/include/sysemu/hvf.h b/include/sysemu/hvf.h
index 1d40a8ec01..6d3ee4fdb7 100644
--- a/include/sysemu/hvf.h
+++ b/include/sysemu/hvf.h
@@ -30,7 +30,6 @@ void hvf_cpu_synchronize_post_reset(CPUState *);
 void hvf_cpu_synchronize_post_init(CPUState *);
 void hvf_cpu_synchronize_pre_loadvm(CPUState *);
 void hvf_vcpu_destroy(CPUState *);
-void hvf_reset_vcpu(CPUState *);
 
 #define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf")
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f1cbac2fb5..c44cc510e1 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6099,9 +6099,6 @@ static void x86_cpu_reset(DeviceState *dev)
     if (kvm_enabled()) {
         kvm_arch_reset_vcpu(cpu);
     }
-    else if (hvf_enabled()) {
-        hvf_reset_vcpu(s);
-    }
 #endif
 }
 
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 31980f9076..2a12867ef0 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -452,95 +452,6 @@ static MemoryListener hvf_memory_listener = {
     .log_sync = hvf_log_sync,
 };
 
-void hvf_reset_vcpu(CPUState *cpu) {
-    uint64_t pdpte[4] = {0, 0, 0, 0};
-    int i;
-
-    /* TODO: this shouldn't be needed; there is already a call to
-     * cpu_synchronize_all_post_reset in vl.c
-     */
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER, 0);
-
-    /* Initialize PDPTE */
-    for (i = 0; i < 4; i++) {
-        wvmcs(cpu->hvf_fd, VMCS_GUEST_PDPTE0 + i * 2, pdpte[i]);
-    }
-
-    macvm_set_cr0(cpu->hvf_fd, 0x60000010);
-
-    wvmcs(cpu->hvf_fd, VMCS_CR4_MASK, CR4_VMXE_MASK);
-    wvmcs(cpu->hvf_fd, VMCS_CR4_SHADOW, 0x0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_CR4, CR4_VMXE_MASK);
-
-    /* set VMCS guest state fields */
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_CS_SELECTOR, 0xf000);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_CS_LIMIT, 0xffff);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_CS_ACCESS_RIGHTS, 0x9b);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_CS_BASE, 0xffff0000);
-
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_DS_SELECTOR, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_DS_LIMIT, 0xffff);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_DS_ACCESS_RIGHTS, 0x93);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_DS_BASE, 0);
-
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_ES_SELECTOR, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_ES_LIMIT, 0xffff);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_ES_ACCESS_RIGHTS, 0x93);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_ES_BASE, 0);
-
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_SELECTOR, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_LIMIT, 0xffff);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_ACCESS_RIGHTS, 0x93);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE, 0);
-
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_SELECTOR, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_LIMIT, 0xffff);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_ACCESS_RIGHTS, 0x93);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE, 0);
-
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_SS_SELECTOR, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_SS_LIMIT, 0xffff);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_SS_ACCESS_RIGHTS, 0x93);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_SS_BASE, 0);
-
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_SELECTOR, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_LIMIT, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_ACCESS_RIGHTS, 0x10000);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_BASE, 0);
-
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_TR_SELECTOR, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_TR_LIMIT, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_TR_ACCESS_RIGHTS, 0x83);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_TR_BASE, 0);
-
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_LIMIT, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_BASE, 0);
-
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_LIMIT, 0);
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_BASE, 0);
-
-    /*wvmcs(cpu->hvf_fd, VMCS_GUEST_CR2, 0x0);*/
-    wvmcs(cpu->hvf_fd, VMCS_GUEST_CR3, 0x0);
-
-    wreg(cpu->hvf_fd, HV_X86_RIP, 0xfff0);
-    wreg(cpu->hvf_fd, HV_X86_RDX, 0x623);
-    wreg(cpu->hvf_fd, HV_X86_RFLAGS, 0x2);
-    wreg(cpu->hvf_fd, HV_X86_RSP, 0x0);
-    wreg(cpu->hvf_fd, HV_X86_RAX, 0x0);
-    wreg(cpu->hvf_fd, HV_X86_RBX, 0x0);
-    wreg(cpu->hvf_fd, HV_X86_RCX, 0x0);
-    wreg(cpu->hvf_fd, HV_X86_RSI, 0x0);
-    wreg(cpu->hvf_fd, HV_X86_RDI, 0x0);
-    wreg(cpu->hvf_fd, HV_X86_RBP, 0x0);
-
-    for (int i = 0; i < 8; i++) {
-        wreg(cpu->hvf_fd, HV_X86_R8 + i, 0x0);
-    }
-
-    hv_vcpu_invalidate_tlb(cpu->hvf_fd);
-    hv_vcpu_flush(cpu->hvf_fd);
-}
-
 void hvf_vcpu_destroy(CPUState *cpu)
 {
     X86CPU *x86_cpu = X86_CPU(cpu);
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 18/53] i386: hvf: Clean up synchronize functions
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (16 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 17/53] i386: hvf: Don't duplicate register reset Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 19/53] MAINTAINERS: Add Cameron as HVF co-maintainer Paolo Bonzini
                   ` (36 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Roman Bolshakov, Cameron Esfahani

From: Roman Bolshakov <r.bolshakov@yadro.com>

Make them more concise and consitent with the rest of the code in the
file and drop non-relevant TODO.

Cc: Cameron Esfahani <dirty@apple.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Message-Id: <20200630102824.77604-9-r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/hvf/hvf.c | 36 ++++++++++++++++--------------------
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 2a12867ef0..d81f569aed 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -282,47 +282,43 @@ void hvf_handle_io(CPUArchState *env, uint16_t port, void *buffer,
     }
 }
 
-/* TODO: synchronize vcpu state */
 static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
 {
-    CPUState *cpu_state = cpu;
-    if (cpu_state->vcpu_dirty == 0) {
-        hvf_get_registers(cpu_state);
+    if (!cpu->vcpu_dirty) {
+        hvf_get_registers(cpu);
+        cpu->vcpu_dirty = true;
     }
-
-    cpu_state->vcpu_dirty = 1;
 }
 
-void hvf_cpu_synchronize_state(CPUState *cpu_state)
+void hvf_cpu_synchronize_state(CPUState *cpu)
 {
-    if (cpu_state->vcpu_dirty == 0) {
-        run_on_cpu(cpu_state, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
+    if (!cpu->vcpu_dirty) {
+        run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
     }
 }
 
-static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
+static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
+                                              run_on_cpu_data arg)
 {
-    CPUState *cpu_state = cpu;
-    hvf_put_registers(cpu_state);
-    cpu_state->vcpu_dirty = false;
+    hvf_put_registers(cpu);
+    cpu->vcpu_dirty = false;
 }
 
-void hvf_cpu_synchronize_post_reset(CPUState *cpu_state)
+void hvf_cpu_synchronize_post_reset(CPUState *cpu)
 {
-    run_on_cpu(cpu_state, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
+    run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
 }
 
 static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
                                              run_on_cpu_data arg)
 {
-    CPUState *cpu_state = cpu;
-    hvf_put_registers(cpu_state);
-    cpu_state->vcpu_dirty = false;
+    hvf_put_registers(cpu);
+    cpu->vcpu_dirty = false;
 }
 
-void hvf_cpu_synchronize_post_init(CPUState *cpu_state)
+void hvf_cpu_synchronize_post_init(CPUState *cpu)
 {
-    run_on_cpu(cpu_state, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
+    run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
 }
 
 static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 19/53] MAINTAINERS: Add Cameron as HVF co-maintainer
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (17 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 18/53] i386: hvf: Clean up synchronize functions Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 20/53] MAINTAINERS: Fix KVM path expansion glob Paolo Bonzini
                   ` (35 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Roman Bolshakov, Cameron Esfahani

From: Roman Bolshakov <r.bolshakov@yadro.com>

Similar patch was sent a while ago but got lost.
While at it, add a status wiki page.

Cc: Cameron Esfahani <dirty@apple.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Message-Id: <20200624225850.16982-9-r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index dec252f38b..b6d4f62ba2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -417,7 +417,9 @@ F: target/i386/kvm.c
 F: scripts/kvm/vmxcap
 
 X86 HVF CPUs
+M: Cameron Esfahani <dirty@apple.com>
 M: Roman Bolshakov <r.bolshakov@yadro.com>
+W: https://wiki.qemu.org/Features/HVF
 S: Maintained
 F: accel/stubs/hvf-stub.c
 F: target/i386/hvf/
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 20/53] MAINTAINERS: Fix KVM path expansion glob
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (18 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 19/53] MAINTAINERS: Add Cameron as HVF co-maintainer Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 21/53] MAINTAINERS: Add an 'overall' entry for accelerators Paolo Bonzini
                   ` (34 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Richard Henderson, Thomas Huth,
	Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

The KVM files has been moved from target-ARCH to the target/ARCH/
folder in commit fcf5ef2a. Fix the pathname expansion.

Fixes: fcf5ef2a ("Move target-* CPU file into a target/ folder")
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index b6d4f62ba2..2593e0f20f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -362,7 +362,7 @@ Overall KVM CPUs
 M: Paolo Bonzini <pbonzini@redhat.com>
 L: kvm@vger.kernel.org
 S: Supported
-F: */kvm.*
+F: */*/kvm*
 F: accel/kvm/
 F: accel/stubs/kvm-stub.c
 F: include/hw/kvm/
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 21/53] MAINTAINERS: Add an 'overall' entry for accelerators
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (19 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 20/53] MAINTAINERS: Fix KVM path expansion glob Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 22/53] MAINTAINERS: Cover the HAX accelerator stub Paolo Bonzini
                   ` (33 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Richard Henderson, Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 MAINTAINERS | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2593e0f20f..d4d6dc7ef5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -416,6 +416,17 @@ S: Supported
 F: target/i386/kvm.c
 F: scripts/kvm/vmxcap
 
+Guest CPU Cores (other accelerators)
+------------------------------------
+Overall
+M: Richard Henderson <rth@twiddle.net>
+R: Paolo Bonzini <pbonzini@redhat.com>
+S: Maintained
+F: include/sysemu/accel.h
+F: accel/accel.c
+F: accel/Makefile.objs
+F: accel/stubs/Makefile.objs
+
 X86 HVF CPUs
 M: Cameron Esfahani <dirty@apple.com>
 M: Roman Bolshakov <r.bolshakov@yadro.com>
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 22/53] MAINTAINERS: Cover the HAX accelerator stub
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (20 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 21/53] MAINTAINERS: Add an 'overall' entry for accelerators Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 23/53] Makefile: Remove dangerous EOL trailing backslash Paolo Bonzini
                   ` (32 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

Cover accel/stubs/hax-stub.c in the HAXM section.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d4d6dc7ef5..72d5871f41 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -478,6 +478,7 @@ M: Colin Xu <colin.xu@intel.com>
 L: haxm-team@intel.com
 W: https://github.com/intel/haxm/issues
 S: Maintained
+F: accel/stubs/hax-stub.c
 F: include/sysemu/hax.h
 F: target/i386/hax-*
 
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 23/53] Makefile: Remove dangerous EOL trailing backslash
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (21 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 22/53] MAINTAINERS: Cover the HAX accelerator stub Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 24/53] Makefile: Write MINIKCONF variables as one entry per line Paolo Bonzini
                   ` (31 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Alistair Francis, Thomas Huth,
	Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

One might get caught trying to understand unexpected Makefile
behavior. Trailing backslash can help to split very long lines,
but are rather dangerous when nothing follow. Preserve other
developers debugging time by removing this one.

Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index b1b8a5a6d0..e7d8f1f027 100644
--- a/Makefile
+++ b/Makefile
@@ -420,7 +420,7 @@ MINIKCONF_ARGS = \
 
 MINIKCONF_INPUTS = $(SRC_PATH)/Kconfig.host $(SRC_PATH)/backends/Kconfig $(SRC_PATH)/hw/Kconfig
 MINIKCONF_DEPS = $(MINIKCONF_INPUTS) $(wildcard $(SRC_PATH)/hw/*/Kconfig)
-MINIKCONF = $(PYTHON) $(SRC_PATH)/scripts/minikconf.py \
+MINIKCONF = $(PYTHON) $(SRC_PATH)/scripts/minikconf.py
 
 $(SUBDIR_DEVICES_MAK): %/config-devices.mak: default-configs/%.mak $(MINIKCONF_DEPS) $(BUILD_DIR)/config-host.mak
 	$(call quiet-command, $(MINIKCONF) $(MINIKCONF_ARGS) > $@.tmp, "GEN", "$@.tmp")
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 24/53] Makefile: Write MINIKCONF variables as one entry per line
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (22 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 23/53] Makefile: Remove dangerous EOL trailing backslash Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 25/53] accel/Kconfig: Extract accel selectors into their own config Paolo Bonzini
                   ` (30 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Richard Henderson, Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

Having one entry per line helps reviews/refactors. As we are
going to modify the MINIKCONF variables, split them now to
ease further review.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 Makefile | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index e7d8f1f027..b96a2d8790 100644
--- a/Makefile
+++ b/Makefile
@@ -418,12 +418,16 @@ MINIKCONF_ARGS = \
     CONFIG_LINUX=$(CONFIG_LINUX) \
     CONFIG_PVRDMA=$(CONFIG_PVRDMA)
 
-MINIKCONF_INPUTS = $(SRC_PATH)/Kconfig.host $(SRC_PATH)/backends/Kconfig $(SRC_PATH)/hw/Kconfig
-MINIKCONF_DEPS = $(MINIKCONF_INPUTS) $(wildcard $(SRC_PATH)/hw/*/Kconfig)
+MINIKCONF_INPUTS = $(SRC_PATH)/Kconfig.host \
+                   $(SRC_PATH)/backends/Kconfig \
+                   $(SRC_PATH)/hw/Kconfig
+MINIKCONF_DEPS = $(MINIKCONF_INPUTS) \
+                 $(wildcard $(SRC_PATH)/hw/*/Kconfig)
 MINIKCONF = $(PYTHON) $(SRC_PATH)/scripts/minikconf.py
 
 $(SUBDIR_DEVICES_MAK): %/config-devices.mak: default-configs/%.mak $(MINIKCONF_DEPS) $(BUILD_DIR)/config-host.mak
-	$(call quiet-command, $(MINIKCONF) $(MINIKCONF_ARGS) > $@.tmp, "GEN", "$@.tmp")
+	$(call quiet-command, $(MINIKCONF) $(MINIKCONF_ARGS) \
+		> $@.tmp, "GEN", "$@.tmp")
 	$(call quiet-command, if test -f $@; then \
 	  if cmp -s $@.old $@; then \
 	    mv $@.tmp $@; \
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 25/53] accel/Kconfig: Extract accel selectors into their own config
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (23 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 24/53] Makefile: Write MINIKCONF variables as one entry per line Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 26/53] accel/Kconfig: Add the TCG selector Paolo Bonzini
                   ` (29 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Richard Henderson, Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

Move the accel selectors from the global Kconfig.host to their
own Kconfig file.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 Kconfig.host  | 7 -------
 Makefile      | 1 +
 accel/Kconfig | 6 ++++++
 3 files changed, 7 insertions(+), 7 deletions(-)
 create mode 100644 accel/Kconfig

diff --git a/Kconfig.host b/Kconfig.host
index 55136e037d..a6d871c399 100644
--- a/Kconfig.host
+++ b/Kconfig.host
@@ -2,9 +2,6 @@
 # down to Kconfig.  See also MINIKCONF_ARGS in the Makefile:
 # these two need to be kept in sync.
 
-config KVM
-    bool
-
 config LINUX
     bool
 
@@ -31,10 +28,6 @@ config VHOST_KERNEL
     bool
     select VHOST
 
-config XEN
-    bool
-    select FSDEV_9P if VIRTFS
-
 config VIRTFS
     bool
 
diff --git a/Makefile b/Makefile
index b96a2d8790..ae025d41ea 100644
--- a/Makefile
+++ b/Makefile
@@ -420,6 +420,7 @@ MINIKCONF_ARGS = \
 
 MINIKCONF_INPUTS = $(SRC_PATH)/Kconfig.host \
                    $(SRC_PATH)/backends/Kconfig \
+                   $(SRC_PATH)/accel/Kconfig \
                    $(SRC_PATH)/hw/Kconfig
 MINIKCONF_DEPS = $(MINIKCONF_INPUTS) \
                  $(wildcard $(SRC_PATH)/hw/*/Kconfig)
diff --git a/accel/Kconfig b/accel/Kconfig
new file mode 100644
index 0000000000..c21802bb49
--- /dev/null
+++ b/accel/Kconfig
@@ -0,0 +1,6 @@
+config KVM
+    bool
+
+config XEN
+    bool
+    select FSDEV_9P if VIRTFS
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 26/53] accel/Kconfig: Add the TCG selector
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (24 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 25/53] accel/Kconfig: Extract accel selectors into their own config Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 27/53] accel/tcg: Add stub for probe_access() Paolo Bonzini
                   ` (28 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Richard Henderson, Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

Expose the CONFIG_TCG selector to let minikconf.py uses it.

When building with --disable-tcg build, this helps to deselect
devices that are TCG-dependent.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 Makefile      | 1 +
 accel/Kconfig | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/Makefile b/Makefile
index ae025d41ea..d4a971283c 100644
--- a/Makefile
+++ b/Makefile
@@ -405,6 +405,7 @@ endif
 MINIKCONF_ARGS = \
     $(CONFIG_MINIKCONF_MODE) \
     $@ $*/config-devices.mak.d $< $(MINIKCONF_INPUTS) \
+    CONFIG_TCG=$(CONFIG_TCG) \
     CONFIG_KVM=$(CONFIG_KVM) \
     CONFIG_SPICE=$(CONFIG_SPICE) \
     CONFIG_IVSHMEM=$(CONFIG_IVSHMEM) \
diff --git a/accel/Kconfig b/accel/Kconfig
index c21802bb49..2ad94a3839 100644
--- a/accel/Kconfig
+++ b/accel/Kconfig
@@ -1,3 +1,6 @@
+config TCG
+    bool
+
 config KVM
     bool
 
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 27/53] accel/tcg: Add stub for probe_access()
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (25 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 26/53] accel/Kconfig: Add the TCG selector Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 28/53] Makefile: simplify MINIKCONF rules Paolo Bonzini
                   ` (27 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Richard Henderson, Philippe Mathieu-Daudé,
	David Hildenbrand

From: Philippe Mathieu-Daudé <f4bug@amsat.org>

The TCG helpers were added in b92e5a22ec3 in softmmu_template.h.
probe_write() was added in there in 3b4afc9e75a to be moved out
to accel/tcg/cputlb.c in 3b08f0a9254, and was later refactored
as probe_access() in c25c283df0f.
Since it is a TCG specific helper, add a stub to avoid failures
when building without TCG, such:

  target/arm/helper.o: In function `probe_read':
  include/exec/exec-all.h:362: undefined reference to `probe_access'

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 accel/stubs/tcg-stub.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c
index 677191a69c..e4bbf997aa 100644
--- a/accel/stubs/tcg-stub.c
+++ b/accel/stubs/tcg-stub.c
@@ -22,3 +22,10 @@ void tb_flush(CPUState *cpu)
 void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
 {
 }
+
+void *probe_access(CPUArchState *env, target_ulong addr, int size,
+                   MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+     /* Handled by hardware accelerator. */
+     g_assert_not_reached();
+}
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 28/53] Makefile: simplify MINIKCONF rules
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (26 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 27/53] accel/tcg: Add stub for probe_access() Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-17 11:02   ` Peter Maydell
  2020-07-06 16:41 ` [PULL 29/53] target/i386: remove gen_io_end Paolo Bonzini
                   ` (26 subsequent siblings)
  54 siblings, 1 reply; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel

There is no reason to write MINIKCONF_DEPS manually, since minikconf.py
emits a dependency file, and also no reason to list multiple Kconfig
files on the command line since they can be included from a master file
in the top-level source directory.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 Kconfig  |  4 ++++
 Makefile | 10 ++--------
 2 files changed, 6 insertions(+), 8 deletions(-)
 create mode 100644 Kconfig

diff --git a/Kconfig b/Kconfig
new file mode 100644
index 0000000000..bf694c42af
--- /dev/null
+++ b/Kconfig
@@ -0,0 +1,4 @@
+source Kconfig.host
+source backends/Kconfig
+source accel/Kconfig
+source hw/Kconfig
diff --git a/Makefile b/Makefile
index d4a971283c..32345c610e 100644
--- a/Makefile
+++ b/Makefile
@@ -404,7 +404,7 @@ endif
 # This has to be kept in sync with Kconfig.host.
 MINIKCONF_ARGS = \
     $(CONFIG_MINIKCONF_MODE) \
-    $@ $*/config-devices.mak.d $< $(MINIKCONF_INPUTS) \
+    $@ $*/config-devices.mak.d $< $(SRC_PATH)/Kconfig \
     CONFIG_TCG=$(CONFIG_TCG) \
     CONFIG_KVM=$(CONFIG_KVM) \
     CONFIG_SPICE=$(CONFIG_SPICE) \
@@ -419,15 +419,9 @@ MINIKCONF_ARGS = \
     CONFIG_LINUX=$(CONFIG_LINUX) \
     CONFIG_PVRDMA=$(CONFIG_PVRDMA)
 
-MINIKCONF_INPUTS = $(SRC_PATH)/Kconfig.host \
-                   $(SRC_PATH)/backends/Kconfig \
-                   $(SRC_PATH)/accel/Kconfig \
-                   $(SRC_PATH)/hw/Kconfig
-MINIKCONF_DEPS = $(MINIKCONF_INPUTS) \
-                 $(wildcard $(SRC_PATH)/hw/*/Kconfig)
 MINIKCONF = $(PYTHON) $(SRC_PATH)/scripts/minikconf.py
 
-$(SUBDIR_DEVICES_MAK): %/config-devices.mak: default-configs/%.mak $(MINIKCONF_DEPS) $(BUILD_DIR)/config-host.mak
+$(SUBDIR_DEVICES_MAK): %/config-devices.mak: default-configs/%.mak $(SRC_PATH)/Kconfig $(BUILD_DIR)/config-host.mak
 	$(call quiet-command, $(MINIKCONF) $(MINIKCONF_ARGS) \
 		> $@.tmp, "GEN", "$@.tmp")
 	$(call quiet-command, if test -f $@; then \
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 29/53] target/i386: remove gen_io_end
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (27 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 28/53] Makefile: simplify MINIKCONF rules Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 30/53] target/i386: implement undocumented "smsw r32" behavior Paolo Bonzini
                   ` (25 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson

Force the end of a translation block after an I/O instruction in
icount mode.  For consistency, all CF_USE_ICOUNT code is kept in
disas_insn instead of having it in gen_ins and gen_outs.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/translate.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index b3fea54411..5ef72ff401 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -1128,9 +1128,6 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
 
 static inline void gen_ins(DisasContext *s, MemOp ot)
 {
-    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-        gen_io_start();
-    }
     gen_string_movl_A0_EDI(s);
     /* Note: we must do this dummy write first to be restartable in
        case of page fault. */
@@ -1143,16 +1140,10 @@ static inline void gen_ins(DisasContext *s, MemOp ot)
     gen_op_movl_T0_Dshift(s, ot);
     gen_op_add_reg_T0(s, s->aflag, R_EDI);
     gen_bpt_io(s, s->tmp2_i32, ot);
-    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
-    }
 }
 
 static inline void gen_outs(DisasContext *s, MemOp ot)
 {
-    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-        gen_io_start();
-    }
     gen_string_movl_A0_ESI(s);
     gen_op_ld_v(s, ot, s->T0, s->A0);
 
@@ -1163,9 +1154,6 @@ static inline void gen_outs(DisasContext *s, MemOp ot)
     gen_op_movl_T0_Dshift(s, ot);
     gen_op_add_reg_T0(s, s->aflag, R_ESI);
     gen_bpt_io(s, s->tmp2_i32, ot);
-    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
-    }
 }
 
 /* same method as Valgrind : we generate jumps to current or next
@@ -6400,8 +6388,12 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base, 
                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
+        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+            gen_io_start();
+        }
         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
             gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+            /* jump generated by gen_repz_ins */
         } else {
             gen_ins(s, ot);
             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -6415,8 +6407,12 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base,
                      svm_is_rep(prefixes) | 4);
+        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+            gen_io_start();
+        }
         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
             gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+            /* jump generated by gen_repz_outs */
         } else {
             gen_outs(s, ot);
             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -8039,7 +8035,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                     gen_helper_read_crN(s->T0, cpu_env, tcg_const_i32(reg));
                     gen_op_mov_reg_v(s, ot, rm, s->T0);
                     if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-                        gen_io_end();
+                        gen_jmp(s, s->pc - s->cs_base);
                     }
                 }
                 break;
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 30/53] target/i386: implement undocumented "smsw r32" behavior
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (28 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 29/53] target/i386: remove gen_io_end Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 31/53] KVM: x86: believe what KVM says about WAITPKG Paolo Bonzini
                   ` (24 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Roman Bolshakov, Richard Henderson

In 32-bit mode, the higher 16 bits of the destination
register are undefined.  In practice CR0[31:0] is stored,
just like in 64-bit mode, so just remove the "if" that
currently differentiates the behavior.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reported-by: Roman Bolshakov <r.bolshakov@yadro.com>
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/translate.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 5ef72ff401..a1d31f09c1 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -7579,12 +7579,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         CASE_MODRM_OP(4): /* smsw */
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0]));
-            if (CODE64(s)) {
-                mod = (modrm >> 6) & 3;
-                ot = (mod != 3 ? MO_16 : s->dflag);
-            } else {
-                ot = MO_16;
-            }
+            /*
+             * In 32-bit mode, the higher 16 bits of the destination
+             * register are undefined.  In practice CR0[31:0] is stored
+             * just like in 64-bit mode.
+             */
+            mod = (modrm >> 6) & 3;
+            ot = (mod != 3 ? MO_16 : s->dflag);
             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
             break;
         case 0xee: /* rdpkru */
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 31/53] KVM: x86: believe what KVM says about WAITPKG
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (29 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 30/53] target/i386: implement undocumented "smsw r32" behavior Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-07 11:42   ` Maxim Levitsky
  2021-12-22  9:35   ` Chenyi Qiang
  2020-07-06 16:41 ` [PULL 32/53] target/i386: sev: provide proper error reporting for query-sev-capabilities Paolo Bonzini
                   ` (23 subsequent siblings)
  54 siblings, 2 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-stable, Maxim Levitsky

Currently, QEMU is overriding KVM_GET_SUPPORTED_CPUID's answer for
the WAITPKG bit depending on the "-overcommit cpu-pm" setting.  This is a
bad idea because it does not even check if the host supports it, but it
can be done in x86_cpu_realizefn just like we do for the MONITOR bit.

This patch moves it there, while making it conditional on host
support for the related UMWAIT MSR.

Cc: qemu-stable@nongnu.org
Reported-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.c      |  3 +++
 target/i386/kvm.c      | 11 +++++------
 target/i386/kvm_i386.h |  1 +
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index c44cc510e1..dc9ba06f1f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6536,6 +6536,9 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
             host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx,
                        &cpu->mwait.ecx, &cpu->mwait.edx);
             env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR;
+            if (kvm_enabled() && kvm_has_waitpkg()) {
+                env->features[FEAT_7_0_ECX] |= CPUID_7_0_ECX_WAITPKG;
+            }
         }
         if (kvm_enabled() && cpu->ucode_rev == 0) {
             cpu->ucode_rev = kvm_arch_get_supported_msr_feature(kvm_state,
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 2b6b7443d2..b8455c89ed 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -411,12 +411,6 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
         if (host_tsx_blacklisted()) {
             ret &= ~(CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_HLE);
         }
-    } else if (function == 7 && index == 0 && reg == R_ECX) {
-        if (enable_cpu_pm) {
-            ret |= CPUID_7_0_ECX_WAITPKG;
-        } else {
-            ret &= ~CPUID_7_0_ECX_WAITPKG;
-        }
     } else if (function == 7 && index == 0 && reg == R_EDX) {
         /*
          * Linux v4.17-v4.20 incorrectly return ARCH_CAPABILITIES on SVM hosts.
@@ -4730,3 +4724,8 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
 {
     abort();
 }
+
+bool kvm_has_waitpkg(void)
+{
+    return has_msr_umwait;
+}
diff --git a/target/i386/kvm_i386.h b/target/i386/kvm_i386.h
index 00bde7acaf..064b8798a2 100644
--- a/target/i386/kvm_i386.h
+++ b/target/i386/kvm_i386.h
@@ -44,6 +44,7 @@ void kvm_put_apicbase(X86CPU *cpu, uint64_t value);
 
 bool kvm_enable_x2apic(void);
 bool kvm_has_x2apic_api(void);
+bool kvm_has_waitpkg(void);
 
 bool kvm_hv_vpindex_settable(void);
 
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 32/53] target/i386: sev: provide proper error reporting for query-sev-capabilities
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (30 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 31/53] KVM: x86: believe what KVM says about WAITPKG Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 33/53] target/i386: sev: fail query-sev-capabilities if QEMU cannot use SEV Paolo Bonzini
                   ` (22 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel

The query-sev-capabilities was reporting errors through error_report;
change it to use Error** so that the cause of the failure is clearer.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/monitor.c  | 10 +---------
 target/i386/sev-stub.c |  3 ++-
 target/i386/sev.c      | 18 +++++++++---------
 target/i386/sev_i386.h |  2 +-
 4 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index 27ebfa3ad2..7abae3c8df 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -726,13 +726,5 @@ SevLaunchMeasureInfo *qmp_query_sev_launch_measure(Error **errp)
 
 SevCapability *qmp_query_sev_capabilities(Error **errp)
 {
-    SevCapability *data;
-
-    data = sev_get_capabilities();
-    if (!data) {
-        error_setg(errp, "SEV feature is not available");
-        return NULL;
-    }
-
-    return data;
+    return sev_get_capabilities(errp);
 }
diff --git a/target/i386/sev-stub.c b/target/i386/sev-stub.c
index e5ee13309c..88e3f39a1e 100644
--- a/target/i386/sev-stub.c
+++ b/target/i386/sev-stub.c
@@ -44,7 +44,8 @@ char *sev_get_launch_measurement(void)
     return NULL;
 }
 
-SevCapability *sev_get_capabilities(void)
+SevCapability *sev_get_capabilities(Error **errp)
 {
+    error_setg(errp, "SEV is not available in this QEMU");
     return NULL;
 }
diff --git a/target/i386/sev.c b/target/i386/sev.c
index d273174ad3..70f9ee026f 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -399,7 +399,7 @@ sev_get_info(void)
 
 static int
 sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
-                 size_t *cert_chain_len)
+                 size_t *cert_chain_len, Error **errp)
 {
     guchar *pdh_data = NULL;
     guchar *cert_chain_data = NULL;
@@ -410,8 +410,8 @@ sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
     r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
     if (r < 0) {
         if (err != SEV_RET_INVALID_LEN) {
-            error_report("failed to export PDH cert ret=%d fw_err=%d (%s)",
-                         r, err, fw_error_to_str(err));
+            error_setg(errp, "failed to export PDH cert ret=%d fw_err=%d (%s)",
+                       r, err, fw_error_to_str(err));
             return 1;
         }
     }
@@ -423,8 +423,8 @@ sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
 
     r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
     if (r < 0) {
-        error_report("failed to export PDH cert ret=%d fw_err=%d (%s)",
-                     r, err, fw_error_to_str(err));
+        error_setg(errp, "failed to export PDH cert ret=%d fw_err=%d (%s)",
+                   r, err, fw_error_to_str(err));
         goto e_free;
     }
 
@@ -441,7 +441,7 @@ e_free:
 }
 
 SevCapability *
-sev_get_capabilities(void)
+sev_get_capabilities(Error **errp)
 {
     SevCapability *cap = NULL;
     guchar *pdh_data = NULL;
@@ -452,13 +452,13 @@ sev_get_capabilities(void)
 
     fd = open(DEFAULT_SEV_DEVICE, O_RDWR);
     if (fd < 0) {
-        error_report("%s: Failed to open %s '%s'", __func__,
-                     DEFAULT_SEV_DEVICE, strerror(errno));
+        error_setg_errno(errp, errno, "Failed to open %s",
+                         DEFAULT_SEV_DEVICE);
         return NULL;
     }
 
     if (sev_get_pdh_info(fd, &pdh_data, &pdh_len,
-                         &cert_chain_data, &cert_chain_len)) {
+                         &cert_chain_data, &cert_chain_len, errp)) {
         goto out;
     }
 
diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h
index 8eb7de1bef..4db6960f60 100644
--- a/target/i386/sev_i386.h
+++ b/target/i386/sev_i386.h
@@ -34,6 +34,6 @@ extern SevInfo *sev_get_info(void);
 extern uint32_t sev_get_cbit_position(void);
 extern uint32_t sev_get_reduced_phys_bits(void);
 extern char *sev_get_launch_measurement(void);
-extern SevCapability *sev_get_capabilities(void);
+extern SevCapability *sev_get_capabilities(Error **errp);
 
 #endif
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 33/53] target/i386: sev: fail query-sev-capabilities if QEMU cannot use SEV
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (31 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 32/53] target/i386: sev: provide proper error reporting for query-sev-capabilities Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 34/53] iscsi: handle check condition status in retry loop Paolo Bonzini
                   ` (21 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel

In some cases, such as if the kvm-amd "sev" module parameter is set
to 0, SEV will be unavailable but query-sev-capabilities will still
return all the information.  This tricks libvirt into erroneously
reporting that SEV is available.  Check the actual usability of the
feature and return the appropriate error if QEMU cannot use KVM
or KVM cannot use SEV.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/sev.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index 70f9ee026f..ee8588fd6c 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -450,6 +450,15 @@ sev_get_capabilities(Error **errp)
     uint32_t ebx;
     int fd;
 
+    if (!kvm_enabled()) {
+        error_setg(errp, "KVM not enabled");
+        return NULL;
+    }
+    if (kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, NULL) < 0) {
+        error_setg(errp, "SEV is not enabled in KVM");
+        return NULL;
+    }
+
     fd = open(DEFAULT_SEV_DEVICE, O_RDWR);
     if (fd < 0) {
         error_setg_errno(errp, errno, "Failed to open %s",
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 34/53] iscsi: handle check condition status in retry loop
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (32 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 33/53] target/i386: sev: fail query-sev-capabilities if QEMU cannot use SEV Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 35/53] iscsi: return -EIO when sense fields are meaningless Paolo Bonzini
                   ` (20 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Xie Yongji

From: Xie Yongji <xieyongji@bytedance.com>

The handling of check condition was incorrect because
we would only do it after retries exceed maximum.

Fixes: 8c460269aa ("iscsi: base all handling of check condition on scsi_sense_to_errno")
Signed-off-by: Xie Yongji <xieyongji@bytedance.com>
Message-Id: <20200701105444.3226-1-xieyongji@bytedance.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/iscsi.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index a8b76979d8..2964c9f8d2 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -266,16 +266,16 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
                 timer_mod(&iTask->retry_timer,
                           qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + retry_time);
                 iTask->do_retry = 1;
-            }
-        } else if (status == SCSI_STATUS_CHECK_CONDITION) {
-            int error = iscsi_translate_sense(&task->sense);
-            if (error == EAGAIN) {
-                error_report("iSCSI CheckCondition: %s",
-                             iscsi_get_error(iscsi));
-                iTask->do_retry = 1;
-            } else {
-                iTask->err_code = -error;
-                iTask->err_str = g_strdup(iscsi_get_error(iscsi));
+            } else if (status == SCSI_STATUS_CHECK_CONDITION) {
+                int error = iscsi_translate_sense(&task->sense);
+                if (error == EAGAIN) {
+                    error_report("iSCSI CheckCondition: %s",
+                                 iscsi_get_error(iscsi));
+                    iTask->do_retry = 1;
+                } else {
+                    iTask->err_code = -error;
+                    iTask->err_str = g_strdup(iscsi_get_error(iscsi));
+                }
             }
         }
     }
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 35/53] iscsi: return -EIO when sense fields are meaningless
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (33 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 34/53] iscsi: handle check condition status in retry loop Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 36/53] chardev/tcp: fix error message double free error Paolo Bonzini
                   ` (19 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Xie Yongji

From: Xie Yongji <xieyongji@bytedance.com>

When an I/O request failed, now we only return correct
value on scsi check condition. We should also have a
default errno such as -EIO in other case.

Signed-off-by: Xie Yongji <xieyongji@bytedance.com>
Message-Id: <20200701105444.3226-2-xieyongji@bytedance.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/iscsi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/block/iscsi.c b/block/iscsi.c
index 2964c9f8d2..387ed872ef 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -241,9 +241,11 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
 
     iTask->status = status;
     iTask->do_retry = 0;
+    iTask->err_code = 0;
     iTask->task = task;
 
     if (status != SCSI_STATUS_GOOD) {
+        iTask->err_code = -EIO;
         if (iTask->retries++ < ISCSI_CMD_RETRIES) {
             if (status == SCSI_STATUS_BUSY ||
                 status == SCSI_STATUS_TIMEOUT ||
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 36/53] chardev/tcp: fix error message double free error
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (34 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 35/53] iscsi: return -EIO when sense fields are meaningless Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 37/53] checkpatch: Change occurences of 'kernel' to 'qemu' in user messages Paolo Bonzini
                   ` (18 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: lichun, Markus Armbruster, qemu-stable

From: lichun <lichun@ruijie.com.cn>

Errors are already freed by error_report_err, so we only need to call
error_free when that function is not called.

Signed-off-by: lichun <lichun@ruijie.com.cn>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20200621213017.17978-1-lichun@ruijie.com.cn>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 chardev/char-socket.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index afebeec5c3..569d54c144 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -142,6 +142,8 @@ static void check_report_connect_error(Chardev *chr,
                           "Unable to connect character device %s: ",
                           chr->label);
         s->connect_err_reported = true;
+    } else {
+        error_free(err);
     }
     qemu_chr_socket_restart_timer(chr);
 }
@@ -1086,7 +1088,6 @@ static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
     if (qio_task_propagate_error(task, &err)) {
         tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
         check_report_connect_error(chr, err);
-        error_free(err);
         goto cleanup;
     }
 
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 37/53] checkpatch: Change occurences of 'kernel' to 'qemu' in user messages
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (35 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 36/53] chardev/tcp: fix error message double free error Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 38/53] target/i386: Correct the warning message of Intel PT Paolo Bonzini
                   ` (17 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Aleksandar Markovic

From: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>

It is odd that we inform user that, for example, his current working
directory is not kernel root, when, in face, we mean qemu root.

Replace that and few other similar odd user messages.

Signed-off-by: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
Message-Id: <20200620133207.26849-3-aleksandar.qemu.devel@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 scripts/checkpatch.pl | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 2d2e922d89..bd3faa154c 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -49,7 +49,7 @@ Version: $V
 
 Options:
   -q, --quiet                quiet
-  --no-tree                  run without a kernel tree
+  --no-tree                  run without a qemu tree
   --no-signoff               do not check for 'Signed-off-by' line
   --patch                    treat FILE as patchfile
   --branch                   treat args as GIT revision list
@@ -57,7 +57,7 @@ Options:
   --terse                    one line per report
   -f, --file                 treat FILE as regular source file
   --strict                   fail if only warnings are found
-  --root=PATH                PATH to the kernel tree root
+  --root=PATH                PATH to the qemu tree root
   --no-summary               suppress the per-file summary
   --mailback                 only produce a report in case of warnings/errors
   --summary-file             include the filename in summary
@@ -203,7 +203,7 @@ if ($tree) {
 	}
 
 	if (!defined $root) {
-		print "Must be run from the top-level dir. of a kernel tree\n";
+		print "Must be run from the top-level dir. of a qemu tree\n";
 		exit(2);
 	}
 }
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 38/53] target/i386: Correct the warning message of Intel PT
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (36 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 37/53] checkpatch: Change occurences of 'kernel' to 'qemu' in user messages Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 39/53] cpus: Move CPU code from exec.c to cpus-common.c Paolo Bonzini
                   ` (16 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Luwei Kang

From: Luwei Kang <luwei.kang@intel.com>

The CPUID level need to be set to 0x14 manually on old
machine-type if Intel PT is enabled in guest. E.g. the
CPUID[0].EAX(level)=7 and CPUID[7].EBX[25](intel-pt)=1 when the
Qemu with "-machine pc-i440fx-3.1 -cpu qemu64,+intel-pt" parameter.

This patch corrects the warning message of the previous
submission(ddc2fc9).

Signed-off-by: Luwei Kang <luwei.kang@intel.com>
Message-Id: <1593499113-4768-1-git-send-email-luwei.kang@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index dc9ba06f1f..be9a0aa76d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6420,7 +6420,7 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
             } else if (cpu->env.cpuid_min_level < 0x14) {
                 mark_unavailable_features(cpu, FEAT_7_0_EBX,
                     CPUID_7_0_EBX_INTEL_PT,
-                    "Intel PT need CPUID leaf 0x14, please set by \"-cpu ...,+intel-pt,level=0x14\"");
+                    "Intel PT need CPUID leaf 0x14, please set by \"-cpu ...,+intel-pt,min-level=0x14\"");
             }
         }
 
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 39/53] cpus: Move CPU code from exec.c to cpus-common.c
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (37 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 38/53] target/i386: Correct the warning message of Intel PT Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 40/53] pc: fix leak in pc_system_flash_cleanup_unused Paolo Bonzini
                   ` (15 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Richard Henderson, Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

This code was introduced with SMP support in commit 6a00d60127,
later commit 267f685b8b moved CPU list management to common code
but forgot this code. Move now and simplify ifdef'ry.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200702104017.14057-1-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus-common.c | 18 ++++++++++++++++++
 exec.c        | 22 ----------------------
 2 files changed, 18 insertions(+), 22 deletions(-)

diff --git a/cpus-common.c b/cpus-common.c
index 8f5512b3d7..34044f4e4c 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -72,6 +72,8 @@ static int cpu_get_free_index(void)
     return max_cpu_index;
 }
 
+CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
+
 void cpu_list_add(CPUState *cpu)
 {
     QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
@@ -96,6 +98,22 @@ void cpu_list_remove(CPUState *cpu)
     cpu->cpu_index = UNASSIGNED_CPU_INDEX;
 }
 
+CPUState *qemu_get_cpu(int index)
+{
+    CPUState *cpu;
+
+    CPU_FOREACH(cpu) {
+        if (cpu->cpu_index == index) {
+            return cpu;
+        }
+    }
+
+    return NULL;
+}
+
+/* current CPU in the current thread. It is only valid inside cpu_exec() */
+__thread CPUState *current_cpu;
+
 struct qemu_work_item {
     QSIMPLEQ_ENTRY(qemu_work_item) node;
     run_on_cpu_func func;
diff --git a/exec.c b/exec.c
index 21926dc9c7..997b7db15f 100644
--- a/exec.c
+++ b/exec.c
@@ -98,12 +98,6 @@ AddressSpace address_space_memory;
 static MemoryRegion io_mem_unassigned;
 #endif
 
-CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
-
-/* current CPU in the current thread. It is only valid inside
-   cpu_exec() */
-__thread CPUState *current_cpu;
-
 uintptr_t qemu_host_page_size;
 intptr_t qemu_host_page_mask;
 
@@ -832,22 +826,6 @@ const VMStateDescription vmstate_cpu_common = {
     }
 };
 
-#endif
-
-CPUState *qemu_get_cpu(int index)
-{
-    CPUState *cpu;
-
-    CPU_FOREACH(cpu) {
-        if (cpu->cpu_index == index) {
-            return cpu;
-        }
-    }
-
-    return NULL;
-}
-
-#if !defined(CONFIG_USER_ONLY)
 void cpu_address_space_init(CPUState *cpu, int asidx,
                             const char *prefix, MemoryRegion *mr)
 {
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 40/53] pc: fix leak in pc_system_flash_cleanup_unused
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (38 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 39/53] cpus: Move CPU code from exec.c to cpus-common.c Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 41/53] softmmu: move softmmu only files from root Paolo Bonzini
                   ` (14 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alexander Bulekov

From: Alexander Bulekov <alxndr@bu.edu>

tries to fix a leak detected when building with --enable-sanitizers:
./i386-softmmu/qemu-system-i386
Upon exit:
==13576==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 1216 byte(s) in 1 object(s) allocated from:
    #0 0x7f9d2ed5c628 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5)
    #1 0x7f9d2e963500 in g_malloc (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.)
    #2 0x55fa646d25cc in object_new_with_type /tmp/qemu/qom/object.c:686
    #3 0x55fa63dbaa88 in qdev_new /tmp/qemu/hw/core/qdev.c:140
    #4 0x55fa638a533f in pc_pflash_create /tmp/qemu/hw/i386/pc_sysfw.c:88
    #5 0x55fa638a54c4 in pc_system_flash_create /tmp/qemu/hw/i386/pc_sysfw.c:106
    #6 0x55fa646caa1d in object_init_with_type /tmp/qemu/qom/object.c:369
    #7 0x55fa646d20b5 in object_initialize_with_type /tmp/qemu/qom/object.c:511
    #8 0x55fa646d2606 in object_new_with_type /tmp/qemu/qom/object.c:687
    #9 0x55fa639431e9 in qemu_init /tmp/qemu/softmmu/vl.c:3878
    #10 0x55fa6335c1b8 in main /tmp/qemu/softmmu/main.c:48
    #11 0x7f9d2cf06e0a in __libc_start_main ../csu/libc-start.c:308
    #12 0x55fa6335f8e9 in _start (/tmp/qemu/build/i386-softmmu/qemu-system-i386)

Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Message-Id: <20200701145231.19531-1-alxndr@bu.edu>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/pc_sysfw.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index ec2a3b3e7e..71ce273a14 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -93,6 +93,11 @@ static PFlashCFI01 *pc_pflash_create(PCMachineState *pcms,
     object_property_add_child(OBJECT(pcms), name, OBJECT(dev));
     object_property_add_alias(OBJECT(pcms), alias_prop_name,
                               OBJECT(dev), "drive");
+    /*
+     * The returned reference is tied to the child property and
+     * will be removed with object_unparent.
+     */
+    object_unref(OBJECT(dev));
     return PFLASH_CFI01(dev);
 }
 
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 41/53] softmmu: move softmmu only files from root
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (39 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 40/53] pc: fix leak in pc_system_flash_cleanup_unused Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 42/53] cpu-throttle: new module, extracted from cpus.c Paolo Bonzini
                   ` (13 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, Thomas Huth, Alex Bennée, Claudio Fontana

From: Claudio Fontana <cfontana@suse.de>

move arch_init, balloon, cpus, ioport, memory, memory_mapping, qtest.

They are all specific to CONFIG_SOFTMMU.

Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20200629093504.3228-2-cfontana@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 MAINTAINERS                                  | 12 ++++++------
 Makefile.target                              |  7 ++-----
 softmmu/Makefile.objs                        | 10 ++++++++++
 arch_init.c => softmmu/arch_init.c           |  0
 balloon.c => softmmu/balloon.c               |  0
 cpus.c => softmmu/cpus.c                     |  0
 ioport.c => softmmu/ioport.c                 |  0
 memory.c => softmmu/memory.c                 |  0
 memory_mapping.c => softmmu/memory_mapping.c |  0
 qtest.c => softmmu/qtest.c                   |  0
 10 files changed, 18 insertions(+), 11 deletions(-)
 rename arch_init.c => softmmu/arch_init.c (100%)
 rename balloon.c => softmmu/balloon.c (100%)
 rename cpus.c => softmmu/cpus.c (100%)
 rename ioport.c => softmmu/ioport.c (100%)
 rename memory.c => softmmu/memory.c (100%)
 rename memory_mapping.c => softmmu/memory_mapping.c (100%)
 rename qtest.c => softmmu/qtest.c (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 72d5871f41..fdf43228b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -115,7 +115,7 @@ Overall TCG CPUs
 M: Richard Henderson <rth@twiddle.net>
 R: Paolo Bonzini <pbonzini@redhat.com>
 S: Maintained
-F: cpus.c
+F: softmmu/cpus.c
 F: cpus-common.c
 F: exec.c
 F: accel/tcg/
@@ -1722,7 +1722,7 @@ M: David Hildenbrand <david@redhat.com>
 S: Maintained
 F: hw/virtio/virtio-balloon*.c
 F: include/hw/virtio/virtio-balloon.h
-F: balloon.c
+F: softmmu/balloon.c
 F: include/sysemu/balloon.h
 
 virtio-9p
@@ -2191,12 +2191,12 @@ Memory API
 M: Paolo Bonzini <pbonzini@redhat.com>
 S: Supported
 F: include/exec/ioport.h
-F: ioport.c
 F: include/exec/memop.h
 F: include/exec/memory.h
 F: include/exec/ram_addr.h
 F: include/exec/ramblock.h
-F: memory.c
+F: softmmu/ioport.c
+F: softmmu/memory.c
 F: include/exec/memory-internal.h
 F: exec.c
 F: scripts/coccinelle/memory-region-housekeeping.cocci
@@ -2228,13 +2228,13 @@ F: ui/cocoa.m
 Main loop
 M: Paolo Bonzini <pbonzini@redhat.com>
 S: Maintained
-F: cpus.c
 F: include/qemu/main-loop.h
 F: include/sysemu/runstate.h
 F: util/main-loop.c
 F: util/qemu-timer.c
 F: softmmu/vl.c
 F: softmmu/main.c
+F: softmmu/cpus.c
 F: qapi/run-state.json
 
 Human Monitor (HMP)
@@ -2389,7 +2389,7 @@ M: Thomas Huth <thuth@redhat.com>
 M: Laurent Vivier <lvivier@redhat.com>
 R: Paolo Bonzini <pbonzini@redhat.com>
 S: Maintained
-F: qtest.c
+F: softmmu/qtest.c
 F: accel/qtest.c
 F: tests/qtest/
 X: tests/qtest/bios-tables-test-allowed-diff.h
diff --git a/Makefile.target b/Makefile.target
index 8ed1eba95b..7fbf5d8b92 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -152,16 +152,13 @@ endif #CONFIG_BSD_USER
 #########################################################
 # System emulator target
 ifdef CONFIG_SOFTMMU
-obj-y += arch_init.o cpus.o gdbstub.o balloon.o ioport.o
-obj-y += qtest.o
+obj-y += softmmu/
+obj-y += gdbstub.o
 obj-y += dump/
 obj-y += hw/
 obj-y += monitor/
 obj-y += qapi/
-obj-y += memory.o
-obj-y += memory_mapping.o
 obj-y += migration/ram.o
-obj-y += softmmu/
 LIBS := $(libs_softmmu) $(LIBS)
 
 # Hardware support
diff --git a/softmmu/Makefile.objs b/softmmu/Makefile.objs
index dd15c24346..a4bd9f2f52 100644
--- a/softmmu/Makefile.objs
+++ b/softmmu/Makefile.objs
@@ -1,3 +1,13 @@
 softmmu-main-y = softmmu/main.o
+
+obj-y += arch_init.o
+obj-y += cpus.o
+obj-y += balloon.o
+obj-y += ioport.o
+obj-y += memory.o
+obj-y += memory_mapping.o
+
+obj-y += qtest.o
+
 obj-y += vl.o
 vl.o-cflags := $(GPROF_CFLAGS) $(SDL_CFLAGS)
diff --git a/arch_init.c b/softmmu/arch_init.c
similarity index 100%
rename from arch_init.c
rename to softmmu/arch_init.c
diff --git a/balloon.c b/softmmu/balloon.c
similarity index 100%
rename from balloon.c
rename to softmmu/balloon.c
diff --git a/cpus.c b/softmmu/cpus.c
similarity index 100%
rename from cpus.c
rename to softmmu/cpus.c
diff --git a/ioport.c b/softmmu/ioport.c
similarity index 100%
rename from ioport.c
rename to softmmu/ioport.c
diff --git a/memory.c b/softmmu/memory.c
similarity index 100%
rename from memory.c
rename to softmmu/memory.c
diff --git a/memory_mapping.c b/softmmu/memory_mapping.c
similarity index 100%
rename from memory_mapping.c
rename to softmmu/memory_mapping.c
diff --git a/qtest.c b/softmmu/qtest.c
similarity index 100%
rename from qtest.c
rename to softmmu/qtest.c
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 42/53] cpu-throttle: new module, extracted from cpus.c
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (40 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 41/53] softmmu: move softmmu only files from root Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 43/53] cpu-timers, icount: new modules Paolo Bonzini
                   ` (12 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, Alex Bennée, Claudio Fontana

From: Claudio Fontana <cfontana@suse.de>

move the vcpu throttling functionality into its own module.

This functionality is not specific to any accelerator,
and it is used currently by migration to slow down guests to try to
have migrations converge, and by the cocoa MacOS UI to throttle speed.

cpu-throttle contains the controls to adjust and inspect throttle
settings, start (set) and stop vcpu throttling, and the throttling
function itself that is run periodically on vcpus to make them take a nap.

Execution of the throttling function on all vcpus is triggered by a timer,
registered at module initialization.

No functionality change.

Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Message-Id: <20200629093504.3228-3-cfontana@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 MAINTAINERS                   |   1 +
 include/hw/core/cpu.h         |  37 -----------
 include/qemu/main-loop.h      |   5 ++
 include/sysemu/cpu-throttle.h |  68 +++++++++++++++++++
 migration/migration.c         |   1 +
 migration/ram.c               |   1 +
 softmmu/Makefile.objs         |   1 +
 softmmu/cpu-throttle.c        | 122 ++++++++++++++++++++++++++++++++++
 softmmu/cpus.c                |  95 +++-----------------------
 9 files changed, 207 insertions(+), 124 deletions(-)
 create mode 100644 include/sysemu/cpu-throttle.h
 create mode 100644 softmmu/cpu-throttle.c

diff --git a/MAINTAINERS b/MAINTAINERS
index fdf43228b5..933c646a86 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2235,6 +2235,7 @@ F: util/qemu-timer.c
 F: softmmu/vl.c
 F: softmmu/main.c
 F: softmmu/cpus.c
+F: softmmu/cpu-throttle.c
 F: qapi/run-state.json
 
 Human Monitor (HMP)
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index b3f4b79318..5542577d2b 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -822,43 +822,6 @@ bool cpu_exists(int64_t id);
  */
 CPUState *cpu_by_arch_id(int64_t id);
 
-/**
- * cpu_throttle_set:
- * @new_throttle_pct: Percent of sleep time. Valid range is 1 to 99.
- *
- * Throttles all vcpus by forcing them to sleep for the given percentage of
- * time. A throttle_percentage of 25 corresponds to a 75% duty cycle roughly.
- * (example: 10ms sleep for every 30ms awake).
- *
- * cpu_throttle_set can be called as needed to adjust new_throttle_pct.
- * Once the throttling starts, it will remain in effect until cpu_throttle_stop
- * is called.
- */
-void cpu_throttle_set(int new_throttle_pct);
-
-/**
- * cpu_throttle_stop:
- *
- * Stops the vcpu throttling started by cpu_throttle_set.
- */
-void cpu_throttle_stop(void);
-
-/**
- * cpu_throttle_active:
- *
- * Returns: %true if the vcpus are currently being throttled, %false otherwise.
- */
-bool cpu_throttle_active(void);
-
-/**
- * cpu_throttle_get_percentage:
- *
- * Returns the vcpu throttle percentage. See cpu_throttle_set for details.
- *
- * Returns: The throttle percentage in range 1 to 99.
- */
-int cpu_throttle_get_percentage(void);
-
 #ifndef CONFIG_USER_ONLY
 
 typedef void (*CPUInterruptHandler)(CPUState *, int);
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index a6d20b0719..8e98613656 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -303,6 +303,11 @@ void qemu_mutex_unlock_iothread(void);
  */
 void qemu_cond_wait_iothread(QemuCond *cond);
 
+/*
+ * qemu_cond_timedwait_iothread: like the previous, but with timeout
+ */
+void qemu_cond_timedwait_iothread(QemuCond *cond, int ms);
+
 /* internal interfaces */
 
 void qemu_fd_register(int fd);
diff --git a/include/sysemu/cpu-throttle.h b/include/sysemu/cpu-throttle.h
new file mode 100644
index 0000000000..d65bdef6d0
--- /dev/null
+++ b/include/sysemu/cpu-throttle.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#ifndef SYSEMU_CPU_THROTTLE_H
+#define SYSEMU_CPU_THROTTLE_H
+
+#include "qemu/timer.h"
+
+/**
+ * cpu_throttle_init:
+ *
+ * Initialize the CPU throttling API.
+ */
+void cpu_throttle_init(void);
+
+/**
+ * cpu_throttle_set:
+ * @new_throttle_pct: Percent of sleep time. Valid range is 1 to 99.
+ *
+ * Throttles all vcpus by forcing them to sleep for the given percentage of
+ * time. A throttle_percentage of 25 corresponds to a 75% duty cycle roughly.
+ * (example: 10ms sleep for every 30ms awake).
+ *
+ * cpu_throttle_set can be called as needed to adjust new_throttle_pct.
+ * Once the throttling starts, it will remain in effect until cpu_throttle_stop
+ * is called.
+ */
+void cpu_throttle_set(int new_throttle_pct);
+
+/**
+ * cpu_throttle_stop:
+ *
+ * Stops the vcpu throttling started by cpu_throttle_set.
+ */
+void cpu_throttle_stop(void);
+
+/**
+ * cpu_throttle_active:
+ *
+ * Returns: %true if the vcpus are currently being throttled, %false otherwise.
+ */
+bool cpu_throttle_active(void);
+
+/**
+ * cpu_throttle_get_percentage:
+ *
+ * Returns the vcpu throttle percentage. See cpu_throttle_set for details.
+ *
+ * Returns: The throttle percentage in range 1 to 99.
+ */
+int cpu_throttle_get_percentage(void);
+
+#endif /* SYSEMU_CPU_THROTTLE_H */
diff --git a/migration/migration.c b/migration/migration.c
index 481a590f72..676fb6084e 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -23,6 +23,7 @@
 #include "socket.h"
 #include "sysemu/runstate.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/cpu-throttle.h"
 #include "rdma.h"
 #include "ram.h"
 #include "migration/global_state.h"
diff --git a/migration/ram.c b/migration/ram.c
index 069b6e30bc..9ef1e63cb6 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -52,6 +52,7 @@
 #include "migration/colo.h"
 #include "block.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/cpu-throttle.h"
 #include "savevm.h"
 #include "qemu/iov.h"
 #include "multifd.h"
diff --git a/softmmu/Makefile.objs b/softmmu/Makefile.objs
index a4bd9f2f52..a414a74c50 100644
--- a/softmmu/Makefile.objs
+++ b/softmmu/Makefile.objs
@@ -2,6 +2,7 @@ softmmu-main-y = softmmu/main.o
 
 obj-y += arch_init.o
 obj-y += cpus.o
+obj-y += cpu-throttle.o
 obj-y += balloon.o
 obj-y += ioport.o
 obj-y += memory.o
diff --git a/softmmu/cpu-throttle.c b/softmmu/cpu-throttle.c
new file mode 100644
index 0000000000..4e6b2818ca
--- /dev/null
+++ b/softmmu/cpu-throttle.c
@@ -0,0 +1,122 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * 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 "qemu-common.h"
+#include "qemu/thread.h"
+#include "hw/core/cpu.h"
+#include "qemu/main-loop.h"
+#include "sysemu/cpus.h"
+#include "sysemu/cpu-throttle.h"
+
+/* vcpu throttling controls */
+static QEMUTimer *throttle_timer;
+static unsigned int throttle_percentage;
+
+#define CPU_THROTTLE_PCT_MIN 1
+#define CPU_THROTTLE_PCT_MAX 99
+#define CPU_THROTTLE_TIMESLICE_NS 10000000
+
+static void cpu_throttle_thread(CPUState *cpu, run_on_cpu_data opaque)
+{
+    double pct;
+    double throttle_ratio;
+    int64_t sleeptime_ns, endtime_ns;
+
+    if (!cpu_throttle_get_percentage()) {
+        return;
+    }
+
+    pct = (double)cpu_throttle_get_percentage() / 100;
+    throttle_ratio = pct / (1 - pct);
+    /* Add 1ns to fix double's rounding error (like 0.9999999...) */
+    sleeptime_ns = (int64_t)(throttle_ratio * CPU_THROTTLE_TIMESLICE_NS + 1);
+    endtime_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + sleeptime_ns;
+    while (sleeptime_ns > 0 && !cpu->stop) {
+        if (sleeptime_ns > SCALE_MS) {
+            qemu_cond_timedwait_iothread(cpu->halt_cond,
+                                         sleeptime_ns / SCALE_MS);
+        } else {
+            qemu_mutex_unlock_iothread();
+            g_usleep(sleeptime_ns / SCALE_US);
+            qemu_mutex_lock_iothread();
+        }
+        sleeptime_ns = endtime_ns - qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+    }
+    atomic_set(&cpu->throttle_thread_scheduled, 0);
+}
+
+static void cpu_throttle_timer_tick(void *opaque)
+{
+    CPUState *cpu;
+    double pct;
+
+    /* Stop the timer if needed */
+    if (!cpu_throttle_get_percentage()) {
+        return;
+    }
+    CPU_FOREACH(cpu) {
+        if (!atomic_xchg(&cpu->throttle_thread_scheduled, 1)) {
+            async_run_on_cpu(cpu, cpu_throttle_thread,
+                             RUN_ON_CPU_NULL);
+        }
+    }
+
+    pct = (double)cpu_throttle_get_percentage() / 100;
+    timer_mod(throttle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) +
+                                   CPU_THROTTLE_TIMESLICE_NS / (1 - pct));
+}
+
+void cpu_throttle_set(int new_throttle_pct)
+{
+    /* Ensure throttle percentage is within valid range */
+    new_throttle_pct = MIN(new_throttle_pct, CPU_THROTTLE_PCT_MAX);
+    new_throttle_pct = MAX(new_throttle_pct, CPU_THROTTLE_PCT_MIN);
+
+    atomic_set(&throttle_percentage, new_throttle_pct);
+
+    timer_mod(throttle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) +
+                                       CPU_THROTTLE_TIMESLICE_NS);
+}
+
+void cpu_throttle_stop(void)
+{
+    atomic_set(&throttle_percentage, 0);
+}
+
+bool cpu_throttle_active(void)
+{
+    return (cpu_throttle_get_percentage() != 0);
+}
+
+int cpu_throttle_get_percentage(void)
+{
+    return atomic_read(&throttle_percentage);
+}
+
+void cpu_throttle_init(void)
+{
+    throttle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
+                                  cpu_throttle_timer_tick, NULL);
+}
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
index d94456ed29..a802e899ab 100644
--- a/softmmu/cpus.c
+++ b/softmmu/cpus.c
@@ -61,6 +61,8 @@
 #include "hw/boards.h"
 #include "hw/hw.h"
 
+#include "sysemu/cpu-throttle.h"
+
 #ifdef CONFIG_LINUX
 
 #include <sys/prctl.h>
@@ -84,14 +86,6 @@ static QemuMutex qemu_global_mutex;
 int64_t max_delay;
 int64_t max_advance;
 
-/* vcpu throttling controls */
-static QEMUTimer *throttle_timer;
-static unsigned int throttle_percentage;
-
-#define CPU_THROTTLE_PCT_MIN 1
-#define CPU_THROTTLE_PCT_MAX 99
-#define CPU_THROTTLE_TIMESLICE_NS 10000000
-
 bool cpu_is_stopped(CPUState *cpu)
 {
     return cpu->stopped || !runstate_is_running();
@@ -738,90 +732,12 @@ static const VMStateDescription vmstate_timers = {
     }
 };
 
-static void cpu_throttle_thread(CPUState *cpu, run_on_cpu_data opaque)
-{
-    double pct;
-    double throttle_ratio;
-    int64_t sleeptime_ns, endtime_ns;
-
-    if (!cpu_throttle_get_percentage()) {
-        return;
-    }
-
-    pct = (double)cpu_throttle_get_percentage()/100;
-    throttle_ratio = pct / (1 - pct);
-    /* Add 1ns to fix double's rounding error (like 0.9999999...) */
-    sleeptime_ns = (int64_t)(throttle_ratio * CPU_THROTTLE_TIMESLICE_NS + 1);
-    endtime_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + sleeptime_ns;
-    while (sleeptime_ns > 0 && !cpu->stop) {
-        if (sleeptime_ns > SCALE_MS) {
-            qemu_cond_timedwait(cpu->halt_cond, &qemu_global_mutex,
-                                sleeptime_ns / SCALE_MS);
-        } else {
-            qemu_mutex_unlock_iothread();
-            g_usleep(sleeptime_ns / SCALE_US);
-            qemu_mutex_lock_iothread();
-        }
-        sleeptime_ns = endtime_ns - qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-    }
-    atomic_set(&cpu->throttle_thread_scheduled, 0);
-}
-
-static void cpu_throttle_timer_tick(void *opaque)
-{
-    CPUState *cpu;
-    double pct;
-
-    /* Stop the timer if needed */
-    if (!cpu_throttle_get_percentage()) {
-        return;
-    }
-    CPU_FOREACH(cpu) {
-        if (!atomic_xchg(&cpu->throttle_thread_scheduled, 1)) {
-            async_run_on_cpu(cpu, cpu_throttle_thread,
-                             RUN_ON_CPU_NULL);
-        }
-    }
-
-    pct = (double)cpu_throttle_get_percentage()/100;
-    timer_mod(throttle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) +
-                                   CPU_THROTTLE_TIMESLICE_NS / (1-pct));
-}
-
-void cpu_throttle_set(int new_throttle_pct)
-{
-    /* Ensure throttle percentage is within valid range */
-    new_throttle_pct = MIN(new_throttle_pct, CPU_THROTTLE_PCT_MAX);
-    new_throttle_pct = MAX(new_throttle_pct, CPU_THROTTLE_PCT_MIN);
-
-    atomic_set(&throttle_percentage, new_throttle_pct);
-
-    timer_mod(throttle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) +
-                                       CPU_THROTTLE_TIMESLICE_NS);
-}
-
-void cpu_throttle_stop(void)
-{
-    atomic_set(&throttle_percentage, 0);
-}
-
-bool cpu_throttle_active(void)
-{
-    return (cpu_throttle_get_percentage() != 0);
-}
-
-int cpu_throttle_get_percentage(void)
-{
-    return atomic_read(&throttle_percentage);
-}
-
 void cpu_ticks_init(void)
 {
     seqlock_init(&timers_state.vm_clock_seqlock);
     qemu_spin_init(&timers_state.vm_clock_lock);
     vmstate_register(NULL, 0, &vmstate_timers, &timers_state);
-    throttle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
-                                           cpu_throttle_timer_tick, NULL);
+    cpu_throttle_init();
 }
 
 void configure_icount(QemuOpts *opts, Error **errp)
@@ -1879,6 +1795,11 @@ void qemu_cond_wait_iothread(QemuCond *cond)
     qemu_cond_wait(cond, &qemu_global_mutex);
 }
 
+void qemu_cond_timedwait_iothread(QemuCond *cond, int ms)
+{
+    qemu_cond_timedwait(cond, &qemu_global_mutex, ms);
+}
+
 static bool all_vcpus_paused(void)
 {
     CPUState *cpu;
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 43/53] cpu-timers, icount: new modules
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (41 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 42/53] cpu-throttle: new module, extracted from cpus.c Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 44/53] softmmu/vl: Remove the check for colons in -accel parameters Paolo Bonzini
                   ` (11 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Claudio Fontana

From: Claudio Fontana <cfontana@suse.de>

refactoring of cpus.c continues with cpu timer state extraction.

cpu-timers: responsible for the cpu timers state, and for access to
cpu clocks and ticks.

icount: counts the TCG instructions executed. As such it is specific to
the TCG accelerator. Therefore, it is built only under CONFIG_TCG.

One complication is due to qtest, which misuses icount to warp time
(qtest_clock_warp). In order to solve this problem, detach instead qtest
from icount, and use a trivial separate counter for it.

This requires fixing assumptions scattered in the code that
qtest_enabled() implies icount_enabled().

No functionality change.

Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20200629093504.3228-4-cfontana@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 MAINTAINERS                  |   2 +
 accel/qtest.c                |   6 +-
 accel/tcg/cpu-exec.c         |  43 +-
 accel/tcg/tcg-all.c          |   7 +-
 accel/tcg/translate-all.c    |   3 +-
 dma-helpers.c                |   4 +-
 docs/replay.txt              |   6 +-
 exec.c                       |   4 -
 hw/core/ptimer.c             |   8 +-
 hw/i386/x86.c                |   1 +
 include/exec/cpu-all.h       |   4 +
 include/exec/exec-all.h      |   4 +-
 include/qemu/timer.h         |  22 +-
 include/sysemu/cpu-timers.h  |  81 ++++
 include/sysemu/cpus.h        |  12 +-
 include/sysemu/qtest.h       |   2 +
 include/sysemu/replay.h      |   4 +-
 replay/replay.c              |   6 +-
 softmmu/Makefile.objs        |   2 +
 softmmu/cpu-timers.c         | 284 +++++++++++++
 softmmu/cpus.c               | 750 +----------------------------------
 softmmu/icount.c             | 499 +++++++++++++++++++++++
 softmmu/qtest.c              |  34 +-
 softmmu/timers-state.h       |  69 ++++
 softmmu/vl.c                 |   8 +-
 stubs/Makefile.objs          |   3 +-
 stubs/clock-warp.c           |   4 +-
 stubs/cpu-get-clock.c        |   3 +-
 stubs/cpu-get-icount.c       |  21 -
 stubs/icount.c               |  22 +
 stubs/qemu-timer-notify-cb.c |   8 +
 stubs/qtest.c                |   5 +
 target/alpha/translate.c     |   3 +-
 target/arm/helper.c          |   7 +-
 target/riscv/csr.c           |   8 +-
 tests/ptimer-test-stubs.c    |   7 +-
 tests/test-timed-average.c   |   2 +-
 util/main-loop.c             |   4 +-
 util/qemu-timer.c            |  12 +-
 39 files changed, 1121 insertions(+), 853 deletions(-)
 create mode 100644 include/sysemu/cpu-timers.h
 create mode 100644 softmmu/cpu-timers.c
 create mode 100644 softmmu/icount.c
 create mode 100644 softmmu/timers-state.h
 delete mode 100644 stubs/cpu-get-icount.c
 create mode 100644 stubs/icount.c
 create mode 100644 stubs/qemu-timer-notify-cb.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 933c646a86..de4f0d238f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2236,6 +2236,8 @@ F: softmmu/vl.c
 F: softmmu/main.c
 F: softmmu/cpus.c
 F: softmmu/cpu-throttle.c
+F: softmmu/cpu-timers.c
+F: softmmu/icount.c
 F: qapi/run-state.json
 
 Human Monitor (HMP)
diff --git a/accel/qtest.c b/accel/qtest.c
index 5b88f55921..119d0f16a4 100644
--- a/accel/qtest.c
+++ b/accel/qtest.c
@@ -19,14 +19,10 @@
 #include "sysemu/accel.h"
 #include "sysemu/qtest.h"
 #include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
 
 static int qtest_init_accel(MachineState *ms)
 {
-    QemuOpts *opts = qemu_opts_create(qemu_find_opts("icount"), NULL, 0,
-                                      &error_abort);
-    qemu_opt_set(opts, "shift", "0", &error_abort);
-    configure_icount(opts, &error_abort);
-    qemu_opts_del(opts);
     return 0;
 }
 
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index d95c4848a4..82155c1db3 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -19,6 +19,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
+#include "qemu/qemu-print.h"
 #include "cpu.h"
 #include "trace.h"
 #include "disas/disas.h"
@@ -36,6 +37,8 @@
 #include "hw/i386/apic.h"
 #endif
 #include "sysemu/cpus.h"
+#include "exec/cpu-all.h"
+#include "sysemu/cpu-timers.h"
 #include "sysemu/replay.h"
 
 /* -icount align implementation. */
@@ -56,6 +59,9 @@ typedef struct SyncClocks {
 #define MAX_DELAY_PRINT_RATE 2000000000LL
 #define MAX_NB_PRINTS 100
 
+static int64_t max_delay;
+static int64_t max_advance;
+
 static void align_clocks(SyncClocks *sc, CPUState *cpu)
 {
     int64_t cpu_icount;
@@ -65,7 +71,7 @@ static void align_clocks(SyncClocks *sc, CPUState *cpu)
     }
 
     cpu_icount = cpu->icount_extra + cpu_neg(cpu)->icount_decr.u16.low;
-    sc->diff_clk += cpu_icount_to_ns(sc->last_cpu_icount - cpu_icount);
+    sc->diff_clk += icount_to_ns(sc->last_cpu_icount - cpu_icount);
     sc->last_cpu_icount = cpu_icount;
 
     if (sc->diff_clk > VM_CLOCK_ADVANCE) {
@@ -98,9 +104,9 @@ static void print_delay(const SyncClocks *sc)
             (-sc->diff_clk / (float)1000000000LL <
              (threshold_delay - THRESHOLD_REDUCE))) {
             threshold_delay = (-sc->diff_clk / 1000000000LL) + 1;
-            printf("Warning: The guest is now late by %.1f to %.1f seconds\n",
-                   threshold_delay - 1,
-                   threshold_delay);
+            qemu_printf("Warning: The guest is now late by %.1f to %.1f seconds\n",
+                        threshold_delay - 1,
+                        threshold_delay);
             nb_prints++;
             last_realtime_clock = sc->realtime_clock;
         }
@@ -597,7 +603,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
 
     /* Finally, check if we need to exit to the main loop.  */
     if (unlikely(atomic_read(&cpu->exit_request))
-        || (use_icount
+        || (icount_enabled()
             && cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra == 0)) {
         atomic_set(&cpu->exit_request, 0);
         if (cpu->exception_index == -1) {
@@ -638,10 +644,10 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
     }
 
     /* Instruction counter expired.  */
-    assert(use_icount);
+    assert(icount_enabled());
 #ifndef CONFIG_USER_ONLY
     /* Ensure global icount has gone forward */
-    cpu_update_icount(cpu);
+    icount_update(cpu);
     /* Refill decrementer and continue execution.  */
     insns_left = MIN(0xffff, cpu->icount_budget);
     cpu_neg(cpu)->icount_decr.u16.low = insns_left;
@@ -741,3 +747,26 @@ int cpu_exec(CPUState *cpu)
 
     return ret;
 }
+
+#ifndef CONFIG_USER_ONLY
+
+void dump_drift_info(void)
+{
+    if (!icount_enabled()) {
+        return;
+    }
+
+    qemu_printf("Host - Guest clock  %"PRIi64" ms\n",
+                (cpu_get_clock() - icount_get()) / SCALE_MS);
+    if (icount_align_option) {
+        qemu_printf("Max guest delay     %"PRIi64" ms\n",
+                    -max_delay / SCALE_MS);
+        qemu_printf("Max guest advance   %"PRIi64" ms\n",
+                    max_advance / SCALE_MS);
+    } else {
+        qemu_printf("Max guest delay     NA\n");
+        qemu_printf("Max guest advance   NA\n");
+    }
+}
+
+#endif /* !CONFIG_USER_ONLY */
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 3b4fda5640..e27385d051 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -29,6 +29,7 @@
 #include "qom/object.h"
 #include "cpu.h"
 #include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
 #include "qemu/main-loop.h"
 #include "tcg/tcg.h"
 #include "qapi/error.h"
@@ -65,7 +66,7 @@ static void tcg_handle_interrupt(CPUState *cpu, int mask)
         qemu_cpu_kick(cpu);
     } else {
         atomic_set(&cpu_neg(cpu)->icount_decr.u16.high, -1);
-        if (use_icount &&
+        if (icount_enabled() &&
             !cpu->can_do_io
             && (mask & ~old_mask) != 0) {
             cpu_abort(cpu, "Raised interrupt while not in I/O function");
@@ -104,7 +105,7 @@ static bool check_tcg_memory_orders_compatible(void)
 
 static bool default_mttcg_enabled(void)
 {
-    if (use_icount || TCG_OVERSIZED_GUEST) {
+    if (icount_enabled() || TCG_OVERSIZED_GUEST) {
         return false;
     } else {
 #ifdef TARGET_SUPPORTS_MTTCG
@@ -146,7 +147,7 @@ static void tcg_set_thread(Object *obj, const char *value, Error **errp)
     if (strcmp(value, "multi") == 0) {
         if (TCG_OVERSIZED_GUEST) {
             error_setg(errp, "No MTTCG when guest word size > hosts");
-        } else if (use_icount) {
+        } else if (icount_enabled()) {
             error_setg(errp, "No MTTCG when icount is enabled");
         } else {
 #ifndef TARGET_SUPPORTS_MTTCG
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 2afa46bd2b..abd22d8d12 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -57,6 +57,7 @@
 #include "qemu/main-loop.h"
 #include "exec/log.h"
 #include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
 #include "sysemu/tcg.h"
 
 /* #define DEBUG_TB_INVALIDATE */
@@ -369,7 +370,7 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
 
  found:
     if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) {
-        assert(use_icount);
+        assert(icount_enabled());
         /* Reset the cycle counter to the start of the block
            and shift if to the number of actually executed instructions */
         cpu_neg(cpu)->icount_decr.u16.low += num_insns - i;
diff --git a/dma-helpers.c b/dma-helpers.c
index 2a77b5a9cb..240ef4d5b8 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -13,7 +13,7 @@
 #include "trace-root.h"
 #include "qemu/thread.h"
 #include "qemu/main-loop.h"
-#include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
 #include "qemu/range.h"
 
 /* #define DEBUG_IOMMU */
@@ -151,7 +151,7 @@ static void dma_blk_cb(void *opaque, int ret)
          * from several sectors. This code splits all SGs into several
          * groups. SGs in every group do not overlap.
          */
-        if (mem && use_icount && dbs->dir == DMA_DIRECTION_FROM_DEVICE) {
+        if (mem && icount_enabled() && dbs->dir == DMA_DIRECTION_FROM_DEVICE) {
             int i;
             for (i = 0 ; i < dbs->iov.niov ; ++i) {
                 if (ranges_overlap((intptr_t)dbs->iov.iov[i].iov_base,
diff --git a/docs/replay.txt b/docs/replay.txt
index 70c27edb36..8952e6d852 100644
--- a/docs/replay.txt
+++ b/docs/replay.txt
@@ -184,11 +184,11 @@ is then incremented (which is called "warping" the virtual clock) as
 soon as the timer fires or the CPUs need to go out of the idle state.
 Two functions are used for this purpose; because these actions change
 virtual machine state and must be deterministic, each of them creates a
-checkpoint.  qemu_start_warp_timer checks if the CPUs are idle and if so
-starts accounting real time to virtual clock.  qemu_account_warp_timer
+checkpoint.  icount_start_warp_timer checks if the CPUs are idle and if so
+starts accounting real time to virtual clock.  icount_account_warp_timer
 is called when the CPUs get an interrupt or when the warp timer fires,
 and it warps the virtual clock by the amount of real time that has passed
-since qemu_start_warp_timer.
+since icount_start_warp_timer.
 
 Bottom halves
 -------------
diff --git a/exec.c b/exec.c
index 997b7db15f..a780e275c4 100644
--- a/exec.c
+++ b/exec.c
@@ -102,10 +102,6 @@ uintptr_t qemu_host_page_size;
 intptr_t qemu_host_page_mask;
 
 #if !defined(CONFIG_USER_ONLY)
-/* 0 = Do not count executed instructions.
-   1 = Precise instruction counting.
-   2 = Adaptive rate instruction counting.  */
-int use_icount;
 
 typedef struct PhysPageEntry PhysPageEntry;
 
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
index b5a54e2536..c6d2beb1da 100644
--- a/hw/core/ptimer.c
+++ b/hw/core/ptimer.c
@@ -7,11 +7,11 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/timer.h"
 #include "hw/ptimer.h"
 #include "migration/vmstate.h"
 #include "qemu/host-utils.h"
 #include "sysemu/replay.h"
+#include "sysemu/cpu-timers.h"
 #include "sysemu/qtest.h"
 #include "block/aio.h"
 #include "sysemu/cpus.h"
@@ -134,7 +134,8 @@ static void ptimer_reload(ptimer_state *s, int delta_adjust)
      * on the current generation of host machines.
      */
 
-    if (s->enabled == 1 && (delta * period < 10000) && !use_icount) {
+    if (s->enabled == 1 && (delta * period < 10000) &&
+        !icount_enabled() && !qtest_enabled()) {
         period = 10000 / delta;
         period_frac = 0;
     }
@@ -217,7 +218,8 @@ uint64_t ptimer_get_count(ptimer_state *s)
             uint32_t period_frac = s->period_frac;
             uint64_t period = s->period;
 
-            if (!oneshot && (s->delta * period < 10000) && !use_icount) {
+            if (!oneshot && (s->delta * period < 10000) &&
+                !icount_enabled() && !qtest_enabled()) {
                 period = 10000 / s->delta;
                 period_frac = 0;
             }
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 34229b45c7..a6dc5900fe 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -34,6 +34,7 @@
 #include "sysemu/numa.h"
 #include "sysemu/replay.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/cpu-timers.h"
 #include "trace.h"
 
 #include "hw/i386/x86.h"
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index fc403d456b..25b6005a91 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -407,8 +407,12 @@ static inline bool tlb_hit(target_ulong tlb_addr, target_ulong addr)
     return tlb_hit_page(tlb_addr, addr & TARGET_PAGE_MASK);
 }
 
+#ifdef CONFIG_TCG
+void dump_drift_info(void);
 void dump_exec_info(void);
 void dump_opcount_info(void);
+#endif /* CONFIG_TCG */
+
 #endif /* !CONFIG_USER_ONLY */
 
 /* Returns: 0 on success, -1 on error */
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 3cf88272df..e019b505a5 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -25,7 +25,7 @@
 #ifdef CONFIG_TCG
 #include "exec/cpu_ldst.h"
 #endif
-#include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
 
 /* allow to see translation results - the slowdown should be negligible, so we leave it */
 #define DEBUG_DISAS
@@ -497,7 +497,7 @@ static inline uint32_t tb_cflags(const TranslationBlock *tb)
 static inline uint32_t curr_cflags(void)
 {
     return (parallel_cpus ? CF_PARALLEL : 0)
-         | (use_icount ? CF_USE_ICOUNT : 0);
+         | (icount_enabled() ? CF_USE_ICOUNT : 0);
 }
 
 /* TranslationBlock invalidate API */
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 6a8b48b5a9..5336c756d5 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -166,7 +166,7 @@ bool qemu_clock_expired(QEMUClockType type);
  *
  * Determine whether a clock should be used for deadline
  * calculations. Some clocks, for instance vm_clock with
- * use_icount set, do not count in nanoseconds. Such clocks
+ * icount_enabled() set, do not count in nanoseconds. Such clocks
  * are not used for deadline calculations, and are presumed
  * to interrupt any poll using qemu_notify/aio_notify
  * etc.
@@ -224,13 +224,6 @@ void qemu_clock_notify(QEMUClockType type);
  */
 void qemu_clock_enable(QEMUClockType type, bool enabled);
 
-/**
- * qemu_start_warp_timer:
- *
- * Starts a timer for virtual clock update
- */
-void qemu_start_warp_timer(void);
-
 /**
  * qemu_clock_run_timers:
  * @type: clock on which to operate
@@ -791,12 +784,6 @@ static inline int64_t qemu_soonest_timeout(int64_t timeout1, int64_t timeout2)
  */
 void init_clocks(QEMUTimerListNotifyCB *notify_cb);
 
-int64_t cpu_get_ticks(void);
-/* Caller must hold BQL */
-void cpu_enable_ticks(void);
-/* Caller must hold BQL */
-void cpu_disable_ticks(void);
-
 static inline int64_t get_max_clock_jump(void)
 {
     /* This should be small enough to prevent excessive interrupts from being
@@ -850,13 +837,6 @@ static inline int64_t get_clock(void)
 }
 #endif
 
-/* icount */
-int64_t cpu_get_icount_raw(void);
-int64_t cpu_get_icount(void);
-int64_t cpu_get_clock(void);
-int64_t cpu_icount_to_ns(int64_t icount);
-void    cpu_update_icount(CPUState *cpu);
-
 /*******************************************/
 /* host CPU ticks (if available) */
 
diff --git a/include/sysemu/cpu-timers.h b/include/sysemu/cpu-timers.h
new file mode 100644
index 0000000000..07d724672f
--- /dev/null
+++ b/include/sysemu/cpu-timers.h
@@ -0,0 +1,81 @@
+/*
+ * CPU timers state API
+ *
+ * Copyright 2020 SUSE LLC
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#ifndef SYSEMU_CPU_TIMERS_H
+#define SYSEMU_CPU_TIMERS_H
+
+#include "qemu/timer.h"
+
+/* init the whole cpu timers API, including icount, ticks, and cpu_throttle */
+void cpu_timers_init(void);
+
+/* icount - Instruction Counter API */
+
+/*
+ * Return the icount enablement state:
+ *
+ * 0 = Disabled - Do not count executed instructions.
+ * 1 = Enabled - Fixed conversion of insn to ns via "shift" option
+ * 2 = Enabled - Runtime adaptive algorithm to compute shift
+ */
+int icount_enabled(void);
+/*
+ * Update the icount with the executed instructions. Called by
+ * cpus-tcg vCPU thread so the main-loop can see time has moved forward.
+ */
+void icount_update(CPUState *cpu);
+
+/* get raw icount value */
+int64_t icount_get_raw(void);
+
+/* return the virtual CPU time in ns, based on the instruction counter. */
+int64_t icount_get(void);
+/*
+ * convert an instruction counter value to ns, based on the icount shift.
+ * This shift is set as a fixed value with the icount "shift" option
+ * (precise mode), or it is constantly approximated and corrected at
+ * runtime in adaptive mode.
+ */
+int64_t icount_to_ns(int64_t icount);
+
+/* configure the icount options, including "shift" */
+void icount_configure(QemuOpts *opts, Error **errp);
+
+/* used by tcg vcpu thread to calc icount budget */
+int64_t icount_round(int64_t count);
+
+/* if the CPUs are idle, start accounting real time to virtual clock. */
+void icount_start_warp_timer(void);
+void icount_account_warp_timer(void);
+
+/*
+ * CPU Ticks and Clock
+ */
+
+/* Caller must hold BQL */
+void cpu_enable_ticks(void);
+/* Caller must hold BQL */
+void cpu_disable_ticks(void);
+
+/*
+ * return the time elapsed in VM between vm_start and vm_stop.  Unless
+ * icount is active, cpu_get_ticks() uses units of the host CPU cycle
+ * counter.
+ */
+int64_t cpu_get_ticks(void);
+
+/*
+ * Returns the monotonic time elapsed in VM, i.e.,
+ * the time between vm_start and vm_stop
+ */
+int64_t cpu_get_clock(void);
+
+void qemu_timer_notify_cb(void *opaque, QEMUClockType type);
+
+#endif /* SYSEMU_CPU_TIMERS_H */
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 3c1da6a018..149de000a0 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -4,33 +4,23 @@
 #include "qemu/timer.h"
 
 /* cpus.c */
+bool all_cpu_threads_idle(void);
 bool qemu_in_vcpu_thread(void);
 void qemu_init_cpu_loop(void);
 void resume_all_vcpus(void);
 void pause_all_vcpus(void);
 void cpu_stop_current(void);
-void cpu_ticks_init(void);
 
-void configure_icount(QemuOpts *opts, Error **errp);
-extern int use_icount;
 extern int icount_align_option;
 
-/* drift information for info jit command */
-extern int64_t max_delay;
-extern int64_t max_advance;
-void dump_drift_info(void);
-
 /* Unblock cpu */
 void qemu_cpu_kick_self(void);
-void qemu_timer_notify_cb(void *opaque, QEMUClockType type);
 
 void cpu_synchronize_all_states(void);
 void cpu_synchronize_all_post_reset(void);
 void cpu_synchronize_all_post_init(void);
 void cpu_synchronize_all_pre_loadvm(void);
 
-void qtest_clock_warp(int64_t dest);
-
 #ifndef CONFIG_USER_ONLY
 /* vl.c */
 /* *-user doesn't have configurable SMP topology */
diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
index eedd3664f0..91acc98ac4 100644
--- a/include/sysemu/qtest.h
+++ b/include/sysemu/qtest.h
@@ -30,4 +30,6 @@ void qtest_server_set_send_handler(void (*send)(void *, const char *),
                                  void *opaque);
 void qtest_server_inproc_recv(void *opaque, const char *buf);
 
+int64_t qtest_get_clock(void);
+
 #endif
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index 5471bb514d..a140d69a73 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -109,12 +109,12 @@ int64_t replay_read_clock(ReplayClockKind kind);
 #define REPLAY_CLOCK(clock, value)                                      \
     (replay_mode == REPLAY_MODE_PLAY ? replay_read_clock((clock))       \
         : replay_mode == REPLAY_MODE_RECORD                             \
-            ? replay_save_clock((clock), (value), cpu_get_icount_raw()) \
+            ? replay_save_clock((clock), (value), icount_get_raw()) \
         : (value))
 #define REPLAY_CLOCK_LOCKED(clock, value)                               \
     (replay_mode == REPLAY_MODE_PLAY ? replay_read_clock((clock))       \
         : replay_mode == REPLAY_MODE_RECORD                             \
-            ? replay_save_clock((clock), (value), cpu_get_icount_raw_locked()) \
+            ? replay_save_clock((clock), (value), icount_get_raw_locked()) \
         : (value))
 
 /* Processing data from random generators */
diff --git a/replay/replay.c b/replay/replay.c
index 83ed9e0e24..4c1457b07e 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -11,10 +11,10 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "sysemu/cpu-timers.h"
 #include "sysemu/replay.h"
 #include "sysemu/runstate.h"
 #include "replay-internal.h"
-#include "qemu/timer.h"
 #include "qemu/main-loop.h"
 #include "qemu/option.h"
 #include "sysemu/cpus.h"
@@ -64,7 +64,7 @@ bool replay_next_event_is(int event)
 
 uint64_t replay_get_current_icount(void)
 {
-    return cpu_get_icount_raw();
+    return icount_get_raw();
 }
 
 int replay_get_instructions(void)
@@ -345,7 +345,7 @@ void replay_start(void)
         error_reportf_err(replay_blockers->data, "Record/replay: ");
         exit(1);
     }
-    if (!use_icount) {
+    if (!icount_enabled()) {
         error_report("Please enable icount to use record/replay");
         exit(1);
     }
diff --git a/softmmu/Makefile.objs b/softmmu/Makefile.objs
index a414a74c50..9c0125f37b 100644
--- a/softmmu/Makefile.objs
+++ b/softmmu/Makefile.objs
@@ -7,6 +7,8 @@ obj-y += balloon.o
 obj-y += ioport.o
 obj-y += memory.o
 obj-y += memory_mapping.o
+obj-y += cpu-timers.o
+obj-$(CONFIG_TCG) += icount.o
 
 obj-y += qtest.o
 
diff --git a/softmmu/cpu-timers.c b/softmmu/cpu-timers.c
new file mode 100644
index 0000000000..64addb315d
--- /dev/null
+++ b/softmmu/cpu-timers.c
@@ -0,0 +1,284 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * 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 "qemu-common.h"
+#include "qemu/cutils.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "exec/exec-all.h"
+#include "sysemu/cpus.h"
+#include "sysemu/qtest.h"
+#include "qemu/main-loop.h"
+#include "qemu/option.h"
+#include "qemu/seqlock.h"
+#include "sysemu/replay.h"
+#include "sysemu/runstate.h"
+#include "hw/core/cpu.h"
+#include "sysemu/cpu-timers.h"
+#include "sysemu/cpu-throttle.h"
+#include "timers-state.h"
+
+/* clock and ticks */
+
+static int64_t cpu_get_ticks_locked(void)
+{
+    int64_t ticks = timers_state.cpu_ticks_offset;
+    if (timers_state.cpu_ticks_enabled) {
+        ticks += cpu_get_host_ticks();
+    }
+
+    if (timers_state.cpu_ticks_prev > ticks) {
+        /* Non increasing ticks may happen if the host uses software suspend. */
+        timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
+        ticks = timers_state.cpu_ticks_prev;
+    }
+
+    timers_state.cpu_ticks_prev = ticks;
+    return ticks;
+}
+
+/*
+ * return the time elapsed in VM between vm_start and vm_stop.  Unless
+ * icount is active, cpu_get_ticks() uses units of the host CPU cycle
+ * counter.
+ */
+int64_t cpu_get_ticks(void)
+{
+    int64_t ticks;
+
+    if (icount_enabled()) {
+        return icount_get();
+    }
+
+    qemu_spin_lock(&timers_state.vm_clock_lock);
+    ticks = cpu_get_ticks_locked();
+    qemu_spin_unlock(&timers_state.vm_clock_lock);
+    return ticks;
+}
+
+int64_t cpu_get_clock_locked(void)
+{
+    int64_t time;
+
+    time = timers_state.cpu_clock_offset;
+    if (timers_state.cpu_ticks_enabled) {
+        time += get_clock();
+    }
+
+    return time;
+}
+
+/*
+ * Return the monotonic time elapsed in VM, i.e.,
+ * the time between vm_start and vm_stop
+ */
+int64_t cpu_get_clock(void)
+{
+    int64_t ti;
+    unsigned start;
+
+    do {
+        start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
+        ti = cpu_get_clock_locked();
+    } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
+
+    return ti;
+}
+
+/*
+ * enable cpu_get_ticks()
+ * Caller must hold BQL which serves as mutex for vm_clock_seqlock.
+ */
+void cpu_enable_ticks(void)
+{
+    seqlock_write_lock(&timers_state.vm_clock_seqlock,
+                       &timers_state.vm_clock_lock);
+    if (!timers_state.cpu_ticks_enabled) {
+        timers_state.cpu_ticks_offset -= cpu_get_host_ticks();
+        timers_state.cpu_clock_offset -= get_clock();
+        timers_state.cpu_ticks_enabled = 1;
+    }
+    seqlock_write_unlock(&timers_state.vm_clock_seqlock,
+                       &timers_state.vm_clock_lock);
+}
+
+/*
+ * disable cpu_get_ticks() : the clock is stopped. You must not call
+ * cpu_get_ticks() after that.
+ * Caller must hold BQL which serves as mutex for vm_clock_seqlock.
+ */
+void cpu_disable_ticks(void)
+{
+    seqlock_write_lock(&timers_state.vm_clock_seqlock,
+                       &timers_state.vm_clock_lock);
+    if (timers_state.cpu_ticks_enabled) {
+        timers_state.cpu_ticks_offset += cpu_get_host_ticks();
+        timers_state.cpu_clock_offset = cpu_get_clock_locked();
+        timers_state.cpu_ticks_enabled = 0;
+    }
+    seqlock_write_unlock(&timers_state.vm_clock_seqlock,
+                         &timers_state.vm_clock_lock);
+}
+
+static bool icount_state_needed(void *opaque)
+{
+    return icount_enabled();
+}
+
+static bool icount_shift_state_needed(void *opaque)
+{
+    return icount_enabled() == 2;
+}
+
+static bool warp_timer_state_needed(void *opaque)
+{
+    TimersState *s = opaque;
+    return s->icount_warp_timer != NULL;
+}
+
+static bool adjust_timers_state_needed(void *opaque)
+{
+    TimersState *s = opaque;
+    return s->icount_rt_timer != NULL;
+}
+
+/*
+ * Subsection for warp timer migration is optional, because may not be created
+ */
+static const VMStateDescription icount_vmstate_warp_timer = {
+    .name = "timer/icount/warp_timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = warp_timer_state_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT64(vm_clock_warp_start, TimersState),
+        VMSTATE_TIMER_PTR(icount_warp_timer, TimersState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription icount_vmstate_adjust_timers = {
+    .name = "timer/icount/timers",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = adjust_timers_state_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_TIMER_PTR(icount_rt_timer, TimersState),
+        VMSTATE_TIMER_PTR(icount_vm_timer, TimersState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription icount_vmstate_shift = {
+    .name = "timer/icount/shift",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = icount_shift_state_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT16(icount_time_shift, TimersState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+/*
+ * This is a subsection for icount migration.
+ */
+static const VMStateDescription icount_vmstate_timers = {
+    .name = "timer/icount",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = icount_state_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT64(qemu_icount_bias, TimersState),
+        VMSTATE_INT64(qemu_icount, TimersState),
+        VMSTATE_END_OF_LIST()
+    },
+    .subsections = (const VMStateDescription * []) {
+        &icount_vmstate_warp_timer,
+        &icount_vmstate_adjust_timers,
+        &icount_vmstate_shift,
+        NULL
+    }
+};
+
+static const VMStateDescription vmstate_timers = {
+    .name = "timer",
+    .version_id = 2,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT64(cpu_ticks_offset, TimersState),
+        VMSTATE_UNUSED(8),
+        VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),
+        VMSTATE_END_OF_LIST()
+    },
+    .subsections = (const VMStateDescription * []) {
+        &icount_vmstate_timers,
+        NULL
+    }
+};
+
+static void do_nothing(CPUState *cpu, run_on_cpu_data unused)
+{
+}
+
+void qemu_timer_notify_cb(void *opaque, QEMUClockType type)
+{
+    if (!icount_enabled() || type != QEMU_CLOCK_VIRTUAL) {
+        qemu_notify_event();
+        return;
+    }
+
+    if (qemu_in_vcpu_thread()) {
+        /*
+         * A CPU is currently running; kick it back out to the
+         * tcg_cpu_exec() loop so it will recalculate its
+         * icount deadline immediately.
+         */
+        qemu_cpu_kick(current_cpu);
+    } else if (first_cpu) {
+        /*
+         * qemu_cpu_kick is not enough to kick a halted CPU out of
+         * qemu_tcg_wait_io_event.  async_run_on_cpu, instead,
+         * causes cpu_thread_is_idle to return false.  This way,
+         * handle_icount_deadline can run.
+         * If we have no CPUs at all for some reason, we don't
+         * need to do anything.
+         */
+        async_run_on_cpu(first_cpu, do_nothing, RUN_ON_CPU_NULL);
+    }
+}
+
+TimersState timers_state;
+
+/* initialize timers state and the cpu throttle for convenience */
+void cpu_timers_init(void)
+{
+    seqlock_init(&timers_state.vm_clock_seqlock);
+    qemu_spin_init(&timers_state.vm_clock_lock);
+    vmstate_register(NULL, 0, &vmstate_timers, &timers_state);
+
+    cpu_throttle_init();
+}
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
index a802e899ab..54fdb2761c 100644
--- a/softmmu/cpus.c
+++ b/softmmu/cpus.c
@@ -58,11 +58,10 @@
 #include "hw/nmi.h"
 #include "sysemu/replay.h"
 #include "sysemu/runstate.h"
+#include "sysemu/cpu-timers.h"
 #include "hw/boards.h"
 #include "hw/hw.h"
 
-#include "sysemu/cpu-throttle.h"
-
 #ifdef CONFIG_LINUX
 
 #include <sys/prctl.h>
@@ -83,9 +82,6 @@
 
 static QemuMutex qemu_global_mutex;
 
-int64_t max_delay;
-int64_t max_advance;
-
 bool cpu_is_stopped(CPUState *cpu)
 {
     return cpu->stopped || !runstate_is_running();
@@ -116,7 +112,7 @@ static bool cpu_thread_is_idle(CPUState *cpu)
     return true;
 }
 
-static bool all_cpu_threads_idle(void)
+bool all_cpu_threads_idle(void)
 {
     CPUState *cpu;
 
@@ -128,688 +124,9 @@ static bool all_cpu_threads_idle(void)
     return true;
 }
 
-/***********************************************************/
-/* guest cycle counter */
-
-/* Protected by TimersState seqlock */
-
-static bool icount_sleep = true;
-/* Arbitrarily pick 1MIPS as the minimum allowable speed.  */
-#define MAX_ICOUNT_SHIFT 10
-
-typedef struct TimersState {
-    /* Protected by BQL.  */
-    int64_t cpu_ticks_prev;
-    int64_t cpu_ticks_offset;
-
-    /* Protect fields that can be respectively read outside the
-     * BQL, and written from multiple threads.
-     */
-    QemuSeqLock vm_clock_seqlock;
-    QemuSpin vm_clock_lock;
-
-    int16_t cpu_ticks_enabled;
-
-    /* Conversion factor from emulated instructions to virtual clock ticks.  */
-    int16_t icount_time_shift;
-
-    /* Compensate for varying guest execution speed.  */
-    int64_t qemu_icount_bias;
-
-    int64_t vm_clock_warp_start;
-    int64_t cpu_clock_offset;
-
-    /* Only written by TCG thread */
-    int64_t qemu_icount;
-
-    /* for adjusting icount */
-    QEMUTimer *icount_rt_timer;
-    QEMUTimer *icount_vm_timer;
-    QEMUTimer *icount_warp_timer;
-} TimersState;
-
-static TimersState timers_state;
 bool mttcg_enabled;
 
 
-/* The current number of executed instructions is based on what we
- * originally budgeted minus the current state of the decrementing
- * icount counters in extra/u16.low.
- */
-static int64_t cpu_get_icount_executed(CPUState *cpu)
-{
-    return (cpu->icount_budget -
-            (cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra));
-}
-
-/*
- * Update the global shared timer_state.qemu_icount to take into
- * account executed instructions. This is done by the TCG vCPU
- * thread so the main-loop can see time has moved forward.
- */
-static void cpu_update_icount_locked(CPUState *cpu)
-{
-    int64_t executed = cpu_get_icount_executed(cpu);
-    cpu->icount_budget -= executed;
-
-    atomic_set_i64(&timers_state.qemu_icount,
-                   timers_state.qemu_icount + executed);
-}
-
-/*
- * Update the global shared timer_state.qemu_icount to take into
- * account executed instructions. This is done by the TCG vCPU
- * thread so the main-loop can see time has moved forward.
- */
-void cpu_update_icount(CPUState *cpu)
-{
-    seqlock_write_lock(&timers_state.vm_clock_seqlock,
-                       &timers_state.vm_clock_lock);
-    cpu_update_icount_locked(cpu);
-    seqlock_write_unlock(&timers_state.vm_clock_seqlock,
-                         &timers_state.vm_clock_lock);
-}
-
-static int64_t cpu_get_icount_raw_locked(void)
-{
-    CPUState *cpu = current_cpu;
-
-    if (cpu && cpu->running) {
-        if (!cpu->can_do_io) {
-            error_report("Bad icount read");
-            exit(1);
-        }
-        /* Take into account what has run */
-        cpu_update_icount_locked(cpu);
-    }
-    /* The read is protected by the seqlock, but needs atomic64 to avoid UB */
-    return atomic_read_i64(&timers_state.qemu_icount);
-}
-
-static int64_t cpu_get_icount_locked(void)
-{
-    int64_t icount = cpu_get_icount_raw_locked();
-    return atomic_read_i64(&timers_state.qemu_icount_bias) +
-        cpu_icount_to_ns(icount);
-}
-
-int64_t cpu_get_icount_raw(void)
-{
-    int64_t icount;
-    unsigned start;
-
-    do {
-        start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
-        icount = cpu_get_icount_raw_locked();
-    } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
-
-    return icount;
-}
-
-/* Return the virtual CPU time, based on the instruction counter.  */
-int64_t cpu_get_icount(void)
-{
-    int64_t icount;
-    unsigned start;
-
-    do {
-        start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
-        icount = cpu_get_icount_locked();
-    } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
-
-    return icount;
-}
-
-int64_t cpu_icount_to_ns(int64_t icount)
-{
-    return icount << atomic_read(&timers_state.icount_time_shift);
-}
-
-static int64_t cpu_get_ticks_locked(void)
-{
-    int64_t ticks = timers_state.cpu_ticks_offset;
-    if (timers_state.cpu_ticks_enabled) {
-        ticks += cpu_get_host_ticks();
-    }
-
-    if (timers_state.cpu_ticks_prev > ticks) {
-        /* Non increasing ticks may happen if the host uses software suspend.  */
-        timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
-        ticks = timers_state.cpu_ticks_prev;
-    }
-
-    timers_state.cpu_ticks_prev = ticks;
-    return ticks;
-}
-
-/* return the time elapsed in VM between vm_start and vm_stop.  Unless
- * icount is active, cpu_get_ticks() uses units of the host CPU cycle
- * counter.
- */
-int64_t cpu_get_ticks(void)
-{
-    int64_t ticks;
-
-    if (use_icount) {
-        return cpu_get_icount();
-    }
-
-    qemu_spin_lock(&timers_state.vm_clock_lock);
-    ticks = cpu_get_ticks_locked();
-    qemu_spin_unlock(&timers_state.vm_clock_lock);
-    return ticks;
-}
-
-static int64_t cpu_get_clock_locked(void)
-{
-    int64_t time;
-
-    time = timers_state.cpu_clock_offset;
-    if (timers_state.cpu_ticks_enabled) {
-        time += get_clock();
-    }
-
-    return time;
-}
-
-/* Return the monotonic time elapsed in VM, i.e.,
- * the time between vm_start and vm_stop
- */
-int64_t cpu_get_clock(void)
-{
-    int64_t ti;
-    unsigned start;
-
-    do {
-        start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
-        ti = cpu_get_clock_locked();
-    } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
-
-    return ti;
-}
-
-/* enable cpu_get_ticks()
- * Caller must hold BQL which serves as mutex for vm_clock_seqlock.
- */
-void cpu_enable_ticks(void)
-{
-    seqlock_write_lock(&timers_state.vm_clock_seqlock,
-                       &timers_state.vm_clock_lock);
-    if (!timers_state.cpu_ticks_enabled) {
-        timers_state.cpu_ticks_offset -= cpu_get_host_ticks();
-        timers_state.cpu_clock_offset -= get_clock();
-        timers_state.cpu_ticks_enabled = 1;
-    }
-    seqlock_write_unlock(&timers_state.vm_clock_seqlock,
-                       &timers_state.vm_clock_lock);
-}
-
-/* disable cpu_get_ticks() : the clock is stopped. You must not call
- * cpu_get_ticks() after that.
- * Caller must hold BQL which serves as mutex for vm_clock_seqlock.
- */
-void cpu_disable_ticks(void)
-{
-    seqlock_write_lock(&timers_state.vm_clock_seqlock,
-                       &timers_state.vm_clock_lock);
-    if (timers_state.cpu_ticks_enabled) {
-        timers_state.cpu_ticks_offset += cpu_get_host_ticks();
-        timers_state.cpu_clock_offset = cpu_get_clock_locked();
-        timers_state.cpu_ticks_enabled = 0;
-    }
-    seqlock_write_unlock(&timers_state.vm_clock_seqlock,
-                         &timers_state.vm_clock_lock);
-}
-
-/* Correlation between real and virtual time is always going to be
-   fairly approximate, so ignore small variation.
-   When the guest is idle real and virtual time will be aligned in
-   the IO wait loop.  */
-#define ICOUNT_WOBBLE (NANOSECONDS_PER_SECOND / 10)
-
-static void icount_adjust(void)
-{
-    int64_t cur_time;
-    int64_t cur_icount;
-    int64_t delta;
-
-    /* Protected by TimersState mutex.  */
-    static int64_t last_delta;
-
-    /* If the VM is not running, then do nothing.  */
-    if (!runstate_is_running()) {
-        return;
-    }
-
-    seqlock_write_lock(&timers_state.vm_clock_seqlock,
-                       &timers_state.vm_clock_lock);
-    cur_time = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT,
-                                   cpu_get_clock_locked());
-    cur_icount = cpu_get_icount_locked();
-
-    delta = cur_icount - cur_time;
-    /* FIXME: This is a very crude algorithm, somewhat prone to oscillation.  */
-    if (delta > 0
-        && last_delta + ICOUNT_WOBBLE < delta * 2
-        && timers_state.icount_time_shift > 0) {
-        /* The guest is getting too far ahead.  Slow time down.  */
-        atomic_set(&timers_state.icount_time_shift,
-                   timers_state.icount_time_shift - 1);
-    }
-    if (delta < 0
-        && last_delta - ICOUNT_WOBBLE > delta * 2
-        && timers_state.icount_time_shift < MAX_ICOUNT_SHIFT) {
-        /* The guest is getting too far behind.  Speed time up.  */
-        atomic_set(&timers_state.icount_time_shift,
-                   timers_state.icount_time_shift + 1);
-    }
-    last_delta = delta;
-    atomic_set_i64(&timers_state.qemu_icount_bias,
-                   cur_icount - (timers_state.qemu_icount
-                                 << timers_state.icount_time_shift));
-    seqlock_write_unlock(&timers_state.vm_clock_seqlock,
-                         &timers_state.vm_clock_lock);
-}
-
-static void icount_adjust_rt(void *opaque)
-{
-    timer_mod(timers_state.icount_rt_timer,
-              qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
-    icount_adjust();
-}
-
-static void icount_adjust_vm(void *opaque)
-{
-    timer_mod(timers_state.icount_vm_timer,
-                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-                   NANOSECONDS_PER_SECOND / 10);
-    icount_adjust();
-}
-
-static int64_t qemu_icount_round(int64_t count)
-{
-    int shift = atomic_read(&timers_state.icount_time_shift);
-    return (count + (1 << shift) - 1) >> shift;
-}
-
-static void icount_warp_rt(void)
-{
-    unsigned seq;
-    int64_t warp_start;
-
-    /* The icount_warp_timer is rescheduled soon after vm_clock_warp_start
-     * changes from -1 to another value, so the race here is okay.
-     */
-    do {
-        seq = seqlock_read_begin(&timers_state.vm_clock_seqlock);
-        warp_start = timers_state.vm_clock_warp_start;
-    } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq));
-
-    if (warp_start == -1) {
-        return;
-    }
-
-    seqlock_write_lock(&timers_state.vm_clock_seqlock,
-                       &timers_state.vm_clock_lock);
-    if (runstate_is_running()) {
-        int64_t clock = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT,
-                                            cpu_get_clock_locked());
-        int64_t warp_delta;
-
-        warp_delta = clock - timers_state.vm_clock_warp_start;
-        if (use_icount == 2) {
-            /*
-             * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
-             * far ahead of real time.
-             */
-            int64_t cur_icount = cpu_get_icount_locked();
-            int64_t delta = clock - cur_icount;
-            warp_delta = MIN(warp_delta, delta);
-        }
-        atomic_set_i64(&timers_state.qemu_icount_bias,
-                       timers_state.qemu_icount_bias + warp_delta);
-    }
-    timers_state.vm_clock_warp_start = -1;
-    seqlock_write_unlock(&timers_state.vm_clock_seqlock,
-                       &timers_state.vm_clock_lock);
-
-    if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
-        qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
-    }
-}
-
-static void icount_timer_cb(void *opaque)
-{
-    /* No need for a checkpoint because the timer already synchronizes
-     * with CHECKPOINT_CLOCK_VIRTUAL_RT.
-     */
-    icount_warp_rt();
-}
-
-void qtest_clock_warp(int64_t dest)
-{
-    int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-    AioContext *aio_context;
-    assert(qtest_enabled());
-    aio_context = qemu_get_aio_context();
-    while (clock < dest) {
-        int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
-                                                      QEMU_TIMER_ATTR_ALL);
-        int64_t warp = qemu_soonest_timeout(dest - clock, deadline);
-
-        seqlock_write_lock(&timers_state.vm_clock_seqlock,
-                           &timers_state.vm_clock_lock);
-        atomic_set_i64(&timers_state.qemu_icount_bias,
-                       timers_state.qemu_icount_bias + warp);
-        seqlock_write_unlock(&timers_state.vm_clock_seqlock,
-                             &timers_state.vm_clock_lock);
-
-        qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
-        timerlist_run_timers(aio_context->tlg.tl[QEMU_CLOCK_VIRTUAL]);
-        clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-    }
-    qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
-}
-
-void qemu_start_warp_timer(void)
-{
-    int64_t clock;
-    int64_t deadline;
-
-    if (!use_icount) {
-        return;
-    }
-
-    /* Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers
-     * do not fire, so computing the deadline does not make sense.
-     */
-    if (!runstate_is_running()) {
-        return;
-    }
-
-    if (replay_mode != REPLAY_MODE_PLAY) {
-        if (!all_cpu_threads_idle()) {
-            return;
-        }
-
-        if (qtest_enabled()) {
-            /* When testing, qtest commands advance icount.  */
-            return;
-        }
-
-        replay_checkpoint(CHECKPOINT_CLOCK_WARP_START);
-    } else {
-        /* warp clock deterministically in record/replay mode */
-        if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_START)) {
-            /* vCPU is sleeping and warp can't be started.
-               It is probably a race condition: notification sent
-               to vCPU was processed in advance and vCPU went to sleep.
-               Therefore we have to wake it up for doing someting. */
-            if (replay_has_checkpoint()) {
-                qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
-            }
-            return;
-        }
-    }
-
-    /* We want to use the earliest deadline from ALL vm_clocks */
-    clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT);
-    deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
-                                          ~QEMU_TIMER_ATTR_EXTERNAL);
-    if (deadline < 0) {
-        static bool notified;
-        if (!icount_sleep && !notified) {
-            warn_report("icount sleep disabled and no active timers");
-            notified = true;
-        }
-        return;
-    }
-
-    if (deadline > 0) {
-        /*
-         * Ensure QEMU_CLOCK_VIRTUAL proceeds even when the virtual CPU goes to
-         * sleep.  Otherwise, the CPU might be waiting for a future timer
-         * interrupt to wake it up, but the interrupt never comes because
-         * the vCPU isn't running any insns and thus doesn't advance the
-         * QEMU_CLOCK_VIRTUAL.
-         */
-        if (!icount_sleep) {
-            /*
-             * We never let VCPUs sleep in no sleep icount mode.
-             * If there is a pending QEMU_CLOCK_VIRTUAL timer we just advance
-             * to the next QEMU_CLOCK_VIRTUAL event and notify it.
-             * It is useful when we want a deterministic execution time,
-             * isolated from host latencies.
-             */
-            seqlock_write_lock(&timers_state.vm_clock_seqlock,
-                               &timers_state.vm_clock_lock);
-            atomic_set_i64(&timers_state.qemu_icount_bias,
-                           timers_state.qemu_icount_bias + deadline);
-            seqlock_write_unlock(&timers_state.vm_clock_seqlock,
-                                 &timers_state.vm_clock_lock);
-            qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
-        } else {
-            /*
-             * We do stop VCPUs and only advance QEMU_CLOCK_VIRTUAL after some
-             * "real" time, (related to the time left until the next event) has
-             * passed. The QEMU_CLOCK_VIRTUAL_RT clock will do this.
-             * This avoids that the warps are visible externally; for example,
-             * you will not be sending network packets continuously instead of
-             * every 100ms.
-             */
-            seqlock_write_lock(&timers_state.vm_clock_seqlock,
-                               &timers_state.vm_clock_lock);
-            if (timers_state.vm_clock_warp_start == -1
-                || timers_state.vm_clock_warp_start > clock) {
-                timers_state.vm_clock_warp_start = clock;
-            }
-            seqlock_write_unlock(&timers_state.vm_clock_seqlock,
-                                 &timers_state.vm_clock_lock);
-            timer_mod_anticipate(timers_state.icount_warp_timer,
-                                 clock + deadline);
-        }
-    } else if (deadline == 0) {
-        qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
-    }
-}
-
-static void qemu_account_warp_timer(void)
-{
-    if (!use_icount || !icount_sleep) {
-        return;
-    }
-
-    /* Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers
-     * do not fire, so computing the deadline does not make sense.
-     */
-    if (!runstate_is_running()) {
-        return;
-    }
-
-    /* warp clock deterministically in record/replay mode */
-    if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_ACCOUNT)) {
-        return;
-    }
-
-    timer_del(timers_state.icount_warp_timer);
-    icount_warp_rt();
-}
-
-static bool icount_state_needed(void *opaque)
-{
-    return use_icount;
-}
-
-static bool warp_timer_state_needed(void *opaque)
-{
-    TimersState *s = opaque;
-    return s->icount_warp_timer != NULL;
-}
-
-static bool adjust_timers_state_needed(void *opaque)
-{
-    TimersState *s = opaque;
-    return s->icount_rt_timer != NULL;
-}
-
-static bool shift_state_needed(void *opaque)
-{
-    return use_icount == 2;
-}
-
-/*
- * Subsection for warp timer migration is optional, because may not be created
- */
-static const VMStateDescription icount_vmstate_warp_timer = {
-    .name = "timer/icount/warp_timer",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .needed = warp_timer_state_needed,
-    .fields = (VMStateField[]) {
-        VMSTATE_INT64(vm_clock_warp_start, TimersState),
-        VMSTATE_TIMER_PTR(icount_warp_timer, TimersState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const VMStateDescription icount_vmstate_adjust_timers = {
-    .name = "timer/icount/timers",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .needed = adjust_timers_state_needed,
-    .fields = (VMStateField[]) {
-        VMSTATE_TIMER_PTR(icount_rt_timer, TimersState),
-        VMSTATE_TIMER_PTR(icount_vm_timer, TimersState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const VMStateDescription icount_vmstate_shift = {
-    .name = "timer/icount/shift",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .needed = shift_state_needed,
-    .fields = (VMStateField[]) {
-        VMSTATE_INT16(icount_time_shift, TimersState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-/*
- * This is a subsection for icount migration.
- */
-static const VMStateDescription icount_vmstate_timers = {
-    .name = "timer/icount",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .needed = icount_state_needed,
-    .fields = (VMStateField[]) {
-        VMSTATE_INT64(qemu_icount_bias, TimersState),
-        VMSTATE_INT64(qemu_icount, TimersState),
-        VMSTATE_END_OF_LIST()
-    },
-    .subsections = (const VMStateDescription*[]) {
-        &icount_vmstate_warp_timer,
-        &icount_vmstate_adjust_timers,
-        &icount_vmstate_shift,
-        NULL
-    }
-};
-
-static const VMStateDescription vmstate_timers = {
-    .name = "timer",
-    .version_id = 2,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_INT64(cpu_ticks_offset, TimersState),
-        VMSTATE_UNUSED(8),
-        VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),
-        VMSTATE_END_OF_LIST()
-    },
-    .subsections = (const VMStateDescription*[]) {
-        &icount_vmstate_timers,
-        NULL
-    }
-};
-
-void cpu_ticks_init(void)
-{
-    seqlock_init(&timers_state.vm_clock_seqlock);
-    qemu_spin_init(&timers_state.vm_clock_lock);
-    vmstate_register(NULL, 0, &vmstate_timers, &timers_state);
-    cpu_throttle_init();
-}
-
-void configure_icount(QemuOpts *opts, Error **errp)
-{
-    const char *option = qemu_opt_get(opts, "shift");
-    bool sleep = qemu_opt_get_bool(opts, "sleep", true);
-    bool align = qemu_opt_get_bool(opts, "align", false);
-    long time_shift = -1;
-
-    if (!option) {
-        if (qemu_opt_get(opts, "align") != NULL) {
-            error_setg(errp, "Please specify shift option when using align");
-        }
-        return;
-    }
-
-    if (align && !sleep) {
-        error_setg(errp, "align=on and sleep=off are incompatible");
-        return;
-    }
-
-    if (strcmp(option, "auto") != 0) {
-        if (qemu_strtol(option, NULL, 0, &time_shift) < 0
-            || time_shift < 0 || time_shift > MAX_ICOUNT_SHIFT) {
-            error_setg(errp, "icount: Invalid shift value");
-            return;
-        }
-    } else if (icount_align_option) {
-        error_setg(errp, "shift=auto and align=on are incompatible");
-        return;
-    } else if (!icount_sleep) {
-        error_setg(errp, "shift=auto and sleep=off are incompatible");
-        return;
-    }
-
-    icount_sleep = sleep;
-    if (icount_sleep) {
-        timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
-                                         icount_timer_cb, NULL);
-    }
-
-    icount_align_option = align;
-
-    if (time_shift >= 0) {
-        timers_state.icount_time_shift = time_shift;
-        use_icount = 1;
-        return;
-    }
-
-    use_icount = 2;
-
-    /* 125MIPS seems a reasonable initial guess at the guest speed.
-       It will be corrected fairly quickly anyway.  */
-    timers_state.icount_time_shift = 3;
-
-    /* Have both realtime and virtual time triggers for speed adjustment.
-       The realtime trigger catches emulated time passing too slowly,
-       the virtual time trigger catches emulated time passing too fast.
-       Realtime triggers occur even when idle, so use them less frequently
-       than VM triggers.  */
-    timers_state.vm_clock_warp_start = -1;
-    timers_state.icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT,
-                                   icount_adjust_rt, NULL);
-    timer_mod(timers_state.icount_rt_timer,
-                   qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
-    timers_state.icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-                                        icount_adjust_vm, NULL);
-    timer_mod(timers_state.icount_vm_timer,
-                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-                   NANOSECONDS_PER_SECOND / 10);
-}
-
 /***********************************************************/
 /* TCG vCPU kick timer
  *
@@ -854,35 +171,6 @@ static void qemu_cpu_kick_rr_cpus(void)
     };
 }
 
-static void do_nothing(CPUState *cpu, run_on_cpu_data unused)
-{
-}
-
-void qemu_timer_notify_cb(void *opaque, QEMUClockType type)
-{
-    if (!use_icount || type != QEMU_CLOCK_VIRTUAL) {
-        qemu_notify_event();
-        return;
-    }
-
-    if (qemu_in_vcpu_thread()) {
-        /* A CPU is currently running; kick it back out to the
-         * tcg_cpu_exec() loop so it will recalculate its
-         * icount deadline immediately.
-         */
-        qemu_cpu_kick(current_cpu);
-    } else if (first_cpu) {
-        /* qemu_cpu_kick is not enough to kick a halted CPU out of
-         * qemu_tcg_wait_io_event.  async_run_on_cpu, instead,
-         * causes cpu_thread_is_idle to return false.  This way,
-         * handle_icount_deadline can run.
-         * If we have no CPUs at all for some reason, we don't
-         * need to do anything.
-         */
-        async_run_on_cpu(first_cpu, do_nothing, RUN_ON_CPU_NULL);
-    }
-}
-
 static void kick_tcg_thread(void *opaque)
 {
     timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick());
@@ -1272,7 +560,7 @@ static int64_t tcg_get_icount_limit(void)
             deadline = INT32_MAX;
         }
 
-        return qemu_icount_round(deadline);
+        return icount_round(deadline);
     } else {
         return replay_get_instructions();
     }
@@ -1288,7 +576,7 @@ static void notify_aio_contexts(void)
 static void handle_icount_deadline(void)
 {
     assert(qemu_in_vcpu_thread());
-    if (use_icount) {
+    if (icount_enabled()) {
         int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
                                                       QEMU_TIMER_ATTR_ALL);
 
@@ -1300,7 +588,7 @@ static void handle_icount_deadline(void)
 
 static void prepare_icount_for_run(CPUState *cpu)
 {
-    if (use_icount) {
+    if (icount_enabled()) {
         int insns_left;
 
         /* These should always be cleared by process_icount_data after
@@ -1325,9 +613,9 @@ static void prepare_icount_for_run(CPUState *cpu)
 
 static void process_icount_data(CPUState *cpu)
 {
-    if (use_icount) {
+    if (icount_enabled()) {
         /* Account for executed instructions */
-        cpu_update_icount(cpu);
+        icount_update(cpu);
 
         /* Reset the counters */
         cpu_neg(cpu)->icount_decr.u16.low = 0;
@@ -1428,7 +716,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
         replay_mutex_lock();
         qemu_mutex_lock_iothread();
         /* Account partial waits to QEMU_CLOCK_VIRTUAL.  */
-        qemu_account_warp_timer();
+        icount_account_warp_timer();
 
         /* Run the timers here.  This is much more efficient than
          * waking up the I/O thread and waiting for completion.
@@ -1486,7 +774,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
             atomic_mb_set(&cpu->exit_request, 0);
         }
 
-        if (use_icount && all_cpu_threads_idle()) {
+        if (icount_enabled() && all_cpu_threads_idle()) {
             /*
              * When all cpus are sleeping (e.g in WFI), to avoid a deadlock
              * in the main_loop, wake it up in order to start the warp timer.
@@ -1639,7 +927,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
     CPUState *cpu = arg;
 
     assert(tcg_enabled());
-    g_assert(!use_icount);
+    g_assert(!icount_enabled());
 
     rcu_register_thread();
     tcg_register_thread();
@@ -2218,21 +1506,3 @@ void qmp_inject_nmi(Error **errp)
     nmi_monitor_handle(monitor_get_cpu_index(), errp);
 }
 
-void dump_drift_info(void)
-{
-    if (!use_icount) {
-        return;
-    }
-
-    qemu_printf("Host - Guest clock  %"PRIi64" ms\n",
-                (cpu_get_clock() - cpu_get_icount())/SCALE_MS);
-    if (icount_align_option) {
-        qemu_printf("Max guest delay     %"PRIi64" ms\n",
-                    -max_delay / SCALE_MS);
-        qemu_printf("Max guest advance   %"PRIi64" ms\n",
-                    max_advance / SCALE_MS);
-    } else {
-        qemu_printf("Max guest delay     NA\n");
-        qemu_printf("Max guest advance   NA\n");
-    }
-}
diff --git a/softmmu/icount.c b/softmmu/icount.c
new file mode 100644
index 0000000000..aeede3601c
--- /dev/null
+++ b/softmmu/icount.c
@@ -0,0 +1,499 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * 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 "qemu-common.h"
+#include "qemu/cutils.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "exec/exec-all.h"
+#include "sysemu/cpus.h"
+#include "sysemu/qtest.h"
+#include "qemu/main-loop.h"
+#include "qemu/option.h"
+#include "qemu/seqlock.h"
+#include "sysemu/replay.h"
+#include "sysemu/runstate.h"
+#include "hw/core/cpu.h"
+#include "sysemu/cpu-timers.h"
+#include "sysemu/cpu-throttle.h"
+#include "timers-state.h"
+
+/*
+ * ICOUNT: Instruction Counter
+ *
+ * this module is split off from cpu-timers because the icount part
+ * is TCG-specific, and does not need to be built for other accels.
+ */
+static bool icount_sleep = true;
+/* Arbitrarily pick 1MIPS as the minimum allowable speed.  */
+#define MAX_ICOUNT_SHIFT 10
+
+/*
+ * 0 = Do not count executed instructions.
+ * 1 = Fixed conversion of insn to ns via "shift" option
+ * 2 = Runtime adaptive algorithm to compute shift
+ */
+static int use_icount;
+
+int icount_enabled(void)
+{
+    return use_icount;
+}
+
+static void icount_enable_precise(void)
+{
+    use_icount = 1;
+}
+
+static void icount_enable_adaptive(void)
+{
+    use_icount = 2;
+}
+
+/*
+ * The current number of executed instructions is based on what we
+ * originally budgeted minus the current state of the decrementing
+ * icount counters in extra/u16.low.
+ */
+static int64_t icount_get_executed(CPUState *cpu)
+{
+    return (cpu->icount_budget -
+            (cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra));
+}
+
+/*
+ * Update the global shared timer_state.qemu_icount to take into
+ * account executed instructions. This is done by the TCG vCPU
+ * thread so the main-loop can see time has moved forward.
+ */
+static void icount_update_locked(CPUState *cpu)
+{
+    int64_t executed = icount_get_executed(cpu);
+    cpu->icount_budget -= executed;
+
+    atomic_set_i64(&timers_state.qemu_icount,
+                   timers_state.qemu_icount + executed);
+}
+
+/*
+ * Update the global shared timer_state.qemu_icount to take into
+ * account executed instructions. This is done by the TCG vCPU
+ * thread so the main-loop can see time has moved forward.
+ */
+void icount_update(CPUState *cpu)
+{
+    seqlock_write_lock(&timers_state.vm_clock_seqlock,
+                       &timers_state.vm_clock_lock);
+    icount_update_locked(cpu);
+    seqlock_write_unlock(&timers_state.vm_clock_seqlock,
+                         &timers_state.vm_clock_lock);
+}
+
+static int64_t icount_get_raw_locked(void)
+{
+    CPUState *cpu = current_cpu;
+
+    if (cpu && cpu->running) {
+        if (!cpu->can_do_io) {
+            error_report("Bad icount read");
+            exit(1);
+        }
+        /* Take into account what has run */
+        icount_update_locked(cpu);
+    }
+    /* The read is protected by the seqlock, but needs atomic64 to avoid UB */
+    return atomic_read_i64(&timers_state.qemu_icount);
+}
+
+static int64_t icount_get_locked(void)
+{
+    int64_t icount = icount_get_raw_locked();
+    return atomic_read_i64(&timers_state.qemu_icount_bias) +
+        icount_to_ns(icount);
+}
+
+int64_t icount_get_raw(void)
+{
+    int64_t icount;
+    unsigned start;
+
+    do {
+        start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
+        icount = icount_get_raw_locked();
+    } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
+
+    return icount;
+}
+
+/* Return the virtual CPU time, based on the instruction counter.  */
+int64_t icount_get(void)
+{
+    int64_t icount;
+    unsigned start;
+
+    do {
+        start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
+        icount = icount_get_locked();
+    } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
+
+    return icount;
+}
+
+int64_t icount_to_ns(int64_t icount)
+{
+    return icount << atomic_read(&timers_state.icount_time_shift);
+}
+
+/*
+ * Correlation between real and virtual time is always going to be
+ * fairly approximate, so ignore small variation.
+ * When the guest is idle real and virtual time will be aligned in
+ * the IO wait loop.
+ */
+#define ICOUNT_WOBBLE (NANOSECONDS_PER_SECOND / 10)
+
+static void icount_adjust(void)
+{
+    int64_t cur_time;
+    int64_t cur_icount;
+    int64_t delta;
+
+    /* Protected by TimersState mutex.  */
+    static int64_t last_delta;
+
+    /* If the VM is not running, then do nothing.  */
+    if (!runstate_is_running()) {
+        return;
+    }
+
+    seqlock_write_lock(&timers_state.vm_clock_seqlock,
+                       &timers_state.vm_clock_lock);
+    cur_time = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT,
+                                   cpu_get_clock_locked());
+    cur_icount = icount_get_locked();
+
+    delta = cur_icount - cur_time;
+    /* FIXME: This is a very crude algorithm, somewhat prone to oscillation.  */
+    if (delta > 0
+        && last_delta + ICOUNT_WOBBLE < delta * 2
+        && timers_state.icount_time_shift > 0) {
+        /* The guest is getting too far ahead.  Slow time down.  */
+        atomic_set(&timers_state.icount_time_shift,
+                   timers_state.icount_time_shift - 1);
+    }
+    if (delta < 0
+        && last_delta - ICOUNT_WOBBLE > delta * 2
+        && timers_state.icount_time_shift < MAX_ICOUNT_SHIFT) {
+        /* The guest is getting too far behind.  Speed time up.  */
+        atomic_set(&timers_state.icount_time_shift,
+                   timers_state.icount_time_shift + 1);
+    }
+    last_delta = delta;
+    atomic_set_i64(&timers_state.qemu_icount_bias,
+                   cur_icount - (timers_state.qemu_icount
+                                 << timers_state.icount_time_shift));
+    seqlock_write_unlock(&timers_state.vm_clock_seqlock,
+                         &timers_state.vm_clock_lock);
+}
+
+static void icount_adjust_rt(void *opaque)
+{
+    timer_mod(timers_state.icount_rt_timer,
+              qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
+    icount_adjust();
+}
+
+static void icount_adjust_vm(void *opaque)
+{
+    timer_mod(timers_state.icount_vm_timer,
+                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+                   NANOSECONDS_PER_SECOND / 10);
+    icount_adjust();
+}
+
+int64_t icount_round(int64_t count)
+{
+    int shift = atomic_read(&timers_state.icount_time_shift);
+    return (count + (1 << shift) - 1) >> shift;
+}
+
+static void icount_warp_rt(void)
+{
+    unsigned seq;
+    int64_t warp_start;
+
+    /*
+     * The icount_warp_timer is rescheduled soon after vm_clock_warp_start
+     * changes from -1 to another value, so the race here is okay.
+     */
+    do {
+        seq = seqlock_read_begin(&timers_state.vm_clock_seqlock);
+        warp_start = timers_state.vm_clock_warp_start;
+    } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq));
+
+    if (warp_start == -1) {
+        return;
+    }
+
+    seqlock_write_lock(&timers_state.vm_clock_seqlock,
+                       &timers_state.vm_clock_lock);
+    if (runstate_is_running()) {
+        int64_t clock = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT,
+                                            cpu_get_clock_locked());
+        int64_t warp_delta;
+
+        warp_delta = clock - timers_state.vm_clock_warp_start;
+        if (icount_enabled() == 2) {
+            /*
+             * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
+             * far ahead of real time.
+             */
+            int64_t cur_icount = icount_get_locked();
+            int64_t delta = clock - cur_icount;
+            warp_delta = MIN(warp_delta, delta);
+        }
+        atomic_set_i64(&timers_state.qemu_icount_bias,
+                       timers_state.qemu_icount_bias + warp_delta);
+    }
+    timers_state.vm_clock_warp_start = -1;
+    seqlock_write_unlock(&timers_state.vm_clock_seqlock,
+                       &timers_state.vm_clock_lock);
+
+    if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
+        qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+    }
+}
+
+static void icount_timer_cb(void *opaque)
+{
+    /*
+     * No need for a checkpoint because the timer already synchronizes
+     * with CHECKPOINT_CLOCK_VIRTUAL_RT.
+     */
+    icount_warp_rt();
+}
+
+void icount_start_warp_timer(void)
+{
+    int64_t clock;
+    int64_t deadline;
+
+    if (!icount_enabled()) {
+        return;
+    }
+
+    /*
+     * Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers
+     * do not fire, so computing the deadline does not make sense.
+     */
+    if (!runstate_is_running()) {
+        return;
+    }
+
+    if (replay_mode != REPLAY_MODE_PLAY) {
+        if (!all_cpu_threads_idle()) {
+            return;
+        }
+
+        if (qtest_enabled()) {
+            /* When testing, qtest commands advance icount.  */
+            return;
+        }
+
+        replay_checkpoint(CHECKPOINT_CLOCK_WARP_START);
+    } else {
+        /* warp clock deterministically in record/replay mode */
+        if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_START)) {
+            /*
+             * vCPU is sleeping and warp can't be started.
+             * It is probably a race condition: notification sent
+             * to vCPU was processed in advance and vCPU went to sleep.
+             * Therefore we have to wake it up for doing someting.
+             */
+            if (replay_has_checkpoint()) {
+                qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+            }
+            return;
+        }
+    }
+
+    /* We want to use the earliest deadline from ALL vm_clocks */
+    clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT);
+    deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+                                          ~QEMU_TIMER_ATTR_EXTERNAL);
+    if (deadline < 0) {
+        static bool notified;
+        if (!icount_sleep && !notified) {
+            warn_report("icount sleep disabled and no active timers");
+            notified = true;
+        }
+        return;
+    }
+
+    if (deadline > 0) {
+        /*
+         * Ensure QEMU_CLOCK_VIRTUAL proceeds even when the virtual CPU goes to
+         * sleep.  Otherwise, the CPU might be waiting for a future timer
+         * interrupt to wake it up, but the interrupt never comes because
+         * the vCPU isn't running any insns and thus doesn't advance the
+         * QEMU_CLOCK_VIRTUAL.
+         */
+        if (!icount_sleep) {
+            /*
+             * We never let VCPUs sleep in no sleep icount mode.
+             * If there is a pending QEMU_CLOCK_VIRTUAL timer we just advance
+             * to the next QEMU_CLOCK_VIRTUAL event and notify it.
+             * It is useful when we want a deterministic execution time,
+             * isolated from host latencies.
+             */
+            seqlock_write_lock(&timers_state.vm_clock_seqlock,
+                               &timers_state.vm_clock_lock);
+            atomic_set_i64(&timers_state.qemu_icount_bias,
+                           timers_state.qemu_icount_bias + deadline);
+            seqlock_write_unlock(&timers_state.vm_clock_seqlock,
+                                 &timers_state.vm_clock_lock);
+            qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+        } else {
+            /*
+             * We do stop VCPUs and only advance QEMU_CLOCK_VIRTUAL after some
+             * "real" time, (related to the time left until the next event) has
+             * passed. The QEMU_CLOCK_VIRTUAL_RT clock will do this.
+             * This avoids that the warps are visible externally; for example,
+             * you will not be sending network packets continuously instead of
+             * every 100ms.
+             */
+            seqlock_write_lock(&timers_state.vm_clock_seqlock,
+                               &timers_state.vm_clock_lock);
+            if (timers_state.vm_clock_warp_start == -1
+                || timers_state.vm_clock_warp_start > clock) {
+                timers_state.vm_clock_warp_start = clock;
+            }
+            seqlock_write_unlock(&timers_state.vm_clock_seqlock,
+                                 &timers_state.vm_clock_lock);
+            timer_mod_anticipate(timers_state.icount_warp_timer,
+                                 clock + deadline);
+        }
+    } else if (deadline == 0) {
+        qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+    }
+}
+
+void icount_account_warp_timer(void)
+{
+    if (!use_icount || !icount_sleep) {
+        return;
+    }
+
+    /*
+     * Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers
+     * do not fire, so computing the deadline does not make sense.
+     */
+    if (!runstate_is_running()) {
+        return;
+    }
+
+    /* warp clock deterministically in record/replay mode */
+    if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_ACCOUNT)) {
+        return;
+    }
+
+    timer_del(timers_state.icount_warp_timer);
+    icount_warp_rt();
+}
+
+void icount_configure(QemuOpts *opts, Error **errp)
+{
+    const char *option = qemu_opt_get(opts, "shift");
+    bool sleep = qemu_opt_get_bool(opts, "sleep", true);
+    bool align = qemu_opt_get_bool(opts, "align", false);
+    long time_shift = -1;
+
+    if (!option) {
+        if (qemu_opt_get(opts, "align") != NULL) {
+            error_setg(errp, "Please specify shift option when using align");
+        }
+        return;
+    }
+
+    if (align && !sleep) {
+        error_setg(errp, "align=on and sleep=off are incompatible");
+        return;
+    }
+
+    if (strcmp(option, "auto") != 0) {
+        if (qemu_strtol(option, NULL, 0, &time_shift) < 0
+            || time_shift < 0 || time_shift > MAX_ICOUNT_SHIFT) {
+            error_setg(errp, "icount: Invalid shift value");
+            return;
+        }
+    } else if (icount_align_option) {
+        error_setg(errp, "shift=auto and align=on are incompatible");
+        return;
+    } else if (!icount_sleep) {
+        error_setg(errp, "shift=auto and sleep=off are incompatible");
+        return;
+    }
+
+    icount_sleep = sleep;
+    if (icount_sleep) {
+        timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
+                                         icount_timer_cb, NULL);
+    }
+
+    icount_align_option = align;
+
+    if (time_shift >= 0) {
+        timers_state.icount_time_shift = time_shift;
+        icount_enable_precise();
+        return;
+    }
+
+    icount_enable_adaptive();
+
+    /*
+     * 125MIPS seems a reasonable initial guess at the guest speed.
+     * It will be corrected fairly quickly anyway.
+     */
+    timers_state.icount_time_shift = 3;
+
+    /*
+     * Have both realtime and virtual time triggers for speed adjustment.
+     * The realtime trigger catches emulated time passing too slowly,
+     * the virtual time trigger catches emulated time passing too fast.
+     * Realtime triggers occur even when idle, so use them less frequently
+     * than VM triggers.
+     */
+    timers_state.vm_clock_warp_start = -1;
+    timers_state.icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT,
+                                   icount_adjust_rt, NULL);
+    timer_mod(timers_state.icount_rt_timer,
+                   qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
+    timers_state.icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+                                        icount_adjust_vm, NULL);
+    timer_mod(timers_state.icount_vm_timer,
+                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+                   NANOSECONDS_PER_SECOND / 10);
+}
diff --git a/softmmu/qtest.c b/softmmu/qtest.c
index 5672b75c35..d79b3f3db1 100644
--- a/softmmu/qtest.c
+++ b/softmmu/qtest.c
@@ -21,7 +21,7 @@
 #include "exec/memory.h"
 #include "hw/irq.h"
 #include "sysemu/accel.h"
-#include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
 #include "qemu/config-file.h"
 #include "qemu/option.h"
 #include "qemu/error-report.h"
@@ -273,6 +273,38 @@ static void qtest_irq_handler(void *opaque, int n, int level)
     }
 }
 
+static int64_t qtest_clock_counter;
+
+int64_t qtest_get_clock(void)
+{
+    return atomic_read_i64(&qtest_clock_counter);
+}
+
+static void qtest_set_clock(int64_t count)
+{
+    atomic_set_i64(&qtest_clock_counter, count);
+}
+
+static void qtest_clock_warp(int64_t dest)
+{
+    int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    AioContext *aio_context;
+    assert(qtest_enabled());
+    aio_context = qemu_get_aio_context();
+    while (clock < dest) {
+        int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+                                                      QEMU_TIMER_ATTR_ALL);
+        int64_t warp = qemu_soonest_timeout(dest - clock, deadline);
+
+        qtest_set_clock(qtest_get_clock() + warp);
+
+        qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
+        timerlist_run_timers(aio_context->tlg.tl[QEMU_CLOCK_VIRTUAL]);
+        clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    }
+    qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+}
+
 static void qtest_process_command(CharBackend *chr, gchar **words)
 {
     const gchar *command;
diff --git a/softmmu/timers-state.h b/softmmu/timers-state.h
new file mode 100644
index 0000000000..db4e60f18f
--- /dev/null
+++ b/softmmu/timers-state.h
@@ -0,0 +1,69 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * 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.
+ */
+
+#ifndef TIMERS_STATE_H
+#define TIMERS_STATE_H
+
+/* timers state, for sharing between icount and cpu-timers */
+
+typedef struct TimersState {
+    /* Protected by BQL.  */
+    int64_t cpu_ticks_prev;
+    int64_t cpu_ticks_offset;
+
+    /*
+     * Protect fields that can be respectively read outside the
+     * BQL, and written from multiple threads.
+     */
+    QemuSeqLock vm_clock_seqlock;
+    QemuSpin vm_clock_lock;
+
+    int16_t cpu_ticks_enabled;
+
+    /* Conversion factor from emulated instructions to virtual clock ticks.  */
+    int16_t icount_time_shift;
+
+    /* Compensate for varying guest execution speed.  */
+    int64_t qemu_icount_bias;
+
+    int64_t vm_clock_warp_start;
+    int64_t cpu_clock_offset;
+
+    /* Only written by TCG thread */
+    int64_t qemu_icount;
+
+    /* for adjusting icount */
+    QEMUTimer *icount_rt_timer;
+    QEMUTimer *icount_vm_timer;
+    QEMUTimer *icount_warp_timer;
+} TimersState;
+
+extern TimersState timers_state;
+
+/*
+ * icount needs this internal from cpu-timers when adjusting the icount shift.
+ */
+int64_t cpu_get_clock_locked(void);
+
+#endif /* TIMERS_STATE_H */
diff --git a/softmmu/vl.c b/softmmu/vl.c
index b003a49058..df32f4c0ae 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -74,6 +74,7 @@
 #include "hw/audio/soundhw.h"
 #include "audio/audio.h"
 #include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
 #include "migration/colo.h"
 #include "migration/postcopy-ram.h"
 #include "sysemu/kvm.h"
@@ -2682,7 +2683,7 @@ static void user_register_global_props(void)
 
 static int do_configure_icount(void *opaque, QemuOpts *opts, Error **errp)
 {
-    configure_icount(opts, errp);
+    icount_configure(opts, errp);
     return 0;
 }
 
@@ -2792,7 +2793,7 @@ static void configure_accelerators(const char *progname)
         error_report("falling back to %s", ac->name);
     }
 
-    if (use_icount && !(tcg_enabled() || qtest_enabled())) {
+    if (icount_enabled() && !tcg_enabled()) {
         error_report("-icount is not allowed with hardware virtualization");
         exit(1);
     }
@@ -4242,7 +4243,8 @@ void qemu_init(int argc, char **argv, char **envp)
     /* spice needs the timers to be initialized by this point */
     qemu_spice_init();
 
-    cpu_ticks_init();
+    /* initialize cpu timers and VCPU throttle modules */
+    cpu_timers_init();
 
     if (default_net) {
         QemuOptsList *net = qemu_find_opts("net");
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index f32b9e47a3..42d4f459e6 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,7 +1,8 @@
 stub-obj-y += blk-commit-all.o
 stub-obj-y += cmos.o
 stub-obj-y += cpu-get-clock.o
-stub-obj-y += cpu-get-icount.o
+stub-obj-y += qemu-timer-notify-cb.o
+stub-obj-y += icount.o
 stub-obj-y += dump.o
 stub-obj-y += error-printf.o
 stub-obj-y += fdset.o
diff --git a/stubs/clock-warp.c b/stubs/clock-warp.c
index b53e5dd94c..304da5091c 100644
--- a/stubs/clock-warp.c
+++ b/stubs/clock-warp.c
@@ -1,7 +1,7 @@
 #include "qemu/osdep.h"
-#include "qemu/timer.h"
+#include "sysemu/cpu-timers.h"
 
-void qemu_start_warp_timer(void)
+void icount_start_warp_timer(void)
 {
 }
 
diff --git a/stubs/cpu-get-clock.c b/stubs/cpu-get-clock.c
index 5a92810e87..9e92404816 100644
--- a/stubs/cpu-get-clock.c
+++ b/stubs/cpu-get-clock.c
@@ -1,5 +1,6 @@
 #include "qemu/osdep.h"
-#include "qemu/timer.h"
+#include "sysemu/cpu-timers.h"
+#include "qemu/main-loop.h"
 
 int64_t cpu_get_clock(void)
 {
diff --git a/stubs/cpu-get-icount.c b/stubs/cpu-get-icount.c
deleted file mode 100644
index b35f844638..0000000000
--- a/stubs/cpu-get-icount.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu/timer.h"
-#include "sysemu/cpus.h"
-#include "qemu/main-loop.h"
-
-int use_icount;
-
-int64_t cpu_get_icount(void)
-{
-    abort();
-}
-
-int64_t cpu_get_icount_raw(void)
-{
-    abort();
-}
-
-void qemu_timer_notify_cb(void *opaque, QEMUClockType type)
-{
-    qemu_notify_event();
-}
diff --git a/stubs/icount.c b/stubs/icount.c
new file mode 100644
index 0000000000..9054724e92
--- /dev/null
+++ b/stubs/icount.c
@@ -0,0 +1,22 @@
+#include "qemu/osdep.h"
+#include "sysemu/cpu-timers.h"
+
+int64_t icount_get(void)
+{
+    abort();
+}
+
+int64_t icount_get_raw(void)
+{
+    abort();
+}
+
+void icount_configure(QemuOpts *opts, Error **errp)
+{
+    abort();
+}
+
+int icount_enabled(void)
+{
+    return 0;
+}
diff --git a/stubs/qemu-timer-notify-cb.c b/stubs/qemu-timer-notify-cb.c
new file mode 100644
index 0000000000..845e46f8e0
--- /dev/null
+++ b/stubs/qemu-timer-notify-cb.c
@@ -0,0 +1,8 @@
+#include "qemu/osdep.h"
+#include "sysemu/cpu-timers.h"
+#include "qemu/main-loop.h"
+
+void qemu_timer_notify_cb(void *opaque, QEMUClockType type)
+{
+    qemu_notify_event();
+}
diff --git a/stubs/qtest.c b/stubs/qtest.c
index 891eb954fb..fe775a622c 100644
--- a/stubs/qtest.c
+++ b/stubs/qtest.c
@@ -18,3 +18,8 @@ bool qtest_driver(void)
 {
     return false;
 }
+
+int64_t qtest_get_clock(void)
+{
+    return 0;
+}
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 8870284f57..36be602179 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
 #include "disas/disas.h"
 #include "qemu/host-utils.h"
 #include "exec/exec-all.h"
@@ -1329,7 +1330,7 @@ static DisasJumpType gen_mfpr(DisasContext *ctx, TCGv va, int regno)
     case 249: /* VMTIME */
         helper = gen_helper_get_vmtime;
     do_helper:
-        if (use_icount) {
+        if (icount_enabled()) {
             gen_io_start();
             helper(va);
             return DISAS_PC_STALE;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index dc9c29f998..06b920fab8 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -24,6 +24,7 @@
 #include "hw/irq.h"
 #include "hw/semihosting/semihost.h"
 #include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
 #include "sysemu/kvm.h"
 #include "sysemu/tcg.h"
 #include "qemu/range.h"
@@ -1206,17 +1207,17 @@ static int64_t cycles_ns_per(uint64_t cycles)
 
 static bool instructions_supported(CPUARMState *env)
 {
-    return use_icount == 1 /* Precise instruction counting */;
+    return icount_enabled() == 1; /* Precise instruction counting */
 }
 
 static uint64_t instructions_get_count(CPUARMState *env)
 {
-    return (uint64_t)cpu_get_icount_raw();
+    return (uint64_t)icount_get_raw();
 }
 
 static int64_t instructions_ns_per(uint64_t icount)
 {
-    return cpu_icount_to_ns((int64_t)icount);
+    return icount_to_ns((int64_t)icount);
 }
 #endif
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 383be0a955..412ca36393 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -174,8 +174,8 @@ static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
 static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
 {
 #if !defined(CONFIG_USER_ONLY)
-    if (use_icount) {
-        *val = cpu_get_icount();
+    if (icount_enabled()) {
+        *val = icount_get();
     } else {
         *val = cpu_get_host_ticks();
     }
@@ -189,8 +189,8 @@ static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
 static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
 {
 #if !defined(CONFIG_USER_ONLY)
-    if (use_icount) {
-        *val = cpu_get_icount() >> 32;
+    if (icount_enabled()) {
+        *val = icount_get() >> 32;
     } else {
         *val = cpu_get_host_ticks() >> 32;
     }
diff --git a/tests/ptimer-test-stubs.c b/tests/ptimer-test-stubs.c
index ed393d9082..b4447a3e44 100644
--- a/tests/ptimer-test-stubs.c
+++ b/tests/ptimer-test-stubs.c
@@ -12,6 +12,7 @@
 #include "qemu/main-loop.h"
 #include "sysemu/replay.h"
 #include "migration/vmstate.h"
+#include "sysemu/cpu-timers.h"
 
 #include "ptimer-test.h"
 
@@ -30,8 +31,10 @@ QEMUTimerListGroup main_loop_tlg;
 
 int64_t ptimer_test_time_ns;
 
-/* Do not artificially limit period - see hw/core/ptimer.c.  */
-int use_icount = 1;
+int icount_enabled(void)
+{
+    return 0;
+}
 bool qtest_allowed;
 
 void timer_init_full(QEMUTimer *ts,
diff --git a/tests/test-timed-average.c b/tests/test-timed-average.c
index e2bcf5fe13..82c92500df 100644
--- a/tests/test-timed-average.c
+++ b/tests/test-timed-average.c
@@ -11,7 +11,7 @@
  */
 
 #include "qemu/osdep.h"
-
+#include "sysemu/cpu-timers.h"
 #include "qemu/timed-average.h"
 
 /* This is the clock for QEMU_CLOCK_VIRTUAL */
diff --git a/util/main-loop.c b/util/main-loop.c
index eda63fe4e0..f1af697572 100644
--- a/util/main-loop.c
+++ b/util/main-loop.c
@@ -27,7 +27,7 @@
 #include "qemu/cutils.h"
 #include "qemu/timer.h"
 #include "sysemu/qtest.h"
-#include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
 #include "sysemu/replay.h"
 #include "qemu/main-loop.h"
 #include "block/aio.h"
@@ -521,7 +521,7 @@ void main_loop_wait(int nonblocking)
 
     /* CPU thread can infinitely wait for event after
        missing the warp */
-    qemu_start_warp_timer();
+    icount_start_warp_timer();
     qemu_clock_run_all_timers();
 }
 
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
index f62b4feecd..8b8c5cb762 100644
--- a/util/qemu-timer.c
+++ b/util/qemu-timer.c
@@ -26,8 +26,10 @@
 #include "qemu/main-loop.h"
 #include "qemu/timer.h"
 #include "qemu/lockable.h"
+#include "sysemu/cpu-timers.h"
 #include "sysemu/replay.h"
 #include "sysemu/cpus.h"
+#include "sysemu/qtest.h"
 
 #ifdef CONFIG_POSIX
 #include <pthread.h>
@@ -134,7 +136,7 @@ static void qemu_clock_init(QEMUClockType type, QEMUTimerListNotifyCB *notify_cb
 
 bool qemu_clock_use_for_deadline(QEMUClockType type)
 {
-    return !(use_icount && (type == QEMU_CLOCK_VIRTUAL));
+    return !(icount_enabled() && (type == QEMU_CLOCK_VIRTUAL));
 }
 
 void qemu_clock_notify(QEMUClockType type)
@@ -417,7 +419,7 @@ static void timerlist_rearm(QEMUTimerList *timer_list)
 {
     /* Interrupt execution to force deadline recalculation.  */
     if (timer_list->clock->type == QEMU_CLOCK_VIRTUAL) {
-        qemu_start_warp_timer();
+        icount_start_warp_timer();
     }
     timerlist_notify(timer_list);
 }
@@ -633,8 +635,10 @@ int64_t qemu_clock_get_ns(QEMUClockType type)
         return get_clock();
     default:
     case QEMU_CLOCK_VIRTUAL:
-        if (use_icount) {
-            return cpu_get_icount();
+        if (icount_enabled()) {
+            return icount_get();
+        } else if (qtest_enabled()) { /* for qtest_clock_warp */
+            return qtest_get_clock();
         } else {
             return cpu_get_clock();
         }
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 44/53] softmmu/vl: Remove the check for colons in -accel parameters
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (42 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 43/53] cpu-timers, icount: new modules Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 45/53] accel/kvm: Let kvm_check_extension use global KVM state Paolo Bonzini
                   ` (10 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Thomas Huth, Claudio Fontana

From: Thomas Huth <thuth@redhat.com>

The new -accel option does not accept colons in the parameters anymore
(since it does not convert the parameters to -machine accel=... parameters
anymore). Thus we can now remove the check for colons in -accel:

$ qemu-system-x86_64 -accel kvm:tcg
qemu-system-x86_64: -accel kvm:tcg: invalid accelerator kvm:tcg

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Claudio Fontana <cfontana@suse.de>
Message-Id: <20200618074001.13642-1-thuth@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 softmmu/vl.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/softmmu/vl.c b/softmmu/vl.c
index df32f4c0ae..5d2cea559d 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -3493,11 +3493,6 @@ void qemu_init(int argc, char **argv, char **envp)
                     g_slist_free(accel_list);
                     exit(0);
                 }
-                if (optarg && strchr(optarg, ':')) {
-                    error_report("Don't use ':' with -accel, "
-                                 "use -M accel=... for now instead");
-                    exit(1);
-                }
                 break;
             case QEMU_OPTION_usb:
                 olist = qemu_find_opts("machine");
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 45/53] accel/kvm: Let kvm_check_extension use global KVM state
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (43 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 44/53] softmmu/vl: Remove the check for colons in -accel parameters Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 46/53] accel/kvm: Simplify kvm_check_extension() Paolo Bonzini
                   ` (9 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Cornelia Huck, Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

As KVM supported extentions those should be the same for
all VMs, it is safe to directly use the global kvm_state
in kvm_check_extension().

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20200623105052.1700-2-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 accel/kvm/kvm-all.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index d54a8701d8..99e4e5722e 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -913,7 +913,7 @@ int kvm_check_extension(KVMState *s, unsigned int extension)
 {
     int ret;
 
-    ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, extension);
+    ret = kvm_ioctl(kvm_state, KVM_CHECK_EXTENSION, extension);
     if (ret < 0) {
         ret = 0;
     }
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 46/53] accel/kvm: Simplify kvm_check_extension()
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (44 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 45/53] accel/kvm: Let kvm_check_extension use global KVM state Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 47/53] accel/kvm: Simplify kvm_check_extension_list() Paolo Bonzini
                   ` (8 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Cornelia Huck, Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

In previous commit we let kvm_check_extension() use the
global kvm_state. Since the KVMState* argument is now
unused, drop it.

Convert callers with this Coccinelle script:

  @@
  expression kvm_state, extension;
  @@
  -   kvm_check_extension(kvm_state, extension)
  +   kvm_check_extension(extension)

Unused variables manually removed:
- CPUState* in hyperv_enabled()
- KVMState* in kvm_arm_get_max_vm_ipa_size()

Inspired-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20200623105052.1700-3-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 accel/kvm/kvm-all.c          | 64 ++++++++++++++++++------------------
 hw/hyperv/hyperv.c           |  2 +-
 hw/i386/kvm/clock.c          |  2 +-
 hw/i386/kvm/i8254.c          |  4 +--
 hw/i386/kvm/ioapic.c         |  2 +-
 hw/intc/arm_gic_kvm.c        |  2 +-
 hw/intc/openpic_kvm.c        |  2 +-
 hw/intc/xics_kvm.c           |  2 +-
 hw/s390x/s390-stattrib-kvm.c |  2 +-
 include/sysemu/kvm.h         |  2 +-
 target/arm/kvm.c             | 13 ++++----
 target/arm/kvm32.c           |  2 +-
 target/arm/kvm64.c           | 15 ++++-----
 target/i386/kvm.c            | 63 ++++++++++++++++-------------------
 target/mips/kvm.c            |  4 +--
 target/ppc/kvm.c             | 34 +++++++++----------
 target/s390x/cpu_models.c    |  3 +-
 target/s390x/kvm.c           | 30 ++++++++---------
 18 files changed, 120 insertions(+), 128 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 99e4e5722e..7370e3413d 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -909,7 +909,7 @@ static MemoryListener kvm_coalesced_pio_listener = {
     .coalesced_io_del = kvm_coalesce_pio_del,
 };
 
-int kvm_check_extension(KVMState *s, unsigned int extension)
+int kvm_check_extension(unsigned int extension)
 {
     int ret;
 
@@ -928,7 +928,7 @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension)
     ret = kvm_vm_ioctl(s, KVM_CHECK_EXTENSION, extension);
     if (ret < 0) {
         /* VM wide version not implemented, use global one instead */
-        ret = kvm_check_extension(s, extension);
+        ret = kvm_check_extension(extension);
     }
 
     return ret;
@@ -1091,7 +1091,7 @@ static const KVMCapabilityInfo *
 kvm_check_extension_list(KVMState *s, const KVMCapabilityInfo *list)
 {
     while (list->name) {
-        if (!kvm_check_extension(s, list->value)) {
+        if (!kvm_check_extension(list->value)) {
             return list;
         }
         list++;
@@ -1394,7 +1394,7 @@ void kvm_init_irq_routing(KVMState *s)
 {
     int gsi_count, i;
 
-    gsi_count = kvm_check_extension(s, KVM_CAP_IRQ_ROUTING) - 1;
+    gsi_count = kvm_check_extension(KVM_CAP_IRQ_ROUTING) - 1;
     if (gsi_count > 0) {
         /* Round up so we can search ints using ffs */
         s->used_gsi_bitmap = bitmap_new(gsi_count);
@@ -1798,7 +1798,7 @@ int kvm_irqchip_add_hv_sint_route(KVMState *s, uint32_t vcpu, uint32_t sint)
     if (!kvm_gsi_routing_enabled()) {
         return -ENOSYS;
     }
-    if (!kvm_check_extension(s, KVM_CAP_HYPERV_SYNIC)) {
+    if (!kvm_check_extension(KVM_CAP_HYPERV_SYNIC)) {
         return -ENOSYS;
     }
     virq = kvm_irqchip_get_virq(s);
@@ -1907,9 +1907,9 @@ static void kvm_irqchip_create(KVMState *s)
     int ret;
 
     assert(s->kernel_irqchip_split != ON_OFF_AUTO_AUTO);
-    if (kvm_check_extension(s, KVM_CAP_IRQCHIP)) {
+    if (kvm_check_extension(KVM_CAP_IRQCHIP)) {
         ;
-    } else if (kvm_check_extension(s, KVM_CAP_S390_IRQCHIP)) {
+    } else if (kvm_check_extension(KVM_CAP_S390_IRQCHIP)) {
         ret = kvm_vm_enable_cap(s, KVM_CAP_S390_IRQCHIP, 0);
         if (ret < 0) {
             fprintf(stderr, "Enable kernel irqchip failed: %s\n", strerror(-ret));
@@ -1959,13 +1959,13 @@ static int kvm_recommended_vcpus(KVMState *s)
 
 static int kvm_max_vcpus(KVMState *s)
 {
-    int ret = kvm_check_extension(s, KVM_CAP_MAX_VCPUS);
+    int ret = kvm_check_extension(KVM_CAP_MAX_VCPUS);
     return (ret) ? ret : kvm_recommended_vcpus(s);
 }
 
 static int kvm_max_vcpu_id(KVMState *s)
 {
-    int ret = kvm_check_extension(s, KVM_CAP_MAX_VCPU_ID);
+    int ret = kvm_check_extension(KVM_CAP_MAX_VCPU_ID);
     return (ret) ? ret : kvm_max_vcpus(s);
 }
 
@@ -2036,15 +2036,15 @@ static int kvm_init(MachineState *ms)
         goto err;
     }
 
-    kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT);
-    s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
+    kvm_immediate_exit = kvm_check_extension(KVM_CAP_IMMEDIATE_EXIT);
+    s->nr_slots = kvm_check_extension(KVM_CAP_NR_MEMSLOTS);
 
     /* If unspecified, use the default value */
     if (!s->nr_slots) {
         s->nr_slots = 32;
     }
 
-    s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE);
+    s->nr_as = kvm_check_extension(KVM_CAP_MULTI_ADDRESS_SPACE);
     if (s->nr_as <= 1) {
         s->nr_as = 1;
     }
@@ -2117,12 +2117,12 @@ static int kvm_init(MachineState *ms)
         goto err;
     }
 
-    s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
+    s->coalesced_mmio = kvm_check_extension(KVM_CAP_COALESCED_MMIO);
     s->coalesced_pio = s->coalesced_mmio &&
-                       kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
+                       kvm_check_extension(KVM_CAP_COALESCED_PIO);
 
     dirty_log_manual_caps =
-        kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
+        kvm_check_extension( KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
     dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
                               KVM_DIRTY_LOG_INITIALLY_SET);
     s->manual_dirty_log_protect = dirty_log_manual_caps;
@@ -2139,46 +2139,46 @@ static int kvm_init(MachineState *ms)
     }
 
 #ifdef KVM_CAP_VCPU_EVENTS
-    s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS);
+    s->vcpu_events = kvm_check_extension(KVM_CAP_VCPU_EVENTS);
 #endif
 
     s->robust_singlestep =
-        kvm_check_extension(s, KVM_CAP_X86_ROBUST_SINGLESTEP);
+        kvm_check_extension(KVM_CAP_X86_ROBUST_SINGLESTEP);
 
 #ifdef KVM_CAP_DEBUGREGS
-    s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS);
+    s->debugregs = kvm_check_extension(KVM_CAP_DEBUGREGS);
 #endif
 
-    s->max_nested_state_len = kvm_check_extension(s, KVM_CAP_NESTED_STATE);
+    s->max_nested_state_len = kvm_check_extension(KVM_CAP_NESTED_STATE);
 
 #ifdef KVM_CAP_IRQ_ROUTING
-    kvm_direct_msi_allowed = (kvm_check_extension(s, KVM_CAP_SIGNAL_MSI) > 0);
+    kvm_direct_msi_allowed = (kvm_check_extension(KVM_CAP_SIGNAL_MSI) > 0);
 #endif
 
-    s->intx_set_mask = kvm_check_extension(s, KVM_CAP_PCI_2_3);
+    s->intx_set_mask = kvm_check_extension(KVM_CAP_PCI_2_3);
 
     s->irq_set_ioctl = KVM_IRQ_LINE;
-    if (kvm_check_extension(s, KVM_CAP_IRQ_INJECT_STATUS)) {
+    if (kvm_check_extension(KVM_CAP_IRQ_INJECT_STATUS)) {
         s->irq_set_ioctl = KVM_IRQ_LINE_STATUS;
     }
 
     kvm_readonly_mem_allowed =
-        (kvm_check_extension(s, KVM_CAP_READONLY_MEM) > 0);
+        (kvm_check_extension(KVM_CAP_READONLY_MEM) > 0);
 
     kvm_eventfds_allowed =
-        (kvm_check_extension(s, KVM_CAP_IOEVENTFD) > 0);
+        (kvm_check_extension(KVM_CAP_IOEVENTFD) > 0);
 
     kvm_irqfds_allowed =
-        (kvm_check_extension(s, KVM_CAP_IRQFD) > 0);
+        (kvm_check_extension(KVM_CAP_IRQFD) > 0);
 
     kvm_resamplefds_allowed =
-        (kvm_check_extension(s, KVM_CAP_IRQFD_RESAMPLE) > 0);
+        (kvm_check_extension(KVM_CAP_IRQFD_RESAMPLE) > 0);
 
     kvm_vm_attributes_allowed =
-        (kvm_check_extension(s, KVM_CAP_VM_ATTRIBUTES) > 0);
+        (kvm_check_extension(KVM_CAP_VM_ATTRIBUTES) > 0);
 
     kvm_ioeventfd_any_length_allowed =
-        (kvm_check_extension(s, KVM_CAP_IOEVENTFD_ANY_LENGTH) > 0);
+        (kvm_check_extension(KVM_CAP_IOEVENTFD_ANY_LENGTH) > 0);
 
     kvm_state = s;
 
@@ -2271,7 +2271,7 @@ static int kvm_handle_internal_error(CPUState *cpu, struct kvm_run *run)
     fprintf(stderr, "KVM internal error. Suberror: %d\n",
             run->internal.suberror);
 
-    if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) {
+    if (kvm_check_extension(KVM_CAP_INTERNAL_ERROR_DATA)) {
         int i;
 
         for (i = 0; i < run->internal.ndata; ++i) {
@@ -2740,7 +2740,7 @@ int kvm_has_many_ioeventfds(void)
 int kvm_has_gsi_routing(void)
 {
 #ifdef KVM_CAP_IRQ_ROUTING
-    return kvm_check_extension(kvm_state, KVM_CAP_IRQ_ROUTING);
+    return kvm_check_extension(KVM_CAP_IRQ_ROUTING);
 #else
     return false;
 #endif
@@ -2753,7 +2753,7 @@ int kvm_has_intx_set_mask(void)
 
 bool kvm_arm_supports_user_irq(void)
 {
-    return kvm_check_extension(kvm_state, KVM_CAP_ARM_USER_IRQ);
+    return kvm_check_extension(KVM_CAP_ARM_USER_IRQ);
 }
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
@@ -3026,7 +3026,7 @@ int kvm_create_device(KVMState *s, uint64_t type, bool test)
     create_dev.fd = -1;
     create_dev.flags = test ? KVM_CREATE_DEVICE_TEST : 0;
 
-    if (!kvm_check_extension(s, KVM_CAP_DEVICE_CTRL)) {
+    if (!kvm_check_extension(KVM_CAP_DEVICE_CTRL)) {
         return -ENOTSUP;
     }
 
diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c
index 844d00776d..92720efc3d 100644
--- a/hw/hyperv/hyperv.c
+++ b/hw/hyperv/hyperv.c
@@ -605,7 +605,7 @@ static bool process_event_flags_userspace;
 int hyperv_set_event_flag_handler(uint32_t conn_id, EventNotifier *notifier)
 {
     if (!process_event_flags_userspace &&
-        !kvm_check_extension(kvm_state, KVM_CAP_HYPERV_EVENTFD)) {
+        !kvm_check_extension(KVM_CAP_HYPERV_EVENTFD)) {
         process_event_flags_userspace = true;
 
         warn_report("Hyper-V event signaling is not supported by this kernel; "
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 64283358f9..c0bfc69349 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -166,7 +166,7 @@ static void kvmclock_vm_state_change(void *opaque, int running,
 {
     KVMClockState *s = opaque;
     CPUState *cpu;
-    int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL);
+    int cap_clock_ctrl = kvm_check_extension(KVM_CAP_KVMCLOCK_CTRL);
     int ret;
 
     if (running) {
diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index 876f5aa6fa..90532df071 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -264,7 +264,7 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
     };
     int ret;
 
-    if (kvm_check_extension(kvm_state, KVM_CAP_PIT2)) {
+    if (kvm_check_extension(KVM_CAP_PIT2)) {
         ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT2, &config);
     } else {
         ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT);
@@ -278,7 +278,7 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
     case LOST_TICK_POLICY_DELAY:
         break; /* enabled by default */
     case LOST_TICK_POLICY_DISCARD:
-        if (kvm_check_extension(kvm_state, KVM_CAP_REINJECT_CONTROL)) {
+        if (kvm_check_extension(KVM_CAP_REINJECT_CONTROL)) {
             struct kvm_reinject_control control = { .pit_reinject = 0 };
 
             ret = kvm_vm_ioctl(kvm_state, KVM_REINJECT_CONTROL, &control);
diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c
index 4ba8e47251..718ed8ec6f 100644
--- a/hw/i386/kvm/ioapic.c
+++ b/hw/i386/kvm/ioapic.c
@@ -25,7 +25,7 @@ void kvm_pc_setup_irq_routing(bool pci_enabled)
     KVMState *s = kvm_state;
     int i;
 
-    if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
+    if (kvm_check_extension(KVM_CAP_IRQ_ROUTING)) {
         for (i = 0; i < 8; ++i) {
             if (i == 2) {
                 continue;
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
index d7df423a7a..b98437b265 100644
--- a/hw/intc/arm_gic_kvm.c
+++ b/hw/intc/arm_gic_kvm.c
@@ -551,7 +551,7 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
                               KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true,
                               &error_abort);
         }
-    } else if (kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) {
+    } else if (kvm_check_extension(KVM_CAP_DEVICE_CTRL)) {
         error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
         error_append_hint(errp,
                           "Perhaps the host CPU does not support GICv2?\n");
diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c
index e4bf47d885..b02e914f5f 100644
--- a/hw/intc/openpic_kvm.c
+++ b/hw/intc/openpic_kvm.c
@@ -203,7 +203,7 @@ static void kvm_openpic_realize(DeviceState *dev, Error **errp)
     struct kvm_create_device cd = {0};
     int ret, i;
 
-    if (!kvm_check_extension(s, KVM_CAP_DEVICE_CTRL)) {
+    if (!kvm_check_extension(KVM_CAP_DEVICE_CTRL)) {
         error_setg(errp, "Kernel is lacking Device Control API");
         return;
     }
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 8d6156578f..054648d16b 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -365,7 +365,7 @@ int xics_kvm_connect(SpaprInterruptController *intc, uint32_t nr_servers,
         return 0;
     }
 
-    if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS)) {
+    if (!kvm_enabled() || !kvm_check_extension(KVM_CAP_IRQ_XICS)) {
         error_setg(errp,
                    "KVM and IRQ_XICS capability must be present for in-kernel XICS");
         return -1;
diff --git a/hw/s390x/s390-stattrib-kvm.c b/hw/s390x/s390-stattrib-kvm.c
index f89d8d9d16..77f536f15a 100644
--- a/hw/s390x/s390-stattrib-kvm.c
+++ b/hw/s390x/s390-stattrib-kvm.c
@@ -22,7 +22,7 @@
 Object *kvm_s390_stattrib_create(void)
 {
     if (kvm_enabled() &&
-                kvm_check_extension(kvm_state, KVM_CAP_S390_CMMA_MIGRATION)) {
+                kvm_check_extension(KVM_CAP_S390_CMMA_MIGRATION)) {
         return object_new(TYPE_KVM_S390_STATTRIB);
     }
     return NULL;
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index b4174d941c..3662641c99 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -436,7 +436,7 @@ void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg);
 
 bool kvm_arch_stop_on_emulation_error(CPUState *cpu);
 
-int kvm_check_extension(KVMState *s, unsigned int extension);
+int kvm_check_extension(unsigned int extension);
 
 int kvm_vm_check_extension(KVMState *s, unsigned int extension);
 
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 7c672c78b8..dcdd01916b 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -60,7 +60,7 @@ int kvm_arm_vcpu_finalize(CPUState *cs, int feature)
 
 void kvm_arm_init_serror_injection(CPUState *cs)
 {
-    cap_has_inject_serror_esr = kvm_check_extension(cs->kvm_state,
+    cap_has_inject_serror_esr = kvm_check_extension(
                                     KVM_CAP_ARM_INJECT_SERROR_ESR);
 }
 
@@ -210,15 +210,14 @@ void kvm_arm_add_vcpu_properties(Object *obj)
 
 bool kvm_arm_pmu_supported(void)
 {
-    return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3);
+    return kvm_check_extension(KVM_CAP_ARM_PMU_V3);
 }
 
 int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
 {
-    KVMState *s = KVM_STATE(ms->accelerator);
     int ret;
 
-    ret = kvm_check_extension(s, KVM_CAP_ARM_VM_IPA_SIZE);
+    ret = kvm_check_extension(KVM_CAP_ARM_VM_IPA_SIZE);
     return ret > 0 ? ret : 40;
 }
 
@@ -236,10 +235,10 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
      */
     kvm_halt_in_kernel_allowed = true;
 
-    cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
+    cap_has_mp_state = kvm_check_extension(KVM_CAP_MP_STATE);
 
     if (ms->smp.cpus > 256 &&
-        !kvm_check_extension(s, KVM_CAP_ARM_IRQ_LINE_LAYOUT_2)) {
+        !kvm_check_extension(KVM_CAP_ARM_IRQ_LINE_LAYOUT_2)) {
         error_report("Using more than 256 vcpus requires a host kernel "
                      "with KVM_CAP_ARM_IRQ_LINE_LAYOUT_2");
         ret = -EINVAL;
@@ -870,7 +869,7 @@ int kvm_arch_irqchip_create(KVMState *s)
     /* If we can create the VGIC using the newer device control API, we
      * let the device do this when it initializes itself, otherwise we
      * fall back to the old API */
-    return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL);
+    return kvm_check_extension(KVM_CAP_DEVICE_CTRL);
 }
 
 int kvm_arm_vgic_probe(void)
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
index 7b3a19e9ae..eff0176c8f 100644
--- a/target/arm/kvm32.c
+++ b/target/arm/kvm32.c
@@ -221,7 +221,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
     if (cpu->start_powered_off) {
         cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
     }
-    if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
+    if (kvm_check_extension(KVM_CAP_ARM_PSCI_0_2)) {
         cpu->psci_version = 2;
         cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
     }
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 3dc494aaa7..49ef8ef15f 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -84,14 +84,13 @@ GArray *hw_breakpoints, *hw_watchpoints;
  */
 static void kvm_arm_init_debug(CPUState *cs)
 {
-    have_guest_debug = kvm_check_extension(cs->kvm_state,
-                                           KVM_CAP_SET_GUEST_DEBUG);
+    have_guest_debug = kvm_check_extension(KVM_CAP_SET_GUEST_DEBUG);
 
-    max_hw_wps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_WPS);
+    max_hw_wps = kvm_check_extension(KVM_CAP_GUEST_DEBUG_HW_WPS);
     hw_watchpoints = g_array_sized_new(true, true,
                                        sizeof(HWWatchpoint), max_hw_wps);
 
-    max_hw_bps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_BPS);
+    max_hw_bps = kvm_check_extension(KVM_CAP_GUEST_DEBUG_HW_BPS);
     hw_breakpoints = g_array_sized_new(true, true,
                                        sizeof(HWBreakpoint), max_hw_bps);
     return;
@@ -654,12 +653,12 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
 
 bool kvm_arm_aarch32_supported(void)
 {
-    return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT);
+    return kvm_check_extension(KVM_CAP_ARM_EL1_32BIT);
 }
 
 bool kvm_arm_sve_supported(void)
 {
-    return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
+    return kvm_check_extension(KVM_CAP_ARM_SVE);
 }
 
 QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
@@ -778,14 +777,14 @@ int kvm_arch_init_vcpu(CPUState *cs)
     if (cpu->start_powered_off) {
         cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
     }
-    if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
+    if (kvm_check_extension(KVM_CAP_ARM_PSCI_0_2)) {
         cpu->psci_version = 2;
         cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
     }
     if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
         cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
     }
-    if (!kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
+    if (!kvm_check_extension(KVM_CAP_ARM_PMU_V3)) {
         cpu->has_pmu = false;
     }
     if (cpu->has_pmu) {
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index b8455c89ed..466c4c2b14 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -133,12 +133,12 @@ int kvm_has_pit_state2(void)
 
 bool kvm_has_smm(void)
 {
-    return kvm_check_extension(kvm_state, KVM_CAP_X86_SMM);
+    return kvm_check_extension(KVM_CAP_X86_SMM);
 }
 
 bool kvm_has_adjust_clock_stable(void)
 {
-    int ret = kvm_check_extension(kvm_state, KVM_CAP_ADJUST_CLOCK);
+    int ret = kvm_check_extension(KVM_CAP_ADJUST_CLOCK);
 
     return (ret == KVM_CLOCK_TSC_STABLE);
 }
@@ -294,7 +294,7 @@ static int get_para_features(KVMState *s)
     int i, features = 0;
 
     for (i = 0; i < ARRAY_SIZE(para_features); i++) {
-        if (kvm_check_extension(s, para_features[i].cap)) {
+        if (kvm_check_extension(para_features[i].cap)) {
             features |= (1 << para_features[i].feature);
         }
     }
@@ -386,7 +386,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
          * and the irqchip is in the kernel.
          */
         if (kvm_irqchip_in_kernel() &&
-                kvm_check_extension(s, KVM_CAP_TSC_DEADLINE_TIMER)) {
+                kvm_check_extension(KVM_CAP_TSC_DEADLINE_TIMER)) {
             ret |= CPUID_EXT_TSC_DEADLINE_TIMER;
         }
 
@@ -398,8 +398,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
         }
 
         if (enable_cpu_pm) {
-            int disable_exits = kvm_check_extension(s,
-                                                    KVM_CAP_X86_DISABLE_EXITS);
+            int disable_exits = kvm_check_extension(KVM_CAP_X86_DISABLE_EXITS);
 
             if (disable_exits & KVM_X86_DISABLE_EXITS_MWAIT) {
                 ret |= CPUID_EXT_MONITOR;
@@ -536,7 +535,7 @@ static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap,
 {
     int r;
 
-    r = kvm_check_extension(s, KVM_CAP_MCE);
+    r = kvm_check_extension(KVM_CAP_MCE);
     if (r > 0) {
         *max_banks = r;
         return kvm_ioctl(s, KVM_X86_GET_MCE_CAP_SUPPORTED, mce_cap);
@@ -728,8 +727,7 @@ unsigned long kvm_arch_vcpu_id(CPUState *cs)
 
 static bool hyperv_enabled(X86CPU *cpu)
 {
-    CPUState *cs = CPU(cpu);
-    return kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV) > 0 &&
+    return kvm_check_extension(KVM_CAP_HYPERV) > 0 &&
         ((cpu->hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY) ||
          cpu->hyperv_features || cpu->hyperv_passthrough);
 }
@@ -761,13 +759,13 @@ static int kvm_arch_set_tsc_khz(CPUState *cs)
         return 0;
     }
 
-    cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
+    cur_freq = kvm_check_extension(KVM_CAP_GET_TSC_KHZ) ?
                kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) : -ENOTSUP;
 
     /*
      * If TSC scaling is supported, attempt to set TSC frequency.
      */
-    if (kvm_check_extension(cs->kvm_state, KVM_CAP_TSC_CONTROL)) {
+    if (kvm_check_extension(KVM_CAP_TSC_CONTROL)) {
         set_ioctl = true;
     }
 
@@ -787,7 +785,7 @@ static int kvm_arch_set_tsc_khz(CPUState *cs)
         /* When KVM_SET_TSC_KHZ fails, it's an error only if the current
          * TSC frequency doesn't match the one we want.
          */
-        cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
+        cur_freq = kvm_check_extension(KVM_CAP_GET_TSC_KHZ) ?
                    kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
                    -ENOTSUP;
         if (cur_freq <= 0 || cur_freq != env->tsc_khz) {
@@ -1008,7 +1006,7 @@ static struct kvm_cpuid2 *get_supported_hv_cpuid_legacy(CPUState *cs)
     entry_recomm->function = HV_CPUID_ENLIGHTMENT_INFO;
     entry_recomm->ebx = cpu->hyperv_spinlock_attempts;
 
-    if (kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV) > 0) {
+    if (kvm_check_extension(KVM_CAP_HYPERV) > 0) {
         entry_feat->eax |= HV_HYPERCALL_AVAILABLE;
         entry_feat->eax |= HV_APIC_ACCESS_AVAILABLE;
         entry_feat->edx |= HV_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
@@ -1016,7 +1014,7 @@ static struct kvm_cpuid2 *get_supported_hv_cpuid_legacy(CPUState *cs)
         entry_recomm->eax |= HV_APIC_ACCESS_RECOMMENDED;
     }
 
-    if (kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_TIME) > 0) {
+    if (kvm_check_extension(KVM_CAP_HYPERV_TIME) > 0) {
         entry_feat->eax |= HV_TIME_REF_COUNT_AVAILABLE;
         entry_feat->eax |= HV_REFERENCE_TSC_AVAILABLE;
     }
@@ -1050,7 +1048,7 @@ static struct kvm_cpuid2 *get_supported_hv_cpuid_legacy(CPUState *cs)
         unsigned int cap = cpu->hyperv_synic_kvm_only ?
             KVM_CAP_HYPERV_SYNIC : KVM_CAP_HYPERV_SYNIC2;
 
-        if (kvm_check_extension(cs->kvm_state, cap) > 0) {
+        if (kvm_check_extension(cap) > 0) {
             entry_feat->eax |= HV_SYNIC_AVAILABLE;
         }
     }
@@ -1059,19 +1057,16 @@ static struct kvm_cpuid2 *get_supported_hv_cpuid_legacy(CPUState *cs)
         entry_feat->eax |= HV_SYNTIMERS_AVAILABLE;
     }
 
-    if (kvm_check_extension(cs->kvm_state,
-                            KVM_CAP_HYPERV_TLBFLUSH) > 0) {
+    if (kvm_check_extension(KVM_CAP_HYPERV_TLBFLUSH) > 0) {
         entry_recomm->eax |= HV_REMOTE_TLB_FLUSH_RECOMMENDED;
         entry_recomm->eax |= HV_EX_PROCESSOR_MASKS_RECOMMENDED;
     }
 
-    if (kvm_check_extension(cs->kvm_state,
-                            KVM_CAP_HYPERV_ENLIGHTENED_VMCS) > 0) {
+    if (kvm_check_extension(KVM_CAP_HYPERV_ENLIGHTENED_VMCS) > 0) {
         entry_recomm->eax |= HV_ENLIGHTENED_VMCS_RECOMMENDED;
     }
 
-    if (kvm_check_extension(cs->kvm_state,
-                            KVM_CAP_HYPERV_SEND_IPI) > 0) {
+    if (kvm_check_extension(KVM_CAP_HYPERV_SEND_IPI) > 0) {
         entry_recomm->eax |= HV_CLUSTER_IPI_RECOMMENDED;
         entry_recomm->eax |= HV_EX_PROCESSOR_MASKS_RECOMMENDED;
     }
@@ -1215,7 +1210,7 @@ static int hyperv_handle_properties(CPUState *cs,
         }
     }
 
-    if (kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_CPUID) > 0) {
+    if (kvm_check_extension(KVM_CAP_HYPERV_CPUID) > 0) {
         cpuid = get_supported_hv_cpuid(cs);
     } else {
         cpuid = get_supported_hv_cpuid_legacy(cs);
@@ -1496,7 +1491,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
      * so that vcpu's TSC frequency can be migrated later via this field.
      */
     if (!env->tsc_khz) {
-        r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
+        r = kvm_check_extension(KVM_CAP_GET_TSC_KHZ) ?
             kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
             -ENOTSUP;
         if (r > 0) {
@@ -1737,7 +1732,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
     if (((env->cpuid_version >> 8)&0xF) >= 6
         && (env->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
            (CPUID_MCE | CPUID_MCA)
-        && kvm_check_extension(cs->kvm_state, KVM_CAP_MCE) > 0) {
+        && kvm_check_extension(KVM_CAP_MCE) > 0) {
         uint64_t mcg_cap, unsupported_caps;
         int banks;
         int ret;
@@ -1932,7 +1927,7 @@ static int kvm_get_supported_feature_msrs(KVMState *s)
         return 0;
     }
 
-    if (!kvm_check_extension(s, KVM_CAP_GET_MSR_FEATURES)) {
+    if (!kvm_check_extension(KVM_CAP_GET_MSR_FEATURES)) {
         return 0;
     }
 
@@ -2128,13 +2123,13 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     int ret;
     struct utsname utsname;
 
-    has_xsave = kvm_check_extension(s, KVM_CAP_XSAVE);
-    has_xcrs = kvm_check_extension(s, KVM_CAP_XCRS);
-    has_pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2);
+    has_xsave = kvm_check_extension(KVM_CAP_XSAVE);
+    has_xcrs = kvm_check_extension(KVM_CAP_XCRS);
+    has_pit_state2 = kvm_check_extension(KVM_CAP_PIT_STATE2);
 
-    hv_vpindex_settable = kvm_check_extension(s, KVM_CAP_HYPERV_VP_INDEX);
+    hv_vpindex_settable = kvm_check_extension(KVM_CAP_HYPERV_VP_INDEX);
 
-    has_exception_payload = kvm_check_extension(s, KVM_CAP_EXCEPTION_PAYLOAD);
+    has_exception_payload = kvm_check_extension(KVM_CAP_EXCEPTION_PAYLOAD);
     if (has_exception_payload) {
         ret = kvm_vm_enable_cap(s, KVM_CAP_EXCEPTION_PAYLOAD, 0, true);
         if (ret < 0) {
@@ -2165,7 +2160,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
      * that case we need to stick with the default, i.e. a 256K maximum BIOS
      * size.
      */
-    if (kvm_check_extension(s, KVM_CAP_SET_IDENTITY_MAP_ADDR)) {
+    if (kvm_check_extension(KVM_CAP_SET_IDENTITY_MAP_ADDR)) {
         /* Allows up to 16M BIOSes. */
         identity_base = 0xfeffc000;
 
@@ -2197,7 +2192,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
         }
     }
 
-    if (kvm_check_extension(s, KVM_CAP_X86_SMM) &&
+    if (kvm_check_extension(KVM_CAP_X86_SMM) &&
         object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE) &&
         x86_machine_is_smm_enabled(X86_MACHINE(ms))) {
         smram_machine_done.notify = register_smram_listener;
@@ -2205,7 +2200,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     }
 
     if (enable_cpu_pm) {
-        int disable_exits = kvm_check_extension(s, KVM_CAP_X86_DISABLE_EXITS);
+        int disable_exits = kvm_check_extension(KVM_CAP_X86_DISABLE_EXITS);
         int ret;
 
 /* Work around for kernel header with a typo. TODO: fix header and drop. */
@@ -4546,7 +4541,7 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
 
 void kvm_arch_init_irq_routing(KVMState *s)
 {
-    if (!kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
+    if (!kvm_check_extension(KVM_CAP_IRQ_ROUTING)) {
         /* If kernel can't do irq routing, interrupt source
          * override 0->2 cannot be set up as required by HPET.
          * So we have to disable it.
diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index 72637a1e02..aca12bfdea 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -52,8 +52,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     /* MIPS has 128 signals */
     kvm_set_sigmask_len(s, 16);
 
-    kvm_mips_fpu_cap = kvm_check_extension(s, KVM_CAP_MIPS_FPU);
-    kvm_mips_msa_cap = kvm_check_extension(s, KVM_CAP_MIPS_MSA);
+    kvm_mips_fpu_cap = kvm_check_extension(KVM_CAP_MIPS_FPU);
+    kvm_mips_msa_cap = kvm_check_extension(KVM_CAP_MIPS_MSA);
 
     DPRINTF("%s\n", __func__);
     return 0;
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 2692f76130..ace44d9fc7 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -110,24 +110,24 @@ static int kvmppc_get_dec_bits(void);
 
 int kvm_arch_init(MachineState *ms, KVMState *s)
 {
-    cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ);
-    cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE);
-    cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS);
+    cap_interrupt_unset = kvm_check_extension(KVM_CAP_PPC_UNSET_IRQ);
+    cap_segstate = kvm_check_extension(KVM_CAP_PPC_SEGSTATE);
+    cap_booke_sregs = kvm_check_extension(KVM_CAP_PPC_BOOKE_SREGS);
     cap_ppc_smt_possible = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT_POSSIBLE);
-    cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
-    cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64);
-    cap_spapr_multitce = kvm_check_extension(s, KVM_CAP_SPAPR_MULTITCE);
+    cap_spapr_tce = kvm_check_extension(KVM_CAP_SPAPR_TCE);
+    cap_spapr_tce_64 = kvm_check_extension(KVM_CAP_SPAPR_TCE_64);
+    cap_spapr_multitce = kvm_check_extension(KVM_CAP_SPAPR_MULTITCE);
     cap_spapr_vfio = kvm_vm_check_extension(s, KVM_CAP_SPAPR_TCE_VFIO);
-    cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG);
-    cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR);
-    cap_epr = kvm_check_extension(s, KVM_CAP_PPC_EPR);
-    cap_ppc_watchdog = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_WATCHDOG);
+    cap_one_reg = kvm_check_extension(KVM_CAP_ONE_REG);
+    cap_hior = kvm_check_extension(KVM_CAP_PPC_HIOR);
+    cap_epr = kvm_check_extension(KVM_CAP_PPC_EPR);
+    cap_ppc_watchdog = kvm_check_extension(KVM_CAP_PPC_BOOKE_WATCHDOG);
     /*
      * Note: we don't set cap_papr here, because this capability is
      * only activated after this by kvmppc_set_papr()
      */
     cap_htab_fd = kvm_vm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
-    cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL);
+    cap_fixup_hcalls = kvm_check_extension(KVM_CAP_PPC_FIXUP_HCALL);
     cap_ppc_smt = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT);
     cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM);
     cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX);
@@ -147,7 +147,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
      */
     cap_ppc_pvr_compat = false;
 
-    if (!kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL)) {
+    if (!kvm_check_extension(KVM_CAP_PPC_IRQ_LEVEL)) {
         error_report("KVM: Host kernel doesn't have level irq capability");
         exit(1);
     }
@@ -205,7 +205,7 @@ static int kvm_booke206_tlb_init(PowerPCCPU *cpu)
     int ret, i;
 
     if (!kvm_enabled() ||
-        !kvm_check_extension(cs->kvm_state, KVM_CAP_SW_TLB)) {
+        !kvm_check_extension(KVM_CAP_SW_TLB)) {
         return 0;
     }
 
@@ -246,7 +246,7 @@ static void kvm_get_smmu_info(struct kvm_ppc_smmu_info *info, Error **errp)
 
     assert(kvm_state != NULL);
 
-    if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_GET_SMMU_INFO)) {
+    if (!kvm_check_extension(KVM_CAP_PPC_GET_SMMU_INFO)) {
         error_setg(errp, "KVM doesn't expose the MMU features it supports");
         error_append_hint(errp, "Consider switching to a newer KVM\n");
         return;
@@ -268,7 +268,7 @@ struct ppc_radix_page_info *kvm_get_radix_page_info(void)
     struct kvm_ppc_rmmu_info rmmu_info;
     int i;
 
-    if (!kvm_check_extension(s, KVM_CAP_PPC_MMU_RADIX)) {
+    if (!kvm_check_extension(KVM_CAP_PPC_MMU_RADIX)) {
         return NULL;
     }
     if (kvm_vm_ioctl(s, KVM_PPC_GET_RMMU_INFO, &rmmu_info)) {
@@ -2611,7 +2611,7 @@ int kvmppc_define_rtas_kernel_token(uint32_t token, const char *function)
         .token = token,
     };
 
-    if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_RTAS)) {
+    if (!kvm_check_extension(KVM_CAP_PPC_RTAS)) {
         return -ENOENT;
     }
 
@@ -2828,7 +2828,7 @@ int kvm_handle_nmi(PowerPCCPU *cpu, struct kvm_run *run)
 
 int kvmppc_enable_hwrng(void)
 {
-    if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_PPC_HWRNG)) {
+    if (!kvm_enabled() || !kvm_check_extension(KVM_CAP_PPC_HWRNG)) {
         return -1;
     }
 
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 2fa609bffe..4b6185bb44 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -222,8 +222,7 @@ bool s390_has_feat(S390Feat feat)
 #ifdef CONFIG_KVM
         if (kvm_enabled()) {
             if (feat == S390_FEAT_VECTOR) {
-                return kvm_check_extension(kvm_state,
-                                           KVM_CAP_S390_VECTOR_REGISTERS);
+                return kvm_check_extension(KVM_CAP_S390_VECTOR_REGISTERS);
             }
             if (feat == S390_FEAT_RUNTIME_INSTRUMENTATION) {
                 return kvm_s390_get_ri();
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index f2f75d2a57..710f353fb0 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -342,21 +342,21 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     object_class_foreach(ccw_machine_class_foreach, TYPE_S390_CCW_MACHINE,
                          false, NULL);
 
-    if (!kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) {
+    if (!kvm_check_extension(KVM_CAP_DEVICE_CTRL)) {
         error_report("KVM is missing capability KVM_CAP_DEVICE_CTRL - "
                      "please use kernel 3.15 or newer");
         return -1;
     }
 
-    cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
-    cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
-    cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
-    cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
-    cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);
-    cap_protected = kvm_check_extension(s, KVM_CAP_S390_PROTECTED);
+    cap_sync_regs = kvm_check_extension(KVM_CAP_SYNC_REGS);
+    cap_async_pf = kvm_check_extension(KVM_CAP_ASYNC_PF);
+    cap_mem_op = kvm_check_extension(KVM_CAP_S390_MEM_OP);
+    cap_s390_irq = kvm_check_extension(KVM_CAP_S390_INJECT_IRQ);
+    cap_vcpu_resets = kvm_check_extension(KVM_CAP_S390_VCPU_RESETS);
+    cap_protected = kvm_check_extension(KVM_CAP_S390_PROTECTED);
 
-    if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
-        || !kvm_check_extension(s, KVM_CAP_S390_COW)) {
+    if (!kvm_check_extension(KVM_CAP_S390_GMAP)
+        || !kvm_check_extension(KVM_CAP_S390_COW)) {
         phys_mem_set_alloc(legacy_s390_alloc);
     }
 
@@ -381,7 +381,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
      * newer machine types if KVM_CAP_S390_AIS_MIGRATION is available.
      */
     if (cpu_model_allowed() && kvm_kernel_irqchip_allowed() &&
-        kvm_check_extension(s, KVM_CAP_S390_AIS_MIGRATION)) {
+        kvm_check_extension(KVM_CAP_S390_AIS_MIGRATION)) {
         kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0);
     }
 
@@ -1996,7 +1996,7 @@ void kvm_arch_init_irq_routing(KVMState *s)
      * are handled in-kernel, it is not true for s390 (yet); therefore, we
      * have to override the common code kvm_halt_in_kernel_allowed setting.
      */
-    if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
+    if (kvm_check_extension(KVM_CAP_IRQ_ROUTING)) {
         kvm_gsi_routing_allowed = true;
         kvm_halt_in_kernel_allowed = false;
     }
@@ -2015,7 +2015,7 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
     };
     trace_kvm_assign_subch_ioeventfd(kick.fd, kick.addr, assign,
                                      kick.datamatch);
-    if (!kvm_check_extension(kvm_state, KVM_CAP_IOEVENTFD)) {
+    if (!kvm_check_extension(KVM_CAP_IOEVENTFD)) {
         return -ENOSYS;
     }
     if (!assign) {
@@ -2082,7 +2082,7 @@ void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu)
     CPUState *cs = CPU(cpu);
     int32_t bytes;
 
-    if (!kvm_check_extension(kvm_state, KVM_CAP_S390_IRQ_STATE)) {
+    if (!kvm_check_extension(KVM_CAP_S390_IRQ_STATE)) {
         return;
     }
 
@@ -2109,7 +2109,7 @@ int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu)
         return 0;
     }
 
-    if (!kvm_check_extension(kvm_state, KVM_CAP_S390_IRQ_STATE)) {
+    if (!kvm_check_extension(KVM_CAP_S390_IRQ_STATE)) {
         return -ENOSYS;
     }
 
@@ -2421,7 +2421,7 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
     }
 
     /* bpb needs kernel support for migration, VSIE and reset */
-    if (!kvm_check_extension(kvm_state, KVM_CAP_S390_BPB)) {
+    if (!kvm_check_extension(KVM_CAP_S390_BPB)) {
         clear_bit(S390_FEAT_BPB, model->features);
     }
 
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 47/53] accel/kvm: Simplify kvm_check_extension_list()
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (45 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 46/53] accel/kvm: Simplify kvm_check_extension() Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 48/53] target/i386/kvm: Simplify get_para_features() Paolo Bonzini
                   ` (7 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Cornelia Huck, Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

The KVMState* argument is now unused, drop it.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20200623105052.1700-4-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 accel/kvm/kvm-all.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 7370e3413d..9f9b2005e5 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1088,7 +1088,7 @@ static int kvm_check_many_ioeventfds(void)
 }
 
 static const KVMCapabilityInfo *
-kvm_check_extension_list(KVMState *s, const KVMCapabilityInfo *list)
+kvm_check_extension_list(const KVMCapabilityInfo *list)
 {
     while (list->name) {
         if (!kvm_check_extension(list->value)) {
@@ -2105,10 +2105,10 @@ static int kvm_init(MachineState *ms)
         nc++;
     }
 
-    missing_cap = kvm_check_extension_list(s, kvm_required_capabilites);
+    missing_cap = kvm_check_extension_list(kvm_required_capabilites);
     if (!missing_cap) {
         missing_cap =
-            kvm_check_extension_list(s, kvm_arch_required_capabilities);
+            kvm_check_extension_list(kvm_arch_required_capabilities);
     }
     if (missing_cap) {
         ret = -EINVAL;
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 48/53] target/i386/kvm: Simplify get_para_features()
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (46 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 47/53] accel/kvm: Simplify kvm_check_extension_list() Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 49/53] target/i386/kvm: Simplify kvm_get_mce_cap_supported() Paolo Bonzini
                   ` (6 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Cornelia Huck, Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

The KVMState* argument is now unused, drop it.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20200623105052.1700-6-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/kvm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 466c4c2b14..14be9917f4 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -289,7 +289,7 @@ static const struct kvm_para_features {
     { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
 };
 
-static int get_para_features(KVMState *s)
+static int get_para_features(void)
 {
     int i, features = 0;
 
@@ -446,7 +446,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
 
     /* fallback for older kernels */
     if ((function == KVM_CPUID_FEATURES) && !found) {
-        ret = get_para_features(s);
+        ret = get_para_features();
     }
 
     return ret;
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 49/53] target/i386/kvm: Simplify kvm_get_mce_cap_supported()
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (47 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 48/53] target/i386/kvm: Simplify get_para_features() Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 50/53] target/i386/kvm: Simplify kvm_get_supported_[feature]_msrs() Paolo Bonzini
                   ` (5 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

As the MCE supported capabilities should be the same for
all VMs, it is safe to directly use the global kvm_state.
Remove the unnecessary KVMState* argument.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200623105052.1700-7-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/kvm.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 14be9917f4..cfb6bc15aa 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -530,7 +530,7 @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
     }
 }
 
-static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap,
+static int kvm_get_mce_cap_supported(uint64_t *mce_cap,
                                      int *max_banks)
 {
     int r;
@@ -538,7 +538,7 @@ static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap,
     r = kvm_check_extension(KVM_CAP_MCE);
     if (r > 0) {
         *max_banks = r;
-        return kvm_ioctl(s, KVM_X86_GET_MCE_CAP_SUPPORTED, mce_cap);
+        return kvm_ioctl(kvm_state, KVM_X86_GET_MCE_CAP_SUPPORTED, mce_cap);
     }
     return -ENOSYS;
 }
@@ -1737,7 +1737,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
         int banks;
         int ret;
 
-        ret = kvm_get_mce_cap_supported(cs->kvm_state, &mcg_cap, &banks);
+        ret = kvm_get_mce_cap_supported(&mcg_cap, &banks);
         if (ret < 0) {
             fprintf(stderr, "kvm_get_mce_cap_supported: %s", strerror(-ret));
             return ret;
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 50/53] target/i386/kvm: Simplify kvm_get_supported_[feature]_msrs()
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (48 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 49/53] target/i386/kvm: Simplify kvm_get_mce_cap_supported() Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 51/53] target/i386: Add SERIALIZE cpu feature Paolo Bonzini
                   ` (4 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé

From: Philippe Mathieu-Daudé <philmd@redhat.com>

As the MSR supported features should be the same for all
VMs, it is safe to directly use the global kvm_state.
Remove the unnecessary KVMState* argument.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200623105052.1700-8-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/kvm.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index cfb6bc15aa..a19a1e6769 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1919,7 +1919,7 @@ void kvm_arch_do_init_vcpu(X86CPU *cpu)
     }
 }
 
-static int kvm_get_supported_feature_msrs(KVMState *s)
+static int kvm_get_supported_feature_msrs(void)
 {
     int ret = 0;
 
@@ -1934,7 +1934,7 @@ static int kvm_get_supported_feature_msrs(KVMState *s)
     struct kvm_msr_list msr_list;
 
     msr_list.nmsrs = 0;
-    ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, &msr_list);
+    ret = kvm_ioctl(kvm_state, KVM_GET_MSR_FEATURE_INDEX_LIST, &msr_list);
     if (ret < 0 && ret != -E2BIG) {
         error_report("Fetch KVM feature MSR list failed: %s",
             strerror(-ret));
@@ -1947,7 +1947,8 @@ static int kvm_get_supported_feature_msrs(KVMState *s)
                  msr_list.nmsrs * sizeof(msr_list.indices[0]));
 
     kvm_feature_msrs->nmsrs = msr_list.nmsrs;
-    ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, kvm_feature_msrs);
+    ret = kvm_ioctl(kvm_state, KVM_GET_MSR_FEATURE_INDEX_LIST,
+                    kvm_feature_msrs);
 
     if (ret < 0) {
         error_report("Fetch KVM feature MSR list failed: %s",
@@ -1960,7 +1961,7 @@ static int kvm_get_supported_feature_msrs(KVMState *s)
     return 0;
 }
 
-static int kvm_get_supported_msrs(KVMState *s)
+static int kvm_get_supported_msrs(void)
 {
     int ret = 0;
     struct kvm_msr_list msr_list, *kvm_msr_list;
@@ -1970,7 +1971,7 @@ static int kvm_get_supported_msrs(KVMState *s)
      *  save/restore.
      */
     msr_list.nmsrs = 0;
-    ret = kvm_ioctl(s, KVM_GET_MSR_INDEX_LIST, &msr_list);
+    ret = kvm_ioctl(kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list);
     if (ret < 0 && ret != -E2BIG) {
         return ret;
     }
@@ -1983,7 +1984,7 @@ static int kvm_get_supported_msrs(KVMState *s)
                                           sizeof(msr_list.indices[0])));
 
     kvm_msr_list->nmsrs = msr_list.nmsrs;
-    ret = kvm_ioctl(s, KVM_GET_MSR_INDEX_LIST, kvm_msr_list);
+    ret = kvm_ioctl(kvm_state, KVM_GET_MSR_INDEX_LIST, kvm_msr_list);
     if (ret >= 0) {
         int i;
 
@@ -2139,12 +2140,12 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
         }
     }
 
-    ret = kvm_get_supported_msrs(s);
+    ret = kvm_get_supported_msrs();
     if (ret < 0) {
         return ret;
     }
 
-    kvm_get_supported_feature_msrs(s);
+    kvm_get_supported_feature_msrs();
 
     uname(&utsname);
     lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 51/53] target/i386: Add SERIALIZE cpu feature
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (49 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 50/53] target/i386/kvm: Simplify kvm_get_supported_[feature]_msrs() Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 52/53] target/i386: Enable TSX Suspend Load Address Tracking feature Paolo Bonzini
                   ` (3 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Cathy Zhang

From: Cathy Zhang <cathy.zhang@intel.com>

The availability of the SERIALIZATION instruction is indicated
by the presence of the CPUID feature flag SERIALIZE, which is
defined as CPUID.(EAX=7,ECX=0):ECX[bit 14].

The release spec link is as follows:
https://software.intel.com/content/dam/develop/public/us/en/documents/\
architecture-instruction-set-extensions-programming-reference.pdf

The associated kvm patch link is as follows:
https://lore.kernel.org/patchwork/patch/1268025/

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
Message-Id: <1593991036-12183-2-git-send-email-cathy.zhang@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index be9a0aa76d..fa9353dfba 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -986,7 +986,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
             NULL, NULL, "avx512-4vnniw", "avx512-4fmaps",
             NULL, NULL, NULL, NULL,
             "avx512-vp2intersect", NULL, "md-clear", NULL,
-            NULL, NULL, NULL, NULL,
+            NULL, NULL, "serialize", NULL,
             NULL, NULL, NULL /* pconfig */, NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, "spec-ctrl", "stibp",
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 9284f96896..bd71fe3ef2 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -777,6 +777,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_7_0_EDX_AVX512_4FMAPS     (1U << 3)
 /* AVX512 Vector Pair Intersection to a Pair of Mask Registers */
 #define CPUID_7_0_EDX_AVX512_VP2INTERSECT (1U << 8)
+/* SERIALIZE instruction */
+#define CPUID_7_0_EDX_SERIALIZE         (1U << 14)
 /* Speculation Control */
 #define CPUID_7_0_EDX_SPEC_CTRL         (1U << 26)
 /* Single Thread Indirect Branch Predictors */
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 52/53] target/i386: Enable TSX Suspend Load Address Tracking feature
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (50 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 51/53] target/i386: Add SERIALIZE cpu feature Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 16:41 ` [PULL 53/53] scripts: improve message when TAP based tests fail Paolo Bonzini
                   ` (2 subsequent siblings)
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Cathy Zhang

From: Cathy Zhang <cathy.zhang@intel.com>

This instruction aims to give a way to choose which memory accesses
do not need to be tracked in the TSX read set, which is defined as
CPUID.(EAX=7,ECX=0):EDX[bit 16].

The release spec link is as follows:
https://software.intel.com/content/dam/develop/public/us/en/documents/\
architecture-instruction-set-extensions-programming-reference.pdf

The associated kvm patch link is as follows:
https://lore.kernel.org/patchwork/patch/1268026/

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
Message-Id: <1593991036-12183-3-git-send-email-cathy.zhang@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index fa9353dfba..0df2a2becb 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -987,7 +987,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
             NULL, NULL, NULL, NULL,
             "avx512-vp2intersect", NULL, "md-clear", NULL,
             NULL, NULL, "serialize", NULL,
-            NULL, NULL, NULL /* pconfig */, NULL,
+            "tsx-ldtrk", NULL, NULL /* pconfig */, NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, "spec-ctrl", "stibp",
             NULL, "arch-capabilities", "core-capability", "ssbd",
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index bd71fe3ef2..37fffa5cac 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -779,6 +779,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_7_0_EDX_AVX512_VP2INTERSECT (1U << 8)
 /* SERIALIZE instruction */
 #define CPUID_7_0_EDX_SERIALIZE         (1U << 14)
+/* TSX Suspend Load Address Tracking instruction */
+#define CPUID_7_0_EDX_TSX_LDTRK         (1U << 16)
 /* Speculation Control */
 #define CPUID_7_0_EDX_SPEC_CTRL         (1U << 26)
 /* Single Thread Indirect Branch Predictors */
-- 
2.26.2




^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PULL 53/53] scripts: improve message when TAP based tests fail
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (51 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 52/53] target/i386: Enable TSX Suspend Load Address Tracking feature Paolo Bonzini
@ 2020-07-06 16:41 ` Paolo Bonzini
  2020-07-06 17:19 ` [PULL 00/53] Misc patches for QEMU 5.1 soft freeze no-reply
  2020-07-07 18:37 ` Peter Maydell
  54 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-06 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé

From: Daniel P. Berrangé <berrange@redhat.com>

If one of the qtests fails, the TAP driver prints out a message like:

  ERROR - too few tests run (expected 3, got 1)

which fails to tell you which test program failed. This is a critical
ommission when many tests are running in parallel as their output is
interleaved. The improved message is:

  ERROR endianness-test - too few tests run (expected 3, got 1)

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20200706125054.2619012-1-berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 scripts/tap-driver.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/tap-driver.pl b/scripts/tap-driver.pl
index 6621a5cd67..b1d3880c50 100755
--- a/scripts/tap-driver.pl
+++ b/scripts/tap-driver.pl
@@ -217,7 +217,7 @@ sub report ($;$)
 
 sub testsuite_error ($)
 {
-  report "ERROR", "- $_[0]";
+  report "ERROR", "$test_name - $_[0]";
 }
 
 sub handle_tap_result ($)
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (52 preceding siblings ...)
  2020-07-06 16:41 ` [PULL 53/53] scripts: improve message when TAP based tests fail Paolo Bonzini
@ 2020-07-06 17:19 ` no-reply
  2020-07-07 18:37 ` Peter Maydell
  54 siblings, 0 replies; 76+ messages in thread
From: no-reply @ 2020-07-06 17:19 UTC (permalink / raw)
  To: pbonzini; +Cc: qemu-devel

Patchew URL: https://patchew.org/QEMU/20200706164155.24696-1-pbonzini@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Subject: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
Type: series
Message-id: 20200706164155.24696-1-pbonzini@redhat.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]      patchew/20200630133912.9428-1-f4bug@amsat.org -> patchew/20200630133912.9428-1-f4bug@amsat.org
 - [tag update]      patchew/20200704144943.18292-1-f4bug@amsat.org -> patchew/20200704144943.18292-1-f4bug@amsat.org
 * [new tag]         patchew/20200706164155.24696-1-pbonzini@redhat.com -> patchew/20200706164155.24696-1-pbonzini@redhat.com
Switched to a new branch 'test'
7f86007 scripts: improve message when TAP based tests fail
7248fcd target/i386: Enable TSX Suspend Load Address Tracking feature
866c9c9 target/i386: Add SERIALIZE cpu feature
167c040 target/i386/kvm: Simplify kvm_get_supported_[feature]_msrs()
c84e280 target/i386/kvm: Simplify kvm_get_mce_cap_supported()
4307708 target/i386/kvm: Simplify get_para_features()
35ba753 accel/kvm: Simplify kvm_check_extension_list()
658563b accel/kvm: Simplify kvm_check_extension()
7c2d8c7 accel/kvm: Let kvm_check_extension use global KVM state
4f09921 softmmu/vl: Remove the check for colons in -accel parameters
aae19bd cpu-timers, icount: new modules
d4c3bd1 cpu-throttle: new module, extracted from cpus.c
3f0a1ca softmmu: move softmmu only files from root
0f5f394 pc: fix leak in pc_system_flash_cleanup_unused
d14fbbb cpus: Move CPU code from exec.c to cpus-common.c
6b5e15e target/i386: Correct the warning message of Intel PT
06d34e2 checkpatch: Change occurences of 'kernel' to 'qemu' in user messages
a797e70 iscsi: return -EIO when sense fields are meaningless
483b353 iscsi: handle check condition status in retry loop
45968d9 target/i386: sev: fail query-sev-capabilities if QEMU cannot use SEV
3991cda target/i386: sev: provide proper error reporting for query-sev-capabilities
56fee26 KVM: x86: believe what KVM says about WAITPKG
c2cad97 target/i386: implement undocumented "smsw r32" behavior
0820d30 target/i386: remove gen_io_end
a808c08e Makefile: simplify MINIKCONF rules
492710d accel/tcg: Add stub for probe_access()
9968331 accel/Kconfig: Add the TCG selector
15af609 accel/Kconfig: Extract accel selectors into their own config
f2c9a72 Makefile: Write MINIKCONF variables as one entry per line
e34b354 Makefile: Remove dangerous EOL trailing backslash
e8ca3d5 MAINTAINERS: Cover the HAX accelerator stub
5cf8ecc MAINTAINERS: Add an 'overall' entry for accelerators
828b5c8 MAINTAINERS: Fix KVM path expansion glob
2b33834 MAINTAINERS: Add Cameron as HVF co-maintainer
f83bafe i386: hvf: Clean up synchronize functions
5546118 i386: hvf: Don't duplicate register reset
0100693 i386: hvf: Move Guest LMA reset to macvm_set_cr0()
50ad1f9 i386: hvf: Make long mode enter and exit clearer
7391fcc i386: hvf: Add hvf_cpu_synchronize_pre_loadvm()
d9b7a7b i386: hvf: Move synchronize functions to sysemu
76f44ff i386: hvf: Set env->eip in macvm_set_rip()
4a75f22 coverity: provide Coverity-friendly MIN_CONST and MAX_CONST
8928cb9 KVM: add support for AMD nested live migration
89f8144 target/i386: fix IEEE SSE floating-point exception raising
9140f0b target/i386: set SSE FTZ in correct floating-point state
d38f9f1 hw/core/null-machine: Do not initialize unused chardev backends
c9a48de tests/qmp-cmd-test: Add qmp/object-add-failure-modes
704157d tests/qmp-cmd-test: Add qmp/object-add-duplicate-id
ddc8b9c qom: Introduce object_property_try_add_child()
82cfec7 util/qemu-error: prepend guest name to error message to identify affected VM owner
af648d9 tests: Inject test name also when the test fails
033c1b7 tcg/svm: use host cr4 during NPT page table walk

=== OUTPUT BEGIN ===
1/52 Checking commit 033c1b717196 (tcg/svm: use host cr4 during NPT page table walk)
2/52 Checking commit af648d9d91aa (tests: Inject test name also when the test fails)
3/52 Checking commit 82cfec7d2eab (util/qemu-error: prepend guest name to error message to identify affected VM owner)
4/52 Checking commit ddc8b9c5389f (qom: Introduce object_property_try_add_child())
5/52 Checking commit 704157dd905c (tests/qmp-cmd-test: Add qmp/object-add-duplicate-id)
6/52 Checking commit c9a48de829c1 (tests/qmp-cmd-test: Add qmp/object-add-failure-modes)
7/52 Checking commit d38f9f107573 (hw/core/null-machine: Do not initialize unused chardev backends)
8/52 Checking commit 9140f0b9bb43 (target/i386: set SSE FTZ in correct floating-point state)
9/52 Checking commit 89f8144f4e84 (target/i386: fix IEEE SSE floating-point exception raising)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#312: 
new file mode 100644

ERROR: Use of volatile is usually wrong, please add a comment
#323: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:7:
+volatile float f_res;

ERROR: Use of volatile is usually wrong, please add a comment
#324: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:8:
+volatile double d_res;

ERROR: Use of volatile is usually wrong, please add a comment
#326: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:10:
+volatile float f_snan = __builtin_nansf("");

ERROR: Use of volatile is usually wrong, please add a comment
#327: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:11:
+volatile float f_half = 0.5f;

ERROR: Use of volatile is usually wrong, please add a comment
#328: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:12:
+volatile float f_third = 1.0f / 3.0f;

ERROR: Use of volatile is usually wrong, please add a comment
#329: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:13:
+volatile float f_nan = __builtin_nanl("");

ERROR: Use of volatile is usually wrong, please add a comment
#330: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:14:
+volatile float f_inf = __builtin_inff();

ERROR: Use of volatile is usually wrong, please add a comment
#331: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:15:
+volatile float f_ninf = -__builtin_inff();

ERROR: Use of volatile is usually wrong, please add a comment
#332: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:16:
+volatile float f_one = 1.0f;

ERROR: Use of volatile is usually wrong, please add a comment
#333: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:17:
+volatile float f_two = 2.0f;

ERROR: Use of volatile is usually wrong, please add a comment
#334: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:18:
+volatile float f_zero = 0.0f;

ERROR: Use of volatile is usually wrong, please add a comment
#335: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:19:
+volatile float f_nzero = -0.0f;

ERROR: Use of volatile is usually wrong, please add a comment
#336: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:20:
+volatile float f_min = FLT_MIN;

ERROR: spaces required around that '-' (ctx:VxV)
#337: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:21:
+volatile float f_true_min = 0x1p-149f;
                                 ^

ERROR: Use of volatile is usually wrong, please add a comment
#337: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:21:
+volatile float f_true_min = 0x1p-149f;

ERROR: Use of volatile is usually wrong, please add a comment
#338: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:22:
+volatile float f_max = FLT_MAX;

ERROR: Use of volatile is usually wrong, please add a comment
#339: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:23:
+volatile float f_nmax = -FLT_MAX;

ERROR: Use of volatile is usually wrong, please add a comment
#341: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:25:
+volatile double d_snan = __builtin_nans("");

ERROR: Use of volatile is usually wrong, please add a comment
#342: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:26:
+volatile double d_half = 0.5;

ERROR: Use of volatile is usually wrong, please add a comment
#343: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:27:
+volatile double d_third = 1.0 / 3.0;

ERROR: Use of volatile is usually wrong, please add a comment
#344: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:28:
+volatile double d_nan = __builtin_nan("");

ERROR: Use of volatile is usually wrong, please add a comment
#345: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:29:
+volatile double d_inf = __builtin_inf();

ERROR: Use of volatile is usually wrong, please add a comment
#346: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:30:
+volatile double d_ninf = -__builtin_inf();

ERROR: Use of volatile is usually wrong, please add a comment
#347: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:31:
+volatile double d_one = 1.0;

ERROR: Use of volatile is usually wrong, please add a comment
#348: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:32:
+volatile double d_two = 2.0;

ERROR: Use of volatile is usually wrong, please add a comment
#349: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:33:
+volatile double d_zero = 0.0;

ERROR: Use of volatile is usually wrong, please add a comment
#350: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:34:
+volatile double d_nzero = -0.0;

ERROR: Use of volatile is usually wrong, please add a comment
#351: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:35:
+volatile double d_min = DBL_MIN;

ERROR: spaces required around that '-' (ctx:VxV)
#352: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:36:
+volatile double d_true_min = 0x1p-1074;
                                  ^

ERROR: Use of volatile is usually wrong, please add a comment
#352: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:36:
+volatile double d_true_min = 0x1p-1074;

ERROR: Use of volatile is usually wrong, please add a comment
#353: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:37:
+volatile double d_max = DBL_MAX;

ERROR: Use of volatile is usually wrong, please add a comment
#354: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:38:
+volatile double d_nmax = -DBL_MAX;

ERROR: Use of volatile is usually wrong, please add a comment
#356: FILE: tests/tcg/i386/test-i386-sse-exceptions.c:40:
+volatile int32_t i32_max = INT32_MAX;

total: 33 errors, 1 warnings, 1033 lines checked

Patch 9/52 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

10/52 Checking commit 8928cb91c066 (KVM: add support for AMD nested live migration)
11/52 Checking commit 4a75f22d725a (coverity: provide Coverity-friendly MIN_CONST and MAX_CONST)
WARNING: architecture specific defines should be avoided
#59: FILE: include/qemu/osdep.h:269:
+#ifdef __COVERITY__

total: 0 errors, 1 warnings, 43 lines checked

Patch 11/52 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
12/52 Checking commit 76f44ffc910f (i386: hvf: Set env->eip in macvm_set_rip())
13/52 Checking commit d9b7a7b91271 (i386: hvf: Move synchronize functions to sysemu)
14/52 Checking commit 7391fccb4503 (i386: hvf: Add hvf_cpu_synchronize_pre_loadvm())
15/52 Checking commit 50ad1f938adf (i386: hvf: Make long mode enter and exit clearer)
16/52 Checking commit 0100693ac7a2 (i386: hvf: Move Guest LMA reset to macvm_set_cr0())
17/52 Checking commit 554611882eb3 (i386: hvf: Don't duplicate register reset)
18/52 Checking commit f83bafef5a99 (i386: hvf: Clean up synchronize functions)
19/52 Checking commit 2b3383479e0d (MAINTAINERS: Add Cameron as HVF co-maintainer)
20/52 Checking commit 828b5c8302e9 (MAINTAINERS: Fix KVM path expansion glob)
21/52 Checking commit 5cf8ecc8f350 (MAINTAINERS: Add an 'overall' entry for accelerators)
22/52 Checking commit e8ca3d539b13 (MAINTAINERS: Cover the HAX accelerator stub)
23/52 Checking commit e34b3545f9a6 (Makefile: Remove dangerous EOL trailing backslash)
24/52 Checking commit f2c9a722a19c (Makefile: Write MINIKCONF variables as one entry per line)
25/52 Checking commit 15af6093c279 (accel/Kconfig: Extract accel selectors into their own config)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#54: 
new file mode 100644

total: 0 errors, 1 warnings, 32 lines checked

Patch 25/52 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
26/52 Checking commit 9968331c3247 (accel/Kconfig: Add the TCG selector)
27/52 Checking commit 492710dfc756 (accel/tcg: Add stub for probe_access())
28/52 Checking commit a808c08ef0d8 (Makefile: simplify MINIKCONF rules)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#16: 
new file mode 100644

total: 0 errors, 1 warnings, 28 lines checked

Patch 28/52 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
29/52 Checking commit 0820d3077474 (target/i386: remove gen_io_end)
30/52 Checking commit c2cad9776a49 (target/i386: implement undocumented "smsw r32" behavior)
31/52 Checking commit 56fee26334f0 (KVM: x86: believe what KVM says about WAITPKG)
32/52 Checking commit 3991cda076dd (target/i386: sev: provide proper error reporting for query-sev-capabilities)
33/52 Checking commit 45968d9ca1b9 (target/i386: sev: fail query-sev-capabilities if QEMU cannot use SEV)
34/52 Checking commit 483b353452de (iscsi: handle check condition status in retry loop)
35/52 Checking commit a797e707f8ab (iscsi: return -EIO when sense fields are meaningless)
36/52 Checking commit 06d34e2e7bbb (checkpatch: Change occurences of 'kernel' to 'qemu' in user messages)
37/52 Checking commit 6b5e15e3daec (target/i386: Correct the warning message of Intel PT)
38/52 Checking commit d14fbbb355b8 (cpus: Move CPU code from exec.c to cpus-common.c)
39/52 Checking commit 0f5f394e08c5 (pc: fix leak in pc_system_flash_cleanup_unused)
40/52 Checking commit 3f0a1caeda2a (softmmu: move softmmu only files from root)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#123: 
rename from arch_init.c

total: 0 errors, 1 warnings, 83 lines checked

Patch 40/52 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
41/52 Checking commit d4c3bd176306 (cpu-throttle: new module, extracted from cpus.c)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#106: 
new file mode 100644

total: 0 errors, 1 warnings, 396 lines checked

Patch 41/52 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
42/52 Checking commit aae19bd9ead0 (cpu-timers, icount: new modules)
WARNING: line over 80 characters
#110: FILE: accel/tcg/cpu-exec.c:107:
+            qemu_printf("Warning: The guest is now late by %.1f to %.1f seconds\n",

WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#424: 
new file mode 100644

total: 0 errors, 2 warnings, 2430 lines checked

Patch 42/52 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
43/52 Checking commit 4f099211e22d (softmmu/vl: Remove the check for colons in -accel parameters)
44/52 Checking commit 7c2d8c7d13ca (accel/kvm: Let kvm_check_extension use global KVM state)
45/52 Checking commit 658563be1173 (accel/kvm: Simplify kvm_check_extension())
ERROR: space prohibited after that open parenthesis '('
#138: FILE: accel/kvm/kvm-all.c:2125:
+        kvm_check_extension( KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);

total: 1 errors, 0 warnings, 757 lines checked

Patch 45/52 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

46/52 Checking commit 35ba7530aa2c (accel/kvm: Simplify kvm_check_extension_list())
47/52 Checking commit 43077084eb85 (target/i386/kvm: Simplify get_para_features())
48/52 Checking commit c84e280ac321 (target/i386/kvm: Simplify kvm_get_mce_cap_supported())
49/52 Checking commit 167c0409c6dc (target/i386/kvm: Simplify kvm_get_supported_[feature]_msrs())
50/52 Checking commit 866c9c9b3cc2 (target/i386: Add SERIALIZE cpu feature)
51/52 Checking commit 7248fcd37ec6 (target/i386: Enable TSX Suspend Load Address Tracking feature)
WARNING: Block comments use a leading /* on a separate line
#32: FILE: target/i386/cpu.c:990:
+            "tsx-ldtrk", NULL, NULL /* pconfig */, NULL,

total: 0 errors, 1 warnings, 16 lines checked

Patch 51/52 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
52/52 Checking commit 7f86007e8aa6 (scripts: improve message when TAP based tests fail)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20200706164155.24696-1-pbonzini@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 31/53] KVM: x86: believe what KVM says about WAITPKG
  2020-07-06 16:41 ` [PULL 31/53] KVM: x86: believe what KVM says about WAITPKG Paolo Bonzini
@ 2020-07-07 11:42   ` Maxim Levitsky
  2020-07-07 11:58     ` Paolo Bonzini
  2021-12-22  9:35   ` Chenyi Qiang
  1 sibling, 1 reply; 76+ messages in thread
From: Maxim Levitsky @ 2020-07-07 11:42 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: qemu-stable

On Mon, 2020-07-06 at 12:41 -0400, Paolo Bonzini wrote:
> Currently, QEMU is overriding KVM_GET_SUPPORTED_CPUID's answer for
> the WAITPKG bit depending on the "-overcommit cpu-pm" setting.  This is a
> bad idea because it does not even check if the host supports it, but it
> can be done in x86_cpu_realizefn just like we do for the MONITOR bit.
> 
> This patch moves it there, while making it conditional on host
> support for the related UMWAIT MSR.
> 
> Cc: qemu-stable@nongnu.org
> Reported-by: Maxim Levitsky <mlevitsk@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  target/i386/cpu.c      |  3 +++
>  target/i386/kvm.c      | 11 +++++------
>  target/i386/kvm_i386.h |  1 +
>  3 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index c44cc510e1..dc9ba06f1f 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -6536,6 +6536,9 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
>              host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx,
>                         &cpu->mwait.ecx, &cpu->mwait.edx);
>              env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR;
> +            if (kvm_enabled() && kvm_has_waitpkg()) {
> +                env->features[FEAT_7_0_ECX] |= CPUID_7_0_ECX_WAITPKG;
> +            }
>          }
>          if (kvm_enabled() && cpu->ucode_rev == 0) {
>              cpu->ucode_rev = kvm_arch_get_supported_msr_feature(kvm_state,
> diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> index 2b6b7443d2..b8455c89ed 100644
> --- a/target/i386/kvm.c
> +++ b/target/i386/kvm.c
> @@ -411,12 +411,6 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
>          if (host_tsx_blacklisted()) {
>              ret &= ~(CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_HLE);
>          }
> -    } else if (function == 7 && index == 0 && reg == R_ECX) {
> -        if (enable_cpu_pm) {
> -            ret |= CPUID_7_0_ECX_WAITPKG;
> -        } else {
> -            ret &= ~CPUID_7_0_ECX_WAITPKG;
> -        }
>      } else if (function == 7 && index == 0 && reg == R_EDX) {
>          /*
>           * Linux v4.17-v4.20 incorrectly return ARCH_CAPABILITIES on SVM hosts.
> @@ -4730,3 +4724,8 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
>  {
>      abort();
>  }
> +
> +bool kvm_has_waitpkg(void)
> +{
> +    return has_msr_umwait;
Note that this depends on the fix in the kernel
to report this msr only when UMWAIT is supported.
I personally don't mind that.

If we want to support older kernels that don't,
then we have to run 'cpuid' ourselves and check the result.

Otherwise looks good to me.

Best regards,
	Maxim Levitsky

> +}
> diff --git a/target/i386/kvm_i386.h b/target/i386/kvm_i386.h
> index 00bde7acaf..064b8798a2 100644
> --- a/target/i386/kvm_i386.h
> +++ b/target/i386/kvm_i386.h
> @@ -44,6 +44,7 @@ void kvm_put_apicbase(X86CPU *cpu, uint64_t value);
>  
>  bool kvm_enable_x2apic(void);
>  bool kvm_has_x2apic_api(void);
> +bool kvm_has_waitpkg(void);
>  
>  bool kvm_hv_vpindex_settable(void);
>  




^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 31/53] KVM: x86: believe what KVM says about WAITPKG
  2020-07-07 11:42   ` Maxim Levitsky
@ 2020-07-07 11:58     ` Paolo Bonzini
  0 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-07 11:58 UTC (permalink / raw)
  To: Maxim Levitsky, qemu-devel; +Cc: qemu-stable

On 07/07/20 13:42, Maxim Levitsky wrote:
>> +bool kvm_has_waitpkg(void)
>> +{
>> +    return has_msr_umwait;
> Note that this depends on the fix in the kernel
> to report this msr only when UMWAIT is supported.
> I personally don't mind that.
> 
> If we want to support older kernels that don't,
> then we have to run 'cpuid' ourselves and check the result.
> 
> Otherwise looks good to me.

Yes, the original kernel version was completely busted but fortunately
the fix will make it into stable kernels, probably faster than it can
make into QEMU releases...

Paolo



^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
                   ` (53 preceding siblings ...)
  2020-07-06 17:19 ` [PULL 00/53] Misc patches for QEMU 5.1 soft freeze no-reply
@ 2020-07-07 18:37 ` Peter Maydell
  2020-07-07 18:42   ` Peter Maydell
                     ` (2 more replies)
  54 siblings, 3 replies; 76+ messages in thread
From: Peter Maydell @ 2020-07-07 18:37 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On Mon, 6 Jul 2020 at 17:48, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> The following changes since commit fc1bff958998910ec8d25db86cd2f53ff125f7ab:
>
>   hw/misc/pca9552: Add missing TypeInfo::class_size field (2020-06-29 21:16:10 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to 80270507070ec73ea82741ce24cb7909a9258ea3:
>
>   scripts: improve message when TAP based tests fail (2020-07-06 12:14:25 -0400)
>
> ----------------------------------------------------------------
> * Make checkpatch say 'qemu' instead of 'kernel' (Aleksandar)
> * Fix PSE guests with emulated NPT (Alexander B. #1)
> * Fix leak (Alexander B. #2)
> * HVF fixes (Roman, Cameron)
> * New Sapphire Rapids CPUID bits (Cathy)
> * cpus.c and softmmu/ cleanups (Claudio)
> * TAP driver tweaks (Daniel, Havard)
> * object-add bugfix and testcases (Eric A.)
> * Fix Coverity MIN_CONST and MAX_CONST (Eric B.)
> * SSE fixes (Joseph)
> * "-msg guest-name" option (Mario)
> * support for AMD nested live migration (myself)
> * Small i386 TCG fixes (myself)
> * improved error reporting for Xen (myself)
> * fix "-cpu host -overcommit cpu-pm=on" (myself)
> * Add accel/Kconfig (Philippe)
> * KVM API cleanup (Philippe)
> * iscsi sense handling fixes (Yongji)
> * Misc bugfixes

Hi; various build or test failures (5 total):

1) OSX:

/Users/pm215/src/qemu-for-merges/ui/cocoa.m:1478:9: error: implicit
declaration of function 'cpu_throttle_set' is invalid in C99 [-
Werror,-Wimplicit-function-declaration]
        cpu_throttle_set(throttle_pct);
        ^

2) aarch64 and aarch32 linux:

/home/pm/qemu/target/arm/kvm.c: In function ‘kvm_arch_init’:
/home/pm/qemu/target/arm/kvm.c:248:29: error: passing argument 1 of
‘kvm_check_extension’ makes integer from pointer without a cast
 [-Werror=int-conversion]
  248 |     if (kvm_check_extension(s, KVM_CAP_ARM_NISV_TO_USER)) {
      |                             ^
      |                             |
      |                             KVMState * {aka struct KVMState *}
In file included from /home/pm/qemu/target/arm/kvm.c:23:
/home/pm/qemu/include/sysemu/kvm.h:439:38: note: expected ‘unsigned
int’ but argument is of type ‘KVMState *’ {aka ‘struct KVMState
 *’}
  439 | int kvm_check_extension(unsigned int extension);
      |                         ~~~~~~~~~~~~~^~~~~~~~~
/home/pm/qemu/target/arm/kvm.c:248:9: error: too many arguments to
function ‘kvm_check_extension’
  248 |     if (kvm_check_extension(s, KVM_CAP_ARM_NISV_TO_USER)) {
      |         ^~~~~~~~~~~~~~~~~~~
In file included from /home/pm/qemu/target/arm/kvm.c:23:
/home/pm/qemu/include/sysemu/kvm.h:439:5: note: declared here
  439 | int kvm_check_extension(unsigned int extension);
      |     ^~~~~~~~~~~~~~~~~~~
/home/pm/qemu/target/arm/kvm.c:253:59: error: passing argument 1 of
‘kvm_check_extension’ makes integer from pointer without a cast
 [-Werror=int-conversion]
  253 |             cap_has_inject_ext_dabt = kvm_check_extension(s,
      |                                                           ^
      |                                                           |
      |
KVMState * {aka struct KVMState *}
In file included from /home/pm/qemu/target/arm/kvm.c:23:
/home/pm/qemu/include/sysemu/kvm.h:439:38: note: expected ‘unsigned
int’ but argument is of type ‘KVMState *’ {aka ‘struct KVMState
 *’}
  439 | int kvm_check_extension(unsigned int extension);
      |                         ~~~~~~~~~~~~~^~~~~~~~~
/home/pm/qemu/target/arm/kvm.c:253:39: error: too many arguments to
function ‘kvm_check_extension’
  253 |             cap_has_inject_ext_dabt = kvm_check_extension(s,
      |                                       ^~~~~~~~~~~~~~~~~~~
In file included from /home/pm/qemu/target/arm/kvm.c:23:
/home/pm/qemu/include/sysemu/kvm.h:439:5: note: declared here
  439 | int kvm_check_extension(unsigned int extension);
      |     ^~~~~~~~~~~~~~~~~~~

3) PPC64 had a failure on iotest 030 (though I think this may
be an intermittent in master):

  TEST    iotest-qcow2: 030 [fail]
QEMU          --
"/home/pm215/qemu/build/all/tests/qemu-iotests/../../ppc64-softmmu/qemu-system-ppc64"
-nodefaults -display none -accel qtest
QEMU_IMG      -- "/home/pm215/qemu/build/all/tests/qemu-iotests/../../qemu-img"
QEMU_IO       --
"/home/pm215/qemu/build/all/tests/qemu-iotests/../../qemu-io"  --cache
writeback --aio threads -f qcow2
QEMU_NBD      -- "/home/pm215/qemu/build/all/tests/qemu-iotests/../../qemu-nbd"
IMGFMT        -- qcow2 (compat=1.1)
IMGPROTO      -- file
PLATFORM      -- Linux/ppc64 gcc1-power7 3.10.0-862.14.4.el7.ppc64
TEST_DIR      -- /home/pm215/qemu/build/all/tests/qemu-iotests/scratch
SOCK_DIR      -- /tmp/tmp.icAW30swbG
SOCKET_SCM_HELPER --
/home/pm215/qemu/build/all/tests/qemu-iotests/socket_scm_helper

--- /home/pm215/qemu/tests/qemu-iotests/030.out 2019-07-15
15:12:04.941863802 +0000
+++ /home/pm215/qemu/build/all/tests/qemu-iotests/030.out.bad
2020-07-07 18:01:06.975652394 +0000
@@ -1,5 +1,17 @@
-...........................
+.............F.............
+======================================================================
+FAIL: test_stream_parallel (__main__.TestParallelOps)
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "030", line 246, in test_stream_parallel
+    self.assert_qmp(result, 'return', {})
+  File "/home/pm215/qemu/tests/qemu-iotests/iotests.py", line 848, in
assert_qmp
+    result = self.dictpath(d, path)
+  File "/home/pm215/qemu/tests/qemu-iotests/iotests.py", line 822, in dictpath
+    self.fail(f'failed path traversal for "{path}" in "{d}"')
+AssertionError: failed path traversal for "return" in "{'error':
{'class': 'DeviceNotActive', 'desc': "Block job 'stream-node8' not
found"}}"
+
 ----------------------------------------------------------------------
 Ran 27 tests

-OK
+FAILED (failures=1)

4) s390x failed on iotest 267:

  TEST    iotest-qcow2: 267 [fail]
QEMU          --
"/home/ubuntu/qemu/build/all/tests/qemu-iotests/../../s390x-softmmu/qemu-system-s390x"
-nodefaults -display none -accel qtest
QEMU_IMG      -- "/home/ubuntu/qemu/build/all/tests/qemu-iotests/../../qemu-img"
QEMU_IO       --
"/home/ubuntu/qemu/build/all/tests/qemu-iotests/../../qemu-io"
--cache writeback --aio threads -f qcow2
QEMU_NBD      -- "/home/ubuntu/qemu/build/all/tests/qemu-iotests/../../qemu-nbd"
IMGFMT        -- qcow2 (compat=1.1)
IMGPROTO      -- file
PLATFORM      -- Linux/s390x qemu01 4.15.0-72-generic
TEST_DIR      -- /home/ubuntu/qemu/build/all/tests/qemu-iotests/scratch
SOCK_DIR      -- /tmp/tmp.REW8Sy64t9
SOCKET_SCM_HELPER --
/home/ubuntu/qemu/build/all/tests/qemu-iotests/socket_scm_helper

--- /home/ubuntu/qemu/tests/qemu-iotests/267.out        2019-12-19
08:32:33.382319918 -0500
+++ /home/ubuntu/qemu/build/all/tests/qemu-iotests/267.out.bad
2020-07-07 14:15:44.173300793 -0400
@@ -137,6 +137,9 @@
 ID        TAG                 VM SIZE                DATE       VM CLOCK
 --        snap0                  SIZE yyyy-mm-dd hh:mm:ss   00:00:00.000
 (qemu) loadvm snap0
+Unexpected storage key flag data: 0
+error while loading state for instance 0x0 of device 's390-skeys'
+Error: Error -22 while loading VM state
 (qemu) quit

 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
backing_file=TEST_DIR/t.IMGFMT.base

5) And a link error on x86-64 Linux:

  LINK    x86_64-softmmu/qemu-system-x86_64
softmmu/cpus.o: In function `tcg_get_icount_limit':
/home/petmay01/linaro/qemu-for-merges/softmmu/cpus.c:563: undefined
reference to `icount_round'
softmmu/cpus.o: In function `process_icount_data':
/home/petmay01/linaro/qemu-for-merges/softmmu/cpus.c:618: undefined
reference to `icount_update'
target/i386/helper.o: In function `x86_cpu_dump_state':
/home/petmay01/linaro/qemu-for-merges/target/i386/helper.c:547:
undefined reference to `update_mxcsr_from_sse_status'
target/i386/gdbstub.o: In function `x86_cpu_gdb_read_register':
/home/petmay01/linaro/qemu-for-merges/target/i386/gdbstub.c:187:
undefined reference to `update_mxcsr_from_sse_status'
collect2: error: ld returned 1 exit status
Makefile:205: recipe for target 'qemu-system-x86_64' failed

thanks
-- PMM


^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-07 18:37 ` Peter Maydell
@ 2020-07-07 18:42   ` Peter Maydell
  2020-07-07 18:48     ` Paolo Bonzini
  2020-07-08  8:25   ` Philippe Mathieu-Daudé
  2020-07-08 16:13   ` Claudio Fontana
  2 siblings, 1 reply; 76+ messages in thread
From: Peter Maydell @ 2020-07-07 18:42 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On Tue, 7 Jul 2020 at 19:37, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Mon, 6 Jul 2020 at 17:48, Paolo Bonzini <pbonzini@redhat.com> wrote:
> >
> > The following changes since commit fc1bff958998910ec8d25db86cd2f53ff125f7ab:
> >
> >   hw/misc/pca9552: Add missing TypeInfo::class_size field (2020-06-29 21:16:10 +0100)
> >
> > are available in the Git repository at:
> >
> >   git://github.com/bonzini/qemu.git tags/for-upstream
> >
> > for you to fetch changes up to 80270507070ec73ea82741ce24cb7909a9258ea3:
> >
> >   scripts: improve message when TAP based tests fail (2020-07-06 12:14:25 -0400)
> >
> > ----------------------------------------------------------------
> > * Make checkpatch say 'qemu' instead of 'kernel' (Aleksandar)
> > * Fix PSE guests with emulated NPT (Alexander B. #1)
> > * Fix leak (Alexander B. #2)
> > * HVF fixes (Roman, Cameron)
> > * New Sapphire Rapids CPUID bits (Cathy)
> > * cpus.c and softmmu/ cleanups (Claudio)
> > * TAP driver tweaks (Daniel, Havard)
> > * object-add bugfix and testcases (Eric A.)
> > * Fix Coverity MIN_CONST and MAX_CONST (Eric B.)
> > * SSE fixes (Joseph)
> > * "-msg guest-name" option (Mario)
> > * support for AMD nested live migration (myself)
> > * Small i386 TCG fixes (myself)
> > * improved error reporting for Xen (myself)
> > * fix "-cpu host -overcommit cpu-pm=on" (myself)
> > * Add accel/Kconfig (Philippe)
> > * KVM API cleanup (Philippe)
> > * iscsi sense handling fixes (Yongji)
> > * Misc bugfixes
>
> Hi; various build or test failures (5 total):

Also it broke my working tree, in the sense that when I
rolled back to current master incremental-rebuild didn't
work but instead failed with:

make: *** No rule to make target '/home/ubuntu/qemu/Kconfig', needed
by 'aarch64-softmmu/config-devices.mak'.  Stop.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-07 18:42   ` Peter Maydell
@ 2020-07-07 18:48     ` Paolo Bonzini
  0 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-07 18:48 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 570 bytes --]

Il mar 7 lug 2020, 20:42 Peter Maydell <peter.maydell@linaro.org> ha
scritto:

> Also it broke my working tree, in the sense that when I
> rolled back to current master incremental-rebuild didn't
> work but instead failed with:
>
> make: *** No rule to make target '/home/ubuntu/qemu/Kconfig', needed
> by 'aarch64-softmmu/config-devices.mak'.  Stop.
>

The latter is unfortunately expected. I am curious about the s390 failure
and especially the x86 link failure which might be a semantic conflict. I
will try to reproduce them locally.

Paolo

>
> thanks
> -- PMM
>
>

[-- Attachment #2: Type: text/html, Size: 1162 bytes --]

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-07 18:37 ` Peter Maydell
  2020-07-07 18:42   ` Peter Maydell
@ 2020-07-08  8:25   ` Philippe Mathieu-Daudé
  2020-07-08 16:13   ` Claudio Fontana
  2 siblings, 0 replies; 76+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-07-08  8:25 UTC (permalink / raw)
  To: Peter Maydell, Paolo Bonzini; +Cc: QEMU Developers

On 7/7/20 8:37 PM, Peter Maydell wrote:
> On Mon, 6 Jul 2020 at 17:48, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>
>> The following changes since commit fc1bff958998910ec8d25db86cd2f53ff125f7ab:
>>
>>   hw/misc/pca9552: Add missing TypeInfo::class_size field (2020-06-29 21:16:10 +0100)
>>
>> are available in the Git repository at:
>>
>>   git://github.com/bonzini/qemu.git tags/for-upstream
>>
>> for you to fetch changes up to 80270507070ec73ea82741ce24cb7909a9258ea3:
>>
>>   scripts: improve message when TAP based tests fail (2020-07-06 12:14:25 -0400)
>>
>> ----------------------------------------------------------------
>> * Make checkpatch say 'qemu' instead of 'kernel' (Aleksandar)
>> * Fix PSE guests with emulated NPT (Alexander B. #1)
>> * Fix leak (Alexander B. #2)
>> * HVF fixes (Roman, Cameron)
>> * New Sapphire Rapids CPUID bits (Cathy)
>> * cpus.c and softmmu/ cleanups (Claudio)
>> * TAP driver tweaks (Daniel, Havard)
>> * object-add bugfix and testcases (Eric A.)
>> * Fix Coverity MIN_CONST and MAX_CONST (Eric B.)
>> * SSE fixes (Joseph)
>> * "-msg guest-name" option (Mario)
>> * support for AMD nested live migration (myself)
>> * Small i386 TCG fixes (myself)
>> * improved error reporting for Xen (myself)
>> * fix "-cpu host -overcommit cpu-pm=on" (myself)
>> * Add accel/Kconfig (Philippe)
>> * KVM API cleanup (Philippe)
>> * iscsi sense handling fixes (Yongji)
>> * Misc bugfixes
> 
> Hi; various build or test failures (5 total):

> 2) aarch64 and aarch32 linux:
> 
> /home/pm/qemu/target/arm/kvm.c: In function ‘kvm_arch_init’:
> /home/pm/qemu/target/arm/kvm.c:248:29: error: passing argument 1 of
> ‘kvm_check_extension’ makes integer from pointer without a cast
>  [-Werror=int-conversion]
>   248 |     if (kvm_check_extension(s, KVM_CAP_ARM_NISV_TO_USER)) {
>       |                             ^
>       |                             |
>       |                             KVMState * {aka struct KVMState *}

I was sure I tested that on ARM hosts, so I double checked and
this code is new, merged last Saturday in 1711bfa5f5 ("target/arm: kvm:
Handle misconfigured dabt injection"), so an unfortunate merge race
problem.

> 3) PPC64 had a failure on iotest 030 (though I think this may
> be an intermittent in master):
> 
>   TEST    iotest-qcow2: 030 [fail]
[...]
> +AssertionError: failed path traversal for "return" in "{'error':
> {'class': 'DeviceNotActive', 'desc': "Block job 'stream-node8' not
> found"}}"

So this is now more intermittent, and this has been reported on:
- Linux/x86
- FreeBSD/x86
- Linux/ppc64



^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-07 18:37 ` Peter Maydell
  2020-07-07 18:42   ` Peter Maydell
  2020-07-08  8:25   ` Philippe Mathieu-Daudé
@ 2020-07-08 16:13   ` Claudio Fontana
  2020-07-08 16:16     ` Paolo Bonzini
  2 siblings, 1 reply; 76+ messages in thread
From: Claudio Fontana @ 2020-07-08 16:13 UTC (permalink / raw)
  To: Peter Maydell, Paolo Bonzini; +Cc: QEMU Developers

On 7/7/20 8:37 PM, Peter Maydell wrote:
> On Mon, 6 Jul 2020 at 17:48, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>
>> The following changes since commit fc1bff958998910ec8d25db86cd2f53ff125f7ab:
>>
>>   hw/misc/pca9552: Add missing TypeInfo::class_size field (2020-06-29 21:16:10 +0100)
>>
>> are available in the Git repository at:
>>
>>   git://github.com/bonzini/qemu.git tags/for-upstream
>>
>> for you to fetch changes up to 80270507070ec73ea82741ce24cb7909a9258ea3:
>>
>>   scripts: improve message when TAP based tests fail (2020-07-06 12:14:25 -0400)
>>
>> ----------------------------------------------------------------
>> * Make checkpatch say 'qemu' instead of 'kernel' (Aleksandar)
>> * Fix PSE guests with emulated NPT (Alexander B. #1)
>> * Fix leak (Alexander B. #2)
>> * HVF fixes (Roman, Cameron)
>> * New Sapphire Rapids CPUID bits (Cathy)
>> * cpus.c and softmmu/ cleanups (Claudio)
>> * TAP driver tweaks (Daniel, Havard)
>> * object-add bugfix and testcases (Eric A.)
>> * Fix Coverity MIN_CONST and MAX_CONST (Eric B.)
>> * SSE fixes (Joseph)
>> * "-msg guest-name" option (Mario)
>> * support for AMD nested live migration (myself)
>> * Small i386 TCG fixes (myself)
>> * improved error reporting for Xen (myself)
>> * fix "-cpu host -overcommit cpu-pm=on" (myself)
>> * Add accel/Kconfig (Philippe)
>> * KVM API cleanup (Philippe)
>> * iscsi sense handling fixes (Yongji)
>> * Misc bugfixes
> 
> Hi; various build or test failures (5 total):
> 
> 1) OSX:
> 
> /Users/pm215/src/qemu-for-merges/ui/cocoa.m:1478:9: error: implicit
> declaration of function 'cpu_throttle_set' is invalid in C99 [-
> Werror,-Wimplicit-function-declaration]
>         cpu_throttle_set(throttle_pct);
>         ^
> 
> 2) aarch64 and aarch32 linux:
> 
> /home/pm/qemu/target/arm/kvm.c: In function ‘kvm_arch_init’:
> /home/pm/qemu/target/arm/kvm.c:248:29: error: passing argument 1 of
> ‘kvm_check_extension’ makes integer from pointer without a cast
>  [-Werror=int-conversion]
>   248 |     if (kvm_check_extension(s, KVM_CAP_ARM_NISV_TO_USER)) {
>       |                             ^
>       |                             |
>       |                             KVMState * {aka struct KVMState *}
> In file included from /home/pm/qemu/target/arm/kvm.c:23:
> /home/pm/qemu/include/sysemu/kvm.h:439:38: note: expected ‘unsigned
> int’ but argument is of type ‘KVMState *’ {aka ‘struct KVMState
>  *’}
>   439 | int kvm_check_extension(unsigned int extension);
>       |                         ~~~~~~~~~~~~~^~~~~~~~~
> /home/pm/qemu/target/arm/kvm.c:248:9: error: too many arguments to
> function ‘kvm_check_extension’
>   248 |     if (kvm_check_extension(s, KVM_CAP_ARM_NISV_TO_USER)) {
>       |         ^~~~~~~~~~~~~~~~~~~
> In file included from /home/pm/qemu/target/arm/kvm.c:23:
> /home/pm/qemu/include/sysemu/kvm.h:439:5: note: declared here
>   439 | int kvm_check_extension(unsigned int extension);
>       |     ^~~~~~~~~~~~~~~~~~~
> /home/pm/qemu/target/arm/kvm.c:253:59: error: passing argument 1 of
> ‘kvm_check_extension’ makes integer from pointer without a cast
>  [-Werror=int-conversion]
>   253 |             cap_has_inject_ext_dabt = kvm_check_extension(s,
>       |                                                           ^
>       |                                                           |
>       |
> KVMState * {aka struct KVMState *}
> In file included from /home/pm/qemu/target/arm/kvm.c:23:
> /home/pm/qemu/include/sysemu/kvm.h:439:38: note: expected ‘unsigned
> int’ but argument is of type ‘KVMState *’ {aka ‘struct KVMState
>  *’}
>   439 | int kvm_check_extension(unsigned int extension);
>       |                         ~~~~~~~~~~~~~^~~~~~~~~
> /home/pm/qemu/target/arm/kvm.c:253:39: error: too many arguments to
> function ‘kvm_check_extension’
>   253 |             cap_has_inject_ext_dabt = kvm_check_extension(s,
>       |                                       ^~~~~~~~~~~~~~~~~~~
> In file included from /home/pm/qemu/target/arm/kvm.c:23:
> /home/pm/qemu/include/sysemu/kvm.h:439:5: note: declared here
>   439 | int kvm_check_extension(unsigned int extension);
>       |     ^~~~~~~~~~~~~~~~~~~
> 
> 3) PPC64 had a failure on iotest 030 (though I think this may
> be an intermittent in master):
> 
>   TEST    iotest-qcow2: 030 [fail]
> QEMU          --
> "/home/pm215/qemu/build/all/tests/qemu-iotests/../../ppc64-softmmu/qemu-system-ppc64"
> -nodefaults -display none -accel qtest
> QEMU_IMG      -- "/home/pm215/qemu/build/all/tests/qemu-iotests/../../qemu-img"
> QEMU_IO       --
> "/home/pm215/qemu/build/all/tests/qemu-iotests/../../qemu-io"  --cache
> writeback --aio threads -f qcow2
> QEMU_NBD      -- "/home/pm215/qemu/build/all/tests/qemu-iotests/../../qemu-nbd"
> IMGFMT        -- qcow2 (compat=1.1)
> IMGPROTO      -- file
> PLATFORM      -- Linux/ppc64 gcc1-power7 3.10.0-862.14.4.el7.ppc64
> TEST_DIR      -- /home/pm215/qemu/build/all/tests/qemu-iotests/scratch
> SOCK_DIR      -- /tmp/tmp.icAW30swbG
> SOCKET_SCM_HELPER --
> /home/pm215/qemu/build/all/tests/qemu-iotests/socket_scm_helper
> 
> --- /home/pm215/qemu/tests/qemu-iotests/030.out 2019-07-15
> 15:12:04.941863802 +0000
> +++ /home/pm215/qemu/build/all/tests/qemu-iotests/030.out.bad
> 2020-07-07 18:01:06.975652394 +0000
> @@ -1,5 +1,17 @@
> -...........................
> +.............F.............
> +======================================================================
> +FAIL: test_stream_parallel (__main__.TestParallelOps)
> +----------------------------------------------------------------------
> +Traceback (most recent call last):
> +  File "030", line 246, in test_stream_parallel
> +    self.assert_qmp(result, 'return', {})
> +  File "/home/pm215/qemu/tests/qemu-iotests/iotests.py", line 848, in
> assert_qmp
> +    result = self.dictpath(d, path)
> +  File "/home/pm215/qemu/tests/qemu-iotests/iotests.py", line 822, in dictpath
> +    self.fail(f'failed path traversal for "{path}" in "{d}"')
> +AssertionError: failed path traversal for "return" in "{'error':
> {'class': 'DeviceNotActive', 'desc': "Block job 'stream-node8' not
> found"}}"
> +
>  ----------------------------------------------------------------------
>  Ran 27 tests
> 
> -OK
> +FAILED (failures=1)
> 
> 4) s390x failed on iotest 267:
> 
>   TEST    iotest-qcow2: 267 [fail]
> QEMU          --
> "/home/ubuntu/qemu/build/all/tests/qemu-iotests/../../s390x-softmmu/qemu-system-s390x"
> -nodefaults -display none -accel qtest
> QEMU_IMG      -- "/home/ubuntu/qemu/build/all/tests/qemu-iotests/../../qemu-img"
> QEMU_IO       --
> "/home/ubuntu/qemu/build/all/tests/qemu-iotests/../../qemu-io"
> --cache writeback --aio threads -f qcow2
> QEMU_NBD      -- "/home/ubuntu/qemu/build/all/tests/qemu-iotests/../../qemu-nbd"
> IMGFMT        -- qcow2 (compat=1.1)
> IMGPROTO      -- file
> PLATFORM      -- Linux/s390x qemu01 4.15.0-72-generic
> TEST_DIR      -- /home/ubuntu/qemu/build/all/tests/qemu-iotests/scratch
> SOCK_DIR      -- /tmp/tmp.REW8Sy64t9
> SOCKET_SCM_HELPER --
> /home/ubuntu/qemu/build/all/tests/qemu-iotests/socket_scm_helper
> 
> --- /home/ubuntu/qemu/tests/qemu-iotests/267.out        2019-12-19
> 08:32:33.382319918 -0500
> +++ /home/ubuntu/qemu/build/all/tests/qemu-iotests/267.out.bad
> 2020-07-07 14:15:44.173300793 -0400
> @@ -137,6 +137,9 @@
>  ID        TAG                 VM SIZE                DATE       VM CLOCK
>  --        snap0                  SIZE yyyy-mm-dd hh:mm:ss   00:00:00.000
>  (qemu) loadvm snap0
> +Unexpected storage key flag data: 0
> +error while loading state for instance 0x0 of device 's390-skeys'
> +Error: Error -22 while loading VM state
>  (qemu) quit
> 
>  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
> backing_file=TEST_DIR/t.IMGFMT.base
> 
> 5) And a link error on x86-64 Linux:
> 
>   LINK    x86_64-softmmu/qemu-system-x86_64
> softmmu/cpus.o: In function `tcg_get_icount_limit':
> /home/petmay01/linaro/qemu-for-merges/softmmu/cpus.c:563: undefined
> reference to `icount_round'
> softmmu/cpus.o: In function `process_icount_data':
> /home/petmay01/linaro/qemu-for-merges/softmmu/cpus.c:618: undefined
> reference to `icount_update'
> target/i386/helper.o: In function `x86_cpu_dump_state':
> /home/petmay01/linaro/qemu-for-merges/target/i386/helper.c:547:
> undefined reference to `update_mxcsr_from_sse_status'
> target/i386/gdbstub.o: In function `x86_cpu_gdb_read_register':
> /home/petmay01/linaro/qemu-for-merges/target/i386/gdbstub.c:187:
> undefined reference to `update_mxcsr_from_sse_status'
> collect2: error: ld returned 1 exit status
> Makefile:205: recipe for target 'qemu-system-x86_64' failed
> 
> thanks
> -- PMM
> 

Hi Peter, Paolo,

I am trying to understand this failure (5), which is triggered by one of my patches,
containing clearly an issue that does not trigger here, although it is apparent to me (I did not provide all necessary stubs).

Could you provide the ./configure command line, config.status, compiler version?

Clearly it is something I have to fix, but would help to be able not to be "blind".

The patch introducing icount_round and icount_update is

"cpu-timers, icount: new modules",

and the issue stems I think from the fact that cpus.c references

icount_round() and icount_update() in code that is conditional on icount_enabled().

If the code is configured with --disable-tcg, in stubs/icount.c , icount_enabled is defined as always returning 0,
and my compiler takes that clue and elides all static functions conditional on that return value,

so I don't get any tcg_get_icount_limit() compiled in, and no errors.

I think that having comparable configure command line and compiler version/flags would help me pin down any related issue.

Thanks,

Claudio








^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-08 16:13   ` Claudio Fontana
@ 2020-07-08 16:16     ` Paolo Bonzini
  2020-07-08 16:45       ` Claudio Fontana
  0 siblings, 1 reply; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-08 16:16 UTC (permalink / raw)
  To: Claudio Fontana, Peter Maydell; +Cc: QEMU Developers

On 08/07/20 18:13, Claudio Fontana wrote:
> so I don't get any tcg_get_icount_limit() compiled in, and no
> errors.
> 
> I think that having comparable configure command line and compiler
> version/flags would help me pin down any related issue.

Are you using link-time optimization by chance?

Paolo



^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-08 16:16     ` Paolo Bonzini
@ 2020-07-08 16:45       ` Claudio Fontana
  2020-07-08 16:55         ` Paolo Bonzini
  0 siblings, 1 reply; 76+ messages in thread
From: Claudio Fontana @ 2020-07-08 16:45 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Maydell; +Cc: QEMU Developers

On 7/8/20 6:16 PM, Paolo Bonzini wrote:
> On 08/07/20 18:13, Claudio Fontana wrote:
>> so I don't get any tcg_get_icount_limit() compiled in, and no
>> errors.
>>
>> I think that having comparable configure command line and compiler
>> version/flags would help me pin down any related issue.
> 
> Are you using link-time optimization by chance?
> 
> Paolo
> 

Yes unfortunately, nothing I have willingly enabled, but I found traces of LTO in C++.

C++ is used to link the final qemu-system binary and on my system c++ has LTO:

c++ -v
Using built-in specs.
COLLECT_GCC=c++
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/7/lto-wrapper
OFFLOAD_TARGET_NAMES=hsa:nvptx-none
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,ada,go --enable-offload-targets=hsa,nvptx-none=/usr/nvptx-none, --without-cuda-driver --enable-checking=release --disable-werror --with-gxx-include-dir=/usr/include/c++/7 --enable-ssp --disable-libssp --disable-libvtv --disable-libcc1 --disable-plugin --with-bugurl=https://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --with-slibdir=/lib64 --with-system-zlib --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --with-gcc-major-version-only --enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function --program-suffix=-7 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux
Thread model: posix
gcc version 7.5.0 (SUSE Linux) 


I checked cc but did not think to check c++ . I will find a way to disable this thing and will correct the patch accordingly.

Thanks a lot, and sorry for the inconvenience!

Claudio




^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-08 16:45       ` Claudio Fontana
@ 2020-07-08 16:55         ` Paolo Bonzini
  2020-07-08 17:03           ` Claudio Fontana
  0 siblings, 1 reply; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-08 16:55 UTC (permalink / raw)
  To: Claudio Fontana, Peter Maydell; +Cc: QEMU Developers

On 08/07/20 18:45, Claudio Fontana wrote:
> C++ is used to link the final qemu-system binary and on my system c++ has LTO:
> 
> c++ -v
> Using built-in specs.
> COLLECT_GCC=c++
> COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/7/lto-wrapper
> OFFLOAD_TARGET_NAMES=hsa:nvptx-none
> Target: x86_64-suse-linux
> Configured with: ../configure --prefix=/usr --infodir=/usr/share/info
> --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64
> --enable-languages=c,c++,objc,fortran,obj-c++,ada,go
> --enable-offload-targets=hsa,nvptx-none=/usr/nvptx-none,
> --without-cuda-driver --enable-checking=release --disable-werror
> --with-gxx-include-dir=/usr/include/c++/7 --enable-ssp --disable-libssp
> --disable-libvtv --disable-libcc1 --disable-plugin
> --with-bugurl=https://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --with-slibdir=/lib64 --with-system-zlib --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --with-gcc-major-version-only --enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function --program-suffix=-7 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux
> Thread model: posix
> gcc version 7.5.0 (SUSE Linux) 
> 
> 
> I checked cc but did not think to check c++ . I will find a way to disable this thing and will correct the patch accordingly.

Having LTO support is not the same thing as having it enabled.  Are you
compiling and linking with "-flto"?

Paolo



^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-08 16:55         ` Paolo Bonzini
@ 2020-07-08 17:03           ` Claudio Fontana
  2020-07-08 18:25             ` Claudio Fontana
  0 siblings, 1 reply; 76+ messages in thread
From: Claudio Fontana @ 2020-07-08 17:03 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Maydell; +Cc: QEMU Developers

On 7/8/20 6:55 PM, Paolo Bonzini wrote:
> On 08/07/20 18:45, Claudio Fontana wrote:
>> C++ is used to link the final qemu-system binary and on my system c++ has LTO:
>>
>> c++ -v
>> Using built-in specs.
>> COLLECT_GCC=c++
>> COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/7/lto-wrapper
>> OFFLOAD_TARGET_NAMES=hsa:nvptx-none
>> Target: x86_64-suse-linux
>> Configured with: ../configure --prefix=/usr --infodir=/usr/share/info
>> --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64
>> --enable-languages=c,c++,objc,fortran,obj-c++,ada,go
>> --enable-offload-targets=hsa,nvptx-none=/usr/nvptx-none,
>> --without-cuda-driver --enable-checking=release --disable-werror
>> --with-gxx-include-dir=/usr/include/c++/7 --enable-ssp --disable-libssp
>> --disable-libvtv --disable-libcc1 --disable-plugin
>> --with-bugurl=https://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --with-slibdir=/lib64 --with-system-zlib --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --with-gcc-major-version-only --enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function --program-suffix=-7 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux
>> Thread model: posix
>> gcc version 7.5.0 (SUSE Linux) 
>>
>>
>> I checked cc but did not think to check c++ . I will find a way to disable this thing and will correct the patch accordingly.
> 
> Having LTO support is not the same thing as having it enabled.  Are you
> compiling and linking with "-flto"?
> 
> Paolo
> 

no, the compilation and link stage do not show this explicit parameter. I am puzzled.

C





^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-08 17:03           ` Claudio Fontana
@ 2020-07-08 18:25             ` Claudio Fontana
  2020-07-08 18:34               ` Claudio Fontana
  2020-07-08 18:41               ` Paolo Bonzini
  0 siblings, 2 replies; 76+ messages in thread
From: Claudio Fontana @ 2020-07-08 18:25 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Maydell; +Cc: QEMU Developers

On 7/8/20 7:03 PM, Claudio Fontana wrote:
> On 7/8/20 6:55 PM, Paolo Bonzini wrote:
>> On 08/07/20 18:45, Claudio Fontana wrote:
>>> C++ is used to link the final qemu-system binary and on my system c++ has LTO:
>>>
>>> c++ -v
>>> Using built-in specs.
>>> COLLECT_GCC=c++
>>> COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/7/lto-wrapper
>>> OFFLOAD_TARGET_NAMES=hsa:nvptx-none
>>> Target: x86_64-suse-linux
>>> Configured with: ../configure --prefix=/usr --infodir=/usr/share/info
>>> --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64
>>> --enable-languages=c,c++,objc,fortran,obj-c++,ada,go
>>> --enable-offload-targets=hsa,nvptx-none=/usr/nvptx-none,
>>> --without-cuda-driver --enable-checking=release --disable-werror
>>> --with-gxx-include-dir=/usr/include/c++/7 --enable-ssp --disable-libssp
>>> --disable-libvtv --disable-libcc1 --disable-plugin
>>> --with-bugurl=https://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --with-slibdir=/lib64 --with-system-zlib --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --with-gcc-major-version-only --enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function --program-suffix=-7 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux
>>> Thread model: posix
>>> gcc version 7.5.0 (SUSE Linux) 
>>>
>>>
>>> I checked cc but did not think to check c++ . I will find a way to disable this thing and will correct the patch accordingly.
>>
>> Having LTO support is not the same thing as having it enabled.  Are you
>> compiling and linking with "-flto"?
>>
>> Paolo
>>
> 
> no, the compilation and link stage do not show this explicit parameter. I am puzzled.
> 
> C
> 

This is really weird, as I cannot reproduce it.

What I did notice is that all the code that directly or indirectly uses the functions is under an

if (0) (
)

since tcg_enabled is the constant 0.

By "indirectly" I mean that the static void qemu_tcg_cpu_thread_fn() function that calls those is referenced only by static void qemu_tcg_init_vcpu(), which is called only under an if (0),
ie if (tcg_enabled()).

For me this builds with --disable-tcg and with --enable-tcg .

Maybe the issue is actually the name clash of the stub and the module?

I admit I am not familiar with the rationale of why the stubs are all built regardless, could we have that icount.o from stubs/ is replacing softmmu/icount.o to cause this?

Thanks,

Claudio





^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-08 18:25             ` Claudio Fontana
@ 2020-07-08 18:34               ` Claudio Fontana
  2020-07-08 18:41               ` Paolo Bonzini
  1 sibling, 0 replies; 76+ messages in thread
From: Claudio Fontana @ 2020-07-08 18:34 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Maydell; +Cc: QEMU Developers

On 7/8/20 8:25 PM, Claudio Fontana wrote:
> On 7/8/20 7:03 PM, Claudio Fontana wrote:
>> On 7/8/20 6:55 PM, Paolo Bonzini wrote:
>>> On 08/07/20 18:45, Claudio Fontana wrote:
>>>> C++ is used to link the final qemu-system binary and on my system c++ has LTO:
>>>>
>>>> c++ -v
>>>> Using built-in specs.
>>>> COLLECT_GCC=c++
>>>> COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/7/lto-wrapper
>>>> OFFLOAD_TARGET_NAMES=hsa:nvptx-none
>>>> Target: x86_64-suse-linux
>>>> Configured with: ../configure --prefix=/usr --infodir=/usr/share/info
>>>> --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64
>>>> --enable-languages=c,c++,objc,fortran,obj-c++,ada,go
>>>> --enable-offload-targets=hsa,nvptx-none=/usr/nvptx-none,
>>>> --without-cuda-driver --enable-checking=release --disable-werror
>>>> --with-gxx-include-dir=/usr/include/c++/7 --enable-ssp --disable-libssp
>>>> --disable-libvtv --disable-libcc1 --disable-plugin
>>>> --with-bugurl=https://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --with-slibdir=/lib64 --with-system-zlib --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --with-gcc-major-version-only --enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function --program-suffix=-7 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux
>>>> Thread model: posix
>>>> gcc version 7.5.0 (SUSE Linux) 
>>>>
>>>>
>>>> I checked cc but did not think to check c++ . I will find a way to disable this thing and will correct the patch accordingly.
>>>
>>> Having LTO support is not the same thing as having it enabled.  Are you
>>> compiling and linking with "-flto"?
>>>
>>> Paolo
>>>
>>
>> no, the compilation and link stage do not show this explicit parameter. I am puzzled.
>>
>> C
>>
> 
> This is really weird, as I cannot reproduce it.
> 
> What I did notice is that all the code that directly or indirectly uses the functions is under an
> 
> if (0) (
> )
> 
> since tcg_enabled is the constant 0.
> 
> By "indirectly" I mean that the static void qemu_tcg_cpu_thread_fn() function that calls those is referenced only by static void qemu_tcg_init_vcpu(), which is called only under an if (0),
> ie if (tcg_enabled()).
> 
> For me this builds with --disable-tcg and with --enable-tcg .
> 
> Maybe the issue is actually the name clash of the stub and the module?
> 
> I admit I am not familiar with the rationale of why the stubs are all built regardless, could we have that icount.o from stubs/ is replacing softmmu/icount.o to cause this?
> 
> Thanks,
> 
> Claudio
> 
> 

So I guess if you could Peter, are you building there with --disable-tcg or with --enable-tcg  when you got that error?

Ciao,

Claudio



^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-08 18:25             ` Claudio Fontana
  2020-07-08 18:34               ` Claudio Fontana
@ 2020-07-08 18:41               ` Paolo Bonzini
  2020-07-09  6:59                 ` Claudio Fontana
  1 sibling, 1 reply; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-08 18:41 UTC (permalink / raw)
  To: Claudio Fontana; +Cc: Peter Maydell, QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 817 bytes --]

Il mer 8 lug 2020, 20:25 Claudio Fontana <cfontana@suse.de> ha scritto:

> What I did notice is that all the code that directly or indirectly uses
> the functions is under an
>
> if (0) (
> )
>
> since tcg_enabled is the constant 0.
>
> By "indirectly" I mean that the static void qemu_tcg_cpu_thread_fn()
> function that calls those is referenced only by static void
> qemu_tcg_init_vcpu(), which is called only under an if (0),
> ie if (tcg_enabled()).
>

Maybe my compiler is older.

I admit I am not familiar with the rationale of why the stubs are all built
> regardless, could we have that icount.o from stubs/ is replacing
> softmmu/icount.o to cause this?
>

No, stubs are in a static library and therefore are always overridden by
symbols in the executable's .o files.

Paolo


> Thanks,
>
> Claudio
>
>
>
>

[-- Attachment #2: Type: text/html, Size: 1674 bytes --]

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-08 18:41               ` Paolo Bonzini
@ 2020-07-09  6:59                 ` Claudio Fontana
  2020-07-09  9:57                   ` Paolo Bonzini
  0 siblings, 1 reply; 76+ messages in thread
From: Claudio Fontana @ 2020-07-09  6:59 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Peter Maydell, QEMU Developers

On 7/8/20 8:41 PM, Paolo Bonzini wrote:
> 
> 
> Il mer 8 lug 2020, 20:25 Claudio Fontana <cfontana@suse.de <mailto:cfontana@suse.de>> ha scritto:
> 
>     What I did notice is that all the code that directly or indirectly uses the functions is under an
> 
>     if (0) (
>     )
> 
>     since tcg_enabled is the constant 0.
> 
>     By "indirectly" I mean that the static void qemu_tcg_cpu_thread_fn() function that calls those is referenced only by static void qemu_tcg_init_vcpu(), which is called only under an if (0),
>     ie if (tcg_enabled()).
> 
> 
> Maybe my compiler is older.
> 
>     I admit I am not familiar with the rationale of why the stubs are all built regardless, could we have that icount.o from stubs/ is replacing softmmu/icount.o to cause this?
> 
> 
> No, stubs are in a static library and therefore are always overridden by symbols in the executable's .o files.
> 
> Paolo
> 
> 

Hi Paolo,

which compiler, linker, binutils etc are you using?

I am using

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/7/lto-wrapper
OFFLOAD_TARGET_NAMES=hsa:nvptx-none
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,ada,go --enable-offload-targets=hsa,nvptx-none=/usr/nvptx-none, --without-cuda-driver --enable-checking=release --disable-werror --with-gxx-include-dir=/usr/include/c++/7 --enable-ssp --disable-libssp --disable-libvtv --disable-libcc1 --disable-plugin --with-bugurl=https://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --with-slibdir=/lib64 --with-system-zlib --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --with-gcc-major-version-only --enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function --program-suffix=-7 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux
Thread model: posix
gcc version 7.5.0 (SUSE Linux) 


$ ld -v
GNU ld (GNU Binutils; openSUSE Leap 15.1) 2.32.0.20190909-lp151.3.3

anything else that we could use to find the real problem?

Of course I can try a blind fix, where I suggest to explicitly provide the stubs,
or you can apply the workaround you already suggested if you want,
but currently I do not have any way to ensure that what I build is ok,
since apparently the local build or any of the CI (travis, cirrus) is not sufficient to capture this.

So getting to the bottom of the issue would be important going forward I think so I can ensure better input from my side.

In general, the way current code is relying on the compiler to (maybe) compile out code that calls undefined symbols,
using #define tcg_enabled 0 , and then having the undefined function calls in the code, seems less preferable than solving the problem explicitly
with proper refactoring or with explicit stubs until proper refactoring is complete..

Thanks,

Claudio

 


^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze
  2020-07-09  6:59                 ` Claudio Fontana
@ 2020-07-09  9:57                   ` Paolo Bonzini
  0 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-09  9:57 UTC (permalink / raw)
  To: Claudio Fontana; +Cc: Peter Maydell, QEMU Developers

On 09/07/20 08:59, Claudio Fontana wrote:
> anything else that we could use to find the real problem?

I'm using

$ gcc -v
...
gcc version 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC)
$ ld -v
GNU ld version 2.30-68.el8

> Of course I can try a blind fix, where I suggest to explicitly provide the stubs,
> or you can apply the workaround you already suggested if you want,
> but currently I do not have any way to ensure that what I build is ok,
> since apparently the local build or any of the CI (travis, cirrus) is not sufficient to capture this.

No problem, I can test it myself on my machine when applying the patch.

Paolo



^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 28/53] Makefile: simplify MINIKCONF rules
  2020-07-06 16:41 ` [PULL 28/53] Makefile: simplify MINIKCONF rules Paolo Bonzini
@ 2020-07-17 11:02   ` Peter Maydell
  2020-07-17 11:20     ` Paolo Bonzini
  0 siblings, 1 reply; 76+ messages in thread
From: Peter Maydell @ 2020-07-17 11:02 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Philippe Mathieu-Daudé, QEMU Developers, Corey Minyard

On Mon, 6 Jul 2020 at 18:03, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> There is no reason to write MINIKCONF_DEPS manually, since minikconf.py
> emits a dependency file, and also no reason to list multiple Kconfig
> files on the command line since they can be included from a master file
> in the top-level source directory.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Hi Paolo. With this change Make seems no longer to realise
that a change to a Kconfig file means it needs to rebuild
the config-devices.mak, which means that we tend to get
weird compile failures for changes which update Kconfig files.

Specifically, this is preventing me getting a clean set of
builds for Corey's latest i2c pullreq. Reverting this
commit allows the pullreq to build on all configs.

> --- a/Makefile
> +++ b/Makefile
> @@ -404,7 +404,7 @@ endif
>  # This has to be kept in sync with Kconfig.host.
>  MINIKCONF_ARGS = \
>      $(CONFIG_MINIKCONF_MODE) \
> -    $@ $*/config-devices.mak.d $< $(MINIKCONF_INPUTS) \
> +    $@ $*/config-devices.mak.d $< $(SRC_PATH)/Kconfig \
>      CONFIG_TCG=$(CONFIG_TCG) \
>      CONFIG_KVM=$(CONFIG_KVM) \
>      CONFIG_SPICE=$(CONFIG_SPICE) \
> @@ -419,15 +419,9 @@ MINIKCONF_ARGS = \
>      CONFIG_LINUX=$(CONFIG_LINUX) \
>      CONFIG_PVRDMA=$(CONFIG_PVRDMA)
>
> -MINIKCONF_INPUTS = $(SRC_PATH)/Kconfig.host \
> -                   $(SRC_PATH)/backends/Kconfig \
> -                   $(SRC_PATH)/accel/Kconfig \
> -                   $(SRC_PATH)/hw/Kconfig
> -MINIKCONF_DEPS = $(MINIKCONF_INPUTS) \
> -                 $(wildcard $(SRC_PATH)/hw/*/Kconfig)
>  MINIKCONF = $(PYTHON) $(SRC_PATH)/scripts/minikconf.py
>
> -$(SUBDIR_DEVICES_MAK): %/config-devices.mak: default-configs/%.mak $(MINIKCONF_DEPS) $(BUILD_DIR)/config-host.mak
> +$(SUBDIR_DEVICES_MAK): %/config-devices.mak: default-configs/%.mak $(SRC_PATH)/Kconfig $(BUILD_DIR)/config-host.mak

Specifically here, the $(MINIKCONF_DEPS) long list of Kconfig
files has been removed from the dependency list of
config-devices.mak.

There doesn't seem to be any machinery for creating .d
files for make to include to tell it that Kconfig has a
dependency on hw/Kconfig which has a dependency on hw/i2c/Kconfig etc.
How is this intended to work ?

For 5.1, should we just revert this commit ?

thanks
-- PMM


^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 28/53] Makefile: simplify MINIKCONF rules
  2020-07-17 11:02   ` Peter Maydell
@ 2020-07-17 11:20     ` Paolo Bonzini
  2020-07-17 13:01       ` Peter Maydell
  0 siblings, 1 reply; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-17 11:20 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Philippe Mathieu-Daudé, QEMU Developers, Corey Minyard

[-- Attachment #1: Type: text/plain, Size: 1470 bytes --]

Il ven 17 lug 2020, 13:03 Peter Maydell <peter.maydell@linaro.org> ha
scritto:

> On Mon, 6 Jul 2020 at 18:03, Paolo Bonzini <pbonzini@redhat.com> wrote:
> >
> > There is no reason to write MINIKCONF_DEPS manually, since minikconf.py
> > emits a dependency file, and also no reason to list multiple Kconfig
> > files on the command line since they can be included from a master file
> > in the top-level source directory.
> >
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>
> Hi Paolo. With this change Make seems no longer to realise
> that a change to a Kconfig file means it needs to rebuild
> the config-devices.mak, which means that we tend to get
> weird compile failures for changes which update Kconfig files.
>
> Specifically here, the $(MINIKCONF_DEPS) long list of Kconfig
> files has been removed from the dependency list of
> config-devices.mak.
>
> There doesn't seem to be any machinery for creating .d
> files for make to include to tell it that Kconfig has a
> dependency on hw/Kconfig which has a dependency on hw/i2c/Kconfig etc.
> How is this intended to work ?
>

I cannot look at a build tree right now, but shouldn't that be in the .d
file produced by minikconf.py Those are passed to minikconf.py as the
second argument and included with "include $(SUBDIR_DEVICES_MAK_DEP)".

No objection against reverting though.

Paolo


> For 5.1, should we just revert this commit ?
>
> thanks
> -- PMM
>
>

[-- Attachment #2: Type: text/html, Size: 2404 bytes --]

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 28/53] Makefile: simplify MINIKCONF rules
  2020-07-17 11:20     ` Paolo Bonzini
@ 2020-07-17 13:01       ` Peter Maydell
  2020-07-17 13:33         ` Paolo Bonzini
  0 siblings, 1 reply; 76+ messages in thread
From: Peter Maydell @ 2020-07-17 13:01 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Philippe Mathieu-Daudé, QEMU Developers, Corey Minyard

On Fri, 17 Jul 2020 at 12:20, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Il ven 17 lug 2020, 13:03 Peter Maydell <peter.maydell@linaro.org> ha scritto:
>> There doesn't seem to be any machinery for creating .d
>> files for make to include to tell it that Kconfig has a
>> dependency on hw/Kconfig which has a dependency on hw/i2c/Kconfig etc.
>> How is this intended to work ?
>
>
> I cannot look at a build tree right now, but shouldn't that be in the .d file produced by minikconf.py Those are passed to minikconf.py as the second argument and included with "include $(SUBDIR_DEVICES_MAK_DEP)".

When you do a "make clean" those .d files get deleted
(but the config-devices.mak files do not). There is no rule
for rebuilding a config-devices.mak.d:

$ make -C build/x86 -n arm-softmmu/config-devices.mak.d
make: Entering directory '/home/petmay01/linaro/qemu-from-laptop/qemu/build/x86'
make[1]: Entering directory '/home/petmay01/linaro/qemu-from-laptop/qemu/slirp'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/petmay01/linaro/qemu-from-laptop/qemu/slirp'
make: *** No rule to make target 'arm-softmmu/config-devices.mak.d'. Stop.
make: Leaving directory '/home/petmay01/linaro/qemu-from-laptop/qemu/build/x86'

and we include them with "-include", so Make silently
proceeds without the dependency information.

My guess is that we need to tell make that this rule:
$(SUBDIR_DEVICES_MAK): %/config-devices.mak: default-configs/%.mak
$(SRC_PATH)/Kconfig $(BUILD_DIR)/config-host.mak

also produces the .mak.d file somehow.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 28/53] Makefile: simplify MINIKCONF rules
  2020-07-17 13:01       ` Peter Maydell
@ 2020-07-17 13:33         ` Paolo Bonzini
  0 siblings, 0 replies; 76+ messages in thread
From: Paolo Bonzini @ 2020-07-17 13:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Philippe Mathieu-Daudé, QEMU Developers, Corey Minyard

[-- Attachment #1: Type: text/plain, Size: 317 bytes --]

Il ven 17 lug 2020, 15:01 Peter Maydell <peter.maydell@linaro.org> ha
scritto:

> When you do a "make clean" those .d files get deleted
> (but the config-devices.mak files do not).


I think that's the bug, both should be removed by "make clean" (since the
.mak files are built by "make" and not "configure").

Paolo

[-- Attachment #2: Type: text/html, Size: 735 bytes --]

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PULL 31/53] KVM: x86: believe what KVM says about WAITPKG
  2020-07-06 16:41 ` [PULL 31/53] KVM: x86: believe what KVM says about WAITPKG Paolo Bonzini
  2020-07-07 11:42   ` Maxim Levitsky
@ 2021-12-22  9:35   ` Chenyi Qiang
  1 sibling, 0 replies; 76+ messages in thread
From: Chenyi Qiang @ 2021-12-22  9:35 UTC (permalink / raw)
  To: Paolo Bonzini, Maxim Levitsky; +Cc: qemu-devel



On 7/7/2020 12:41 AM, Paolo Bonzini wrote:
> Currently, QEMU is overriding KVM_GET_SUPPORTED_CPUID's answer for
> the WAITPKG bit depending on the "-overcommit cpu-pm" setting.  This is a
> bad idea because it does not even check if the host supports it, but it
> can be done in x86_cpu_realizefn just like we do for the MONITOR bit.
> 
> This patch moves it there, while making it conditional on host
> support for the related UMWAIT MSR.
> 
> Cc: qemu-stable@nongnu.org
> Reported-by: Maxim Levitsky <mlevitsk@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   target/i386/cpu.c      |  3 +++
>   target/i386/kvm.c      | 11 +++++------
>   target/i386/kvm_i386.h |  1 +
>   3 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index c44cc510e1..dc9ba06f1f 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -6536,6 +6536,9 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
>               host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx,
>                          &cpu->mwait.ecx, &cpu->mwait.edx);
>               env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR;
> +            if (kvm_enabled() && kvm_has_waitpkg()) {
> +                env->features[FEAT_7_0_ECX] |= CPUID_7_0_ECX_WAITPKG;
> +            }

Hi Paolo and Maxim,

Sorry to find out this long-time-ago mail although the code has been 
refactor nowadays. Recently, when testing WAITPKG exposure, I found 
WAITPKG is no longer controlled by "-overcommit cpu-pm", i.e. if 
!enable_cpu_pm && KVM cap reports WAITPKG (KVM set the cap in 
vmx_set_cpu_caps), this feature can still be seen in guest. It is 
obviously due to QEMU doesn't clear CPUID_7_0_ECX_WAITPKG explicitly if 
!enable_cpu_pm.

So, is this the expected behavior for this patch?

Thanks
Chenyi

>           }
>           if (kvm_enabled() && cpu->ucode_rev == 0) {
>               cpu->ucode_rev = kvm_arch_get_supported_msr_feature(kvm_state,
> diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> index 2b6b7443d2..b8455c89ed 100644
> --- a/target/i386/kvm.c
> +++ b/target/i386/kvm.c
> @@ -411,12 +411,6 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
>           if (host_tsx_blacklisted()) {
>               ret &= ~(CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_HLE);
>           }
> -    } else if (function == 7 && index == 0 && reg == R_ECX) {
> -        if (enable_cpu_pm) {
> -            ret |= CPUID_7_0_ECX_WAITPKG;
> -        } else {
> -            ret &= ~CPUID_7_0_ECX_WAITPKG;
> -        }
>       } else if (function == 7 && index == 0 && reg == R_EDX) {
>           /*
>            * Linux v4.17-v4.20 incorrectly return ARCH_CAPABILITIES on SVM hosts.
> @@ -4730,3 +4724,8 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
>   {
>       abort();
>   }
> +
> +bool kvm_has_waitpkg(void)
> +{
> +    return has_msr_umwait;
> +}
> diff --git a/target/i386/kvm_i386.h b/target/i386/kvm_i386.h
> index 00bde7acaf..064b8798a2 100644
> --- a/target/i386/kvm_i386.h
> +++ b/target/i386/kvm_i386.h
> @@ -44,6 +44,7 @@ void kvm_put_apicbase(X86CPU *cpu, uint64_t value);
> 
>   bool kvm_enable_x2apic(void);
>   bool kvm_has_x2apic_api(void);
> +bool kvm_has_waitpkg(void);
> 
>   bool kvm_hv_vpindex_settable(void);
> 
> --
> 2.26.2
> 
> 
> 


^ permalink raw reply	[flat|nested] 76+ messages in thread

end of thread, other threads:[~2021-12-22  9:36 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-06 16:41 [PULL 00/53] Misc patches for QEMU 5.1 soft freeze Paolo Bonzini
2020-07-06 16:41 ` [PULL 01/53] tcg/svm: use host cr4 during NPT page table walk Paolo Bonzini
2020-07-06 16:41 ` [PULL 02/53] tests: Inject test name also when the test fails Paolo Bonzini
2020-07-06 16:41 ` [PULL 03/53] util/qemu-error: prepend guest name to error message to identify affected VM owner Paolo Bonzini
2020-07-06 16:41 ` [PULL 04/53] qom: Introduce object_property_try_add_child() Paolo Bonzini
2020-07-06 16:41 ` [PULL 05/53] tests/qmp-cmd-test: Add qmp/object-add-duplicate-id Paolo Bonzini
2020-07-06 16:41 ` [PULL 06/53] tests/qmp-cmd-test: Add qmp/object-add-failure-modes Paolo Bonzini
2020-07-06 16:41 ` [PULL 07/53] hw/core/null-machine: Do not initialize unused chardev backends Paolo Bonzini
2020-07-06 16:41 ` [PULL 08/53] target/i386: set SSE FTZ in correct floating-point state Paolo Bonzini
2020-07-06 16:41 ` [PULL 09/53] target/i386: fix IEEE SSE floating-point exception raising Paolo Bonzini
2020-07-06 16:41 ` [PULL 10/53] KVM: add support for AMD nested live migration Paolo Bonzini
2020-07-06 16:41 ` [PULL 11/53] coverity: provide Coverity-friendly MIN_CONST and MAX_CONST Paolo Bonzini
2020-07-06 16:41 ` [PULL 12/53] i386: hvf: Set env->eip in macvm_set_rip() Paolo Bonzini
2020-07-06 16:41 ` [PULL 13/53] i386: hvf: Move synchronize functions to sysemu Paolo Bonzini
2020-07-06 16:41 ` [PULL 14/53] i386: hvf: Add hvf_cpu_synchronize_pre_loadvm() Paolo Bonzini
2020-07-06 16:41 ` [PULL 15/53] i386: hvf: Make long mode enter and exit clearer Paolo Bonzini
2020-07-06 16:41 ` [PULL 16/53] i386: hvf: Move Guest LMA reset to macvm_set_cr0() Paolo Bonzini
2020-07-06 16:41 ` [PULL 17/53] i386: hvf: Don't duplicate register reset Paolo Bonzini
2020-07-06 16:41 ` [PULL 18/53] i386: hvf: Clean up synchronize functions Paolo Bonzini
2020-07-06 16:41 ` [PULL 19/53] MAINTAINERS: Add Cameron as HVF co-maintainer Paolo Bonzini
2020-07-06 16:41 ` [PULL 20/53] MAINTAINERS: Fix KVM path expansion glob Paolo Bonzini
2020-07-06 16:41 ` [PULL 21/53] MAINTAINERS: Add an 'overall' entry for accelerators Paolo Bonzini
2020-07-06 16:41 ` [PULL 22/53] MAINTAINERS: Cover the HAX accelerator stub Paolo Bonzini
2020-07-06 16:41 ` [PULL 23/53] Makefile: Remove dangerous EOL trailing backslash Paolo Bonzini
2020-07-06 16:41 ` [PULL 24/53] Makefile: Write MINIKCONF variables as one entry per line Paolo Bonzini
2020-07-06 16:41 ` [PULL 25/53] accel/Kconfig: Extract accel selectors into their own config Paolo Bonzini
2020-07-06 16:41 ` [PULL 26/53] accel/Kconfig: Add the TCG selector Paolo Bonzini
2020-07-06 16:41 ` [PULL 27/53] accel/tcg: Add stub for probe_access() Paolo Bonzini
2020-07-06 16:41 ` [PULL 28/53] Makefile: simplify MINIKCONF rules Paolo Bonzini
2020-07-17 11:02   ` Peter Maydell
2020-07-17 11:20     ` Paolo Bonzini
2020-07-17 13:01       ` Peter Maydell
2020-07-17 13:33         ` Paolo Bonzini
2020-07-06 16:41 ` [PULL 29/53] target/i386: remove gen_io_end Paolo Bonzini
2020-07-06 16:41 ` [PULL 30/53] target/i386: implement undocumented "smsw r32" behavior Paolo Bonzini
2020-07-06 16:41 ` [PULL 31/53] KVM: x86: believe what KVM says about WAITPKG Paolo Bonzini
2020-07-07 11:42   ` Maxim Levitsky
2020-07-07 11:58     ` Paolo Bonzini
2021-12-22  9:35   ` Chenyi Qiang
2020-07-06 16:41 ` [PULL 32/53] target/i386: sev: provide proper error reporting for query-sev-capabilities Paolo Bonzini
2020-07-06 16:41 ` [PULL 33/53] target/i386: sev: fail query-sev-capabilities if QEMU cannot use SEV Paolo Bonzini
2020-07-06 16:41 ` [PULL 34/53] iscsi: handle check condition status in retry loop Paolo Bonzini
2020-07-06 16:41 ` [PULL 35/53] iscsi: return -EIO when sense fields are meaningless Paolo Bonzini
2020-07-06 16:41 ` [PULL 36/53] chardev/tcp: fix error message double free error Paolo Bonzini
2020-07-06 16:41 ` [PULL 37/53] checkpatch: Change occurences of 'kernel' to 'qemu' in user messages Paolo Bonzini
2020-07-06 16:41 ` [PULL 38/53] target/i386: Correct the warning message of Intel PT Paolo Bonzini
2020-07-06 16:41 ` [PULL 39/53] cpus: Move CPU code from exec.c to cpus-common.c Paolo Bonzini
2020-07-06 16:41 ` [PULL 40/53] pc: fix leak in pc_system_flash_cleanup_unused Paolo Bonzini
2020-07-06 16:41 ` [PULL 41/53] softmmu: move softmmu only files from root Paolo Bonzini
2020-07-06 16:41 ` [PULL 42/53] cpu-throttle: new module, extracted from cpus.c Paolo Bonzini
2020-07-06 16:41 ` [PULL 43/53] cpu-timers, icount: new modules Paolo Bonzini
2020-07-06 16:41 ` [PULL 44/53] softmmu/vl: Remove the check for colons in -accel parameters Paolo Bonzini
2020-07-06 16:41 ` [PULL 45/53] accel/kvm: Let kvm_check_extension use global KVM state Paolo Bonzini
2020-07-06 16:41 ` [PULL 46/53] accel/kvm: Simplify kvm_check_extension() Paolo Bonzini
2020-07-06 16:41 ` [PULL 47/53] accel/kvm: Simplify kvm_check_extension_list() Paolo Bonzini
2020-07-06 16:41 ` [PULL 48/53] target/i386/kvm: Simplify get_para_features() Paolo Bonzini
2020-07-06 16:41 ` [PULL 49/53] target/i386/kvm: Simplify kvm_get_mce_cap_supported() Paolo Bonzini
2020-07-06 16:41 ` [PULL 50/53] target/i386/kvm: Simplify kvm_get_supported_[feature]_msrs() Paolo Bonzini
2020-07-06 16:41 ` [PULL 51/53] target/i386: Add SERIALIZE cpu feature Paolo Bonzini
2020-07-06 16:41 ` [PULL 52/53] target/i386: Enable TSX Suspend Load Address Tracking feature Paolo Bonzini
2020-07-06 16:41 ` [PULL 53/53] scripts: improve message when TAP based tests fail Paolo Bonzini
2020-07-06 17:19 ` [PULL 00/53] Misc patches for QEMU 5.1 soft freeze no-reply
2020-07-07 18:37 ` Peter Maydell
2020-07-07 18:42   ` Peter Maydell
2020-07-07 18:48     ` Paolo Bonzini
2020-07-08  8:25   ` Philippe Mathieu-Daudé
2020-07-08 16:13   ` Claudio Fontana
2020-07-08 16:16     ` Paolo Bonzini
2020-07-08 16:45       ` Claudio Fontana
2020-07-08 16:55         ` Paolo Bonzini
2020-07-08 17:03           ` Claudio Fontana
2020-07-08 18:25             ` Claudio Fontana
2020-07-08 18:34               ` Claudio Fontana
2020-07-08 18:41               ` Paolo Bonzini
2020-07-09  6:59                 ` Claudio Fontana
2020-07-09  9:57                   ` Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.