Переглянути джерело

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* Don't silently truncate extremely long words in the command line
* dtc configure fixes
* MemoryRegionCache second try
* Deprecated option removal
* add support for Hyper-V reenlightenment MSRs

# gpg: Signature made Fri 11 May 2018 13:33:46 BST
# gpg:                using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream: (29 commits)
  rename included C files to foo.inc.c, remove osdep.h
  pc-dimm: fix error messages if no slots were defined
  build: Silence dtc directory creation
  shippable: Remove Debian 8 libfdt kludge
  configure: Display if libfdt is from system or git
  configure: Really use local libfdt if the system one is too old
  i386/kvm: add support for Hyper-V reenlightenment MSRs
  qemu-doc: provide details of supported build platforms
  qemu-options: Remove deprecated -no-kvm-irqchip
  qemu-options: Remove deprecated -no-kvm-pit-reinjection
  qemu-options: Bail out on unsupported options instead of silently ignoring them
  qemu-options: Remove remainders of the -tdf option
  qemu-options: Mark -virtioconsole as deprecated
  target/i386: sev: fix memory leaks
  opts: don't silently truncate long option values
  opts: don't silently truncate long parameter keys
  accel: use g_strsplit for parsing accelerator names
  update-linux-headers: drop hyperv.h
  qemu-thread: always keep the posix wrapper layer
  exec: reintroduce MemoryRegion caching
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Peter Maydell 7 роки тому
батько
коміт
9ba1733a76
51 змінених файлів з 1029 додано та 621 видалено
  1. 0 8
      .shippable.yml
  2. 1 1
      Makefile
  3. 7 9
      accel/accel.c
  4. 0 26
      backends/hostmem.c
  5. 11 6
      configure
  6. 9 9
      cpus.c
  7. 187 55
      exec.c
  8. 21 12
      hw/i386/multiboot.c
  9. 8 1
      hw/mem/pc-dimm.c
  10. 34 45
      include/exec/cpu-all.h
  11. 3 0
      include/exec/memory-internal.h
  12. 96 113
      include/exec/memory.h
  13. 71 0
      include/exec/memory_ldst.inc.h
  14. 108 0
      include/exec/memory_ldst_cached.inc.h
  15. 147 0
      include/exec/memory_ldst_phys.inc.h
  16. 1 1
      include/qemu-common.h
  17. 1 2
      include/qemu/option.h
  18. 1 0
      include/qom/object.h
  19. 0 1
      include/sysemu/hostmem.h
  20. 2 2
      memory.c
  21. 0 126
      memory_ldst.inc.c
  22. 1 1
      numa.c
  23. 5 1
      os-posix.c
  24. 2 2
      os-win32.c
  25. 73 10
      qemu-doc.texi
  26. 1 14
      qemu-options.hx
  27. 3 2
      qom/object.c
  28. 0 6
      qom/object_interfaces.c
  29. 1 1
      rules.mak
  30. 28 0
      scripts/checkpatch.pl
  31. 0 6
      scripts/update-linux-headers.sh
  32. 1 1
      target/cris/translate.c
  33. 0 0
      target/cris/translate_v10.inc.c
  34. 3 1
      target/i386/cpu.c
  35. 4 0
      target/i386/cpu.h
  36. 8 1
      target/i386/hyperv-proto.h
  37. 38 1
      target/i386/kvm.c
  38. 24 0
      target/i386/machine.c
  39. 17 15
      target/i386/sev.c
  40. 1 1
      target/mips/translate.c
  41. 0 0
      target/mips/translate_init.inc.c
  42. 1 1
      target/ppc/int_helper.c
  43. 0 0
      target/ppc/mfrom_table.inc.c
  44. 1 1
      target/ppc/translate.c
  45. 0 1
      target/ppc/translate_init.inc.c
  46. 0 18
      tests/test-qemu-opts.c
  47. 11 11
      ui/vnc-enc-zrle.c
  48. 0 0
      ui/vnc-enc-zrle.inc.c
  49. 79 71
      util/qemu-option.c
  50. 13 20
      util/qemu-thread-posix.c
  51. 6 18
      vl.c

+ 0 - 8
.shippable.yml

@@ -35,13 +35,5 @@ build:
     options: "-e HOME=/root"
     options: "-e HOME=/root"
   ci:
   ci:
     - unset CC
     - unset CC
-    # some targets require newer up to date packages, for example TARGET_LIST matching
-    # aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu)
-    # see the configure script:
-    #    error_exit "DTC (libfdt) version >= 1.4.2 not present. Your options:"
-    #    "  (1) Preferred: Install the DTC (libfdt) devel package"
-    #    "  (2) Fetch the DTC submodule, using:"
-    #    "      git submodule update --init dtc"
-    - dpkg --compare-versions `dpkg-query --showformat='${Version}' --show libfdt-dev` ge 1.4.2 || git submodule update --init dtc
     - ./configure ${QEMU_CONFIGURE_OPTS} --target-list=${TARGET_LIST}
     - ./configure ${QEMU_CONFIGURE_OPTS} --target-list=${TARGET_LIST}
     - make -j$(($(getconf _NPROCESSORS_ONLN) + 1))
     - make -j$(($(getconf _NPROCESSORS_ONLN) + 1))

+ 1 - 1
Makefile

@@ -485,7 +485,7 @@ subdir-dtc: .git-submodule-status dtc/libfdt dtc/tests
 	$(call quiet-command,$(MAKE) $(DTC_MAKE_ARGS) CPPFLAGS="$(DTC_CPPFLAGS)" CFLAGS="$(DTC_CFLAGS)" LDFLAGS="$(LDFLAGS)" ARFLAGS="$(ARFLAGS)" CC="$(CC)" AR="$(AR)" LD="$(LD)" $(SUBDIR_MAKEFLAGS) libfdt/libfdt.a,)
 	$(call quiet-command,$(MAKE) $(DTC_MAKE_ARGS) CPPFLAGS="$(DTC_CPPFLAGS)" CFLAGS="$(DTC_CFLAGS)" LDFLAGS="$(LDFLAGS)" ARFLAGS="$(ARFLAGS)" CC="$(CC)" AR="$(AR)" LD="$(LD)" $(SUBDIR_MAKEFLAGS) libfdt/libfdt.a,)
 
 
 dtc/%: .git-submodule-status
 dtc/%: .git-submodule-status
-	mkdir -p $@
+	@mkdir -p $@
 
 
 # Overriding CFLAGS causes us to lose defines added in the sub-makefile.
 # Overriding CFLAGS causes us to lose defines added in the sub-makefile.
 # Not overriding CFLAGS leads to mis-matches between compilation modes.
 # Not overriding CFLAGS leads to mis-matches between compilation modes.

+ 7 - 9
accel/accel.c

@@ -70,8 +70,8 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms)
 
 
 void configure_accelerator(MachineState *ms)
 void configure_accelerator(MachineState *ms)
 {
 {
-    const char *accel, *p;
-    char buf[10];
+    const char *accel;
+    char **accel_list, **tmp;
     int ret;
     int ret;
     bool accel_initialised = false;
     bool accel_initialised = false;
     bool init_failed = false;
     bool init_failed = false;
@@ -83,13 +83,10 @@ void configure_accelerator(MachineState *ms)
         accel = "tcg";
         accel = "tcg";
     }
     }
 
 
-    p = accel;
-    while (!accel_initialised && *p != '\0') {
-        if (*p == ':') {
-            p++;
-        }
-        p = get_opt_name(buf, sizeof(buf), p, ':');
-        acc = accel_find(buf);
+    accel_list = g_strsplit(accel, ":", 0);
+
+    for (tmp = accel_list; !accel_initialised && tmp && *tmp; tmp++) {
+        acc = accel_find(*tmp);
         if (!acc) {
         if (!acc) {
             continue;
             continue;
         }
         }
@@ -107,6 +104,7 @@ void configure_accelerator(MachineState *ms)
             accel_initialised = true;
             accel_initialised = true;
         }
         }
     }
     }
+    g_strfreev(accel_list);
 
 
     if (!accel_initialised) {
     if (!accel_initialised) {
         if (!init_failed) {
         if (!init_failed) {

+ 0 - 26
backends/hostmem.c

@@ -369,24 +369,6 @@ host_memory_backend_can_be_deleted(UserCreatable *uc)
     }
     }
 }
 }
 
 
-static char *get_id(Object *o, Error **errp)
-{
-    HostMemoryBackend *backend = MEMORY_BACKEND(o);
-
-    return g_strdup(backend->id);
-}
-
-static void set_id(Object *o, const char *str, Error **errp)
-{
-    HostMemoryBackend *backend = MEMORY_BACKEND(o);
-
-    if (backend->id) {
-        error_setg(errp, "cannot change property value");
-        return;
-    }
-    backend->id = g_strdup(str);
-}
-
 static bool host_memory_backend_get_share(Object *o, Error **errp)
 static bool host_memory_backend_get_share(Object *o, Error **errp)
 {
 {
     HostMemoryBackend *backend = MEMORY_BACKEND(o);
     HostMemoryBackend *backend = MEMORY_BACKEND(o);
@@ -434,18 +416,11 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
         &HostMemPolicy_lookup,
         &HostMemPolicy_lookup,
         host_memory_backend_get_policy,
         host_memory_backend_get_policy,
         host_memory_backend_set_policy, &error_abort);
         host_memory_backend_set_policy, &error_abort);
-    object_class_property_add_str(oc, "id", get_id, set_id, &error_abort);
     object_class_property_add_bool(oc, "share",
     object_class_property_add_bool(oc, "share",
         host_memory_backend_get_share, host_memory_backend_set_share,
         host_memory_backend_get_share, host_memory_backend_set_share,
         &error_abort);
         &error_abort);
 }
 }
 
 
-static void host_memory_backend_finalize(Object *o)
-{
-    HostMemoryBackend *backend = MEMORY_BACKEND(o);
-    g_free(backend->id);
-}
-
 static const TypeInfo host_memory_backend_info = {
 static const TypeInfo host_memory_backend_info = {
     .name = TYPE_MEMORY_BACKEND,
     .name = TYPE_MEMORY_BACKEND,
     .parent = TYPE_OBJECT,
     .parent = TYPE_OBJECT,
@@ -454,7 +429,6 @@ static const TypeInfo host_memory_backend_info = {
     .class_init = host_memory_backend_class_init,
     .class_init = host_memory_backend_class_init,
     .instance_size = sizeof(HostMemoryBackend),
     .instance_size = sizeof(HostMemoryBackend),
     .instance_init = host_memory_backend_init,
     .instance_init = host_memory_backend_init,
-    .instance_finalize = host_memory_backend_finalize,
     .interfaces = (InterfaceInfo[]) {
     .interfaces = (InterfaceInfo[]) {
         { TYPE_USER_CREATABLE },
         { TYPE_USER_CREATABLE },
         { }
         { }

+ 11 - 6
configure

@@ -964,6 +964,8 @@ for opt do
   ;;
   ;;
   --firmwarepath=*) firmwarepath="$optarg"
   --firmwarepath=*) firmwarepath="$optarg"
   ;;
   ;;
+  --host=*|--build=*|\
+  --disable-dependency-tracking|\
   --sbindir=*|--sharedstatedir=*|\
   --sbindir=*|--sharedstatedir=*|\
   --oldincludedir=*|--datarootdir=*|--infodir=*|--localedir=*|\
   --oldincludedir=*|--datarootdir=*|--infodir=*|--localedir=*|\
   --htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*)
   --htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*)
@@ -3787,22 +3789,22 @@ int main(void) { fdt_first_subnode(0, 0); return 0; }
 EOF
 EOF
   if compile_prog "" "$fdt_libs" ; then
   if compile_prog "" "$fdt_libs" ; then
     # system DTC is good - use it
     # system DTC is good - use it
-    fdt=yes
+    fdt=system
   else
   else
       # have GIT checkout, so activate dtc submodule
       # have GIT checkout, so activate dtc submodule
       if test -e "${source_path}/.git" ; then
       if test -e "${source_path}/.git" ; then
           git_submodules="${git_submodules} dtc"
           git_submodules="${git_submodules} dtc"
       fi
       fi
       if test -d "${source_path}/dtc/libfdt" || test -e "${source_path}/.git" ; then
       if test -d "${source_path}/dtc/libfdt" || test -e "${source_path}/.git" ; then
-          fdt=yes
-          dtc_internal="yes"
+          fdt=git
           mkdir -p dtc
           mkdir -p dtc
           if [ "$pwd_is_source_path" != "y" ] ; then
           if [ "$pwd_is_source_path" != "y" ] ; then
               symlink "$source_path/dtc/Makefile" "dtc/Makefile"
               symlink "$source_path/dtc/Makefile" "dtc/Makefile"
               symlink "$source_path/dtc/scripts" "dtc/scripts"
               symlink "$source_path/dtc/scripts" "dtc/scripts"
           fi
           fi
           fdt_cflags="-I\$(SRC_PATH)/dtc/libfdt"
           fdt_cflags="-I\$(SRC_PATH)/dtc/libfdt"
-          fdt_libs="-L\$(BUILD_DIR)/dtc/libfdt $fdt_libs"
+          fdt_ldflags="-L\$(BUILD_DIR)/dtc/libfdt"
+          fdt_libs="$fdt_libs"
       elif test "$fdt" = "yes" ; then
       elif test "$fdt" = "yes" ; then
           # Not a git build & no libfdt found, prompt for system install
           # Not a git build & no libfdt found, prompt for system install
           error_exit "DTC (libfdt) version >= 1.4.2 not present." \
           error_exit "DTC (libfdt) version >= 1.4.2 not present." \
@@ -5744,6 +5746,7 @@ echo_version() {
 
 
 # prepend pixman and ftd flags after all config tests are done
 # prepend pixman and ftd flags after all config tests are done
 QEMU_CFLAGS="$pixman_cflags $fdt_cflags $QEMU_CFLAGS"
 QEMU_CFLAGS="$pixman_cflags $fdt_cflags $QEMU_CFLAGS"
+QEMU_LDFLAGS="$fdt_ldflags $QEMU_LDFLAGS"
 libs_softmmu="$pixman_libs $libs_softmmu"
 libs_softmmu="$pixman_libs $libs_softmmu"
 
 
 echo "Install prefix    $prefix"
 echo "Install prefix    $prefix"
@@ -5774,6 +5777,7 @@ echo "ARFLAGS           $ARFLAGS"
 echo "CFLAGS            $CFLAGS"
 echo "CFLAGS            $CFLAGS"
 echo "QEMU_CFLAGS       $QEMU_CFLAGS"
 echo "QEMU_CFLAGS       $QEMU_CFLAGS"
 echo "LDFLAGS           $LDFLAGS"
 echo "LDFLAGS           $LDFLAGS"
+echo "QEMU_LDFLAGS      $QEMU_LDFLAGS"
 echo "make              $make"
 echo "make              $make"
 echo "install           $install"
 echo "install           $install"
 echo "python            $python"
 echo "python            $python"
@@ -6333,7 +6337,7 @@ fi
 if test "$preadv" = "yes" ; then
 if test "$preadv" = "yes" ; then
   echo "CONFIG_PREADV=y" >> $config_host_mak
   echo "CONFIG_PREADV=y" >> $config_host_mak
 fi
 fi
-if test "$fdt" = "yes" ; then
+if test "$fdt" != "no" ; then
   echo "CONFIG_FDT=y" >> $config_host_mak
   echo "CONFIG_FDT=y" >> $config_host_mak
 fi
 fi
 if test "$membarrier" = "yes" ; then
 if test "$membarrier" = "yes" ; then
@@ -6708,6 +6712,7 @@ else
 fi
 fi
 echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
 echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
 echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
 echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
+echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
 echo "LD_REL_FLAGS=$LD_REL_FLAGS" >> $config_host_mak
 echo "LD_REL_FLAGS=$LD_REL_FLAGS" >> $config_host_mak
 echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak
 echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak
 echo "LIBS+=$LIBS" >> $config_host_mak
 echo "LIBS+=$LIBS" >> $config_host_mak
@@ -7134,7 +7139,7 @@ echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak
 
 
 done # for target in $targets
 done # for target in $targets
 
 
-if [ "$dtc_internal" = "yes" ]; then
+if [ "$fdt" = "git" ]; then
   echo "config-host.h: subdir-dtc" >> $config_host_mak
   echo "config-host.h: subdir-dtc" >> $config_host_mak
 fi
 fi
 if [ "$capstone" = "git" -o "$capstone" = "internal" ]; then
 if [ "$capstone" = "git" -o "$capstone" = "internal" ]; then

+ 9 - 9
cpus.c

@@ -1648,7 +1648,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
     /* process any pending work */
     /* process any pending work */
     cpu->exit_request = 1;
     cpu->exit_request = 1;
 
 
-    while (1) {
+    do {
         if (cpu_can_run(cpu)) {
         if (cpu_can_run(cpu)) {
             int r;
             int r;
             qemu_mutex_unlock_iothread();
             qemu_mutex_unlock_iothread();
@@ -2043,7 +2043,6 @@ int vm_stop(RunState state)
 int vm_prepare_start(void)
 int vm_prepare_start(void)
 {
 {
     RunState requested;
     RunState requested;
-    int res = 0;
 
 
     qemu_vmstop_requested(&requested);
     qemu_vmstop_requested(&requested);
     if (runstate_is_running() && requested == RUN_STATE__MAX) {
     if (runstate_is_running() && requested == RUN_STATE__MAX) {
@@ -2057,17 +2056,18 @@ int vm_prepare_start(void)
      */
      */
     if (runstate_is_running()) {
     if (runstate_is_running()) {
         qapi_event_send_stop(&error_abort);
         qapi_event_send_stop(&error_abort);
-        res = -1;
-    } else {
-        replay_enable_events();
-        cpu_enable_ticks();
-        runstate_set(RUN_STATE_RUNNING);
-        vm_state_notify(1, RUN_STATE_RUNNING);
+        qapi_event_send_resume(&error_abort);
+        return -1;
     }
     }
 
 
     /* We are sending this now, but the CPUs will be resumed shortly later */
     /* We are sending this now, but the CPUs will be resumed shortly later */
     qapi_event_send_resume(&error_abort);
     qapi_event_send_resume(&error_abort);
-    return res;
+
+    replay_enable_events();
+    cpu_enable_ticks();
+    runstate_set(RUN_STATE_RUNNING);
+    vm_state_notify(1, RUN_STATE_RUNNING);
+    return 0;
 }
 }
 
 
 void vm_start(void)
 void vm_start(void)

+ 187 - 55
exec.c

@@ -461,6 +461,70 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
     return section;
     return section;
 }
 }
 
 
+/**
+ * address_space_translate_iommu - translate an address through an IOMMU
+ * memory region and then through the target address space.
+ *
+ * @iommu_mr: the IOMMU memory region that we start the translation from
+ * @addr: the address to be translated through the MMU
+ * @xlat: the translated address offset within the destination memory region.
+ *        It cannot be %NULL.
+ * @plen_out: valid read/write length of the translated address. It
+ *            cannot be %NULL.
+ * @page_mask_out: page mask for the translated address. This
+ *            should only be meaningful for IOMMU translated
+ *            addresses, since there may be huge pages that this bit
+ *            would tell. It can be %NULL if we don't care about it.
+ * @is_write: whether the translation operation is for write
+ * @is_mmio: whether this can be MMIO, set true if it can
+ * @target_as: the address space targeted by the IOMMU
+ *
+ * This function is called from RCU critical section.  It is the common
+ * part of flatview_do_translate and address_space_translate_cached.
+ */
+static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iommu_mr,
+                                                         hwaddr *xlat,
+                                                         hwaddr *plen_out,
+                                                         hwaddr *page_mask_out,
+                                                         bool is_write,
+                                                         bool is_mmio,
+                                                         AddressSpace **target_as)
+{
+    MemoryRegionSection *section;
+    hwaddr page_mask = (hwaddr)-1;
+
+    do {
+        hwaddr addr = *xlat;
+        IOMMUMemoryRegionClass *imrc = memory_region_get_iommu_class_nocheck(iommu_mr);
+        IOMMUTLBEntry iotlb = imrc->translate(iommu_mr, addr, is_write ?
+                                              IOMMU_WO : IOMMU_RO);
+
+        if (!(iotlb.perm & (1 << is_write))) {
+            goto unassigned;
+        }
+
+        addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
+                | (addr & iotlb.addr_mask));
+        page_mask &= iotlb.addr_mask;
+        *plen_out = MIN(*plen_out, (addr | iotlb.addr_mask) - addr + 1);
+        *target_as = iotlb.target_as;
+
+        section = address_space_translate_internal(
+                address_space_to_dispatch(iotlb.target_as), addr, xlat,
+                plen_out, is_mmio);
+
+        iommu_mr = memory_region_get_iommu(section->mr);
+    } while (unlikely(iommu_mr));
+
+    if (page_mask_out) {
+        *page_mask_out = page_mask;
+    }
+    return *section;
+
+unassigned:
+    return (MemoryRegionSection) { .mr = &io_mem_unassigned };
+}
+
 /**
 /**
  * flatview_do_translate - translate an address in FlatView
  * flatview_do_translate - translate an address in FlatView
  *
  *
@@ -476,6 +540,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
  *            would tell. It can be @NULL if we don't care about it.
  *            would tell. It can be @NULL if we don't care about it.
  * @is_write: whether the translation operation is for write
  * @is_write: whether the translation operation is for write
  * @is_mmio: whether this can be MMIO, set true if it can
  * @is_mmio: whether this can be MMIO, set true if it can
+ * @target_as: the address space targeted by the IOMMU
  *
  *
  * This function is called from RCU critical section
  * This function is called from RCU critical section
  */
  */
@@ -488,61 +553,31 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
                                                  bool is_mmio,
                                                  bool is_mmio,
                                                  AddressSpace **target_as)
                                                  AddressSpace **target_as)
 {
 {
-    IOMMUTLBEntry iotlb;
     MemoryRegionSection *section;
     MemoryRegionSection *section;
     IOMMUMemoryRegion *iommu_mr;
     IOMMUMemoryRegion *iommu_mr;
-    IOMMUMemoryRegionClass *imrc;
-    hwaddr page_mask = (hwaddr)(-1);
     hwaddr plen = (hwaddr)(-1);
     hwaddr plen = (hwaddr)(-1);
 
 
-    if (plen_out) {
-        plen = *plen_out;
-    }
-
-    for (;;) {
-        section = address_space_translate_internal(
-                flatview_to_dispatch(fv), addr, &addr,
-                &plen, is_mmio);
-
-        iommu_mr = memory_region_get_iommu(section->mr);
-        if (!iommu_mr) {
-            break;
-        }
-        imrc = memory_region_get_iommu_class_nocheck(iommu_mr);
-
-        iotlb = imrc->translate(iommu_mr, addr, is_write ?
-                                IOMMU_WO : IOMMU_RO);
-        addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
-                | (addr & iotlb.addr_mask));
-        page_mask &= iotlb.addr_mask;
-        plen = MIN(plen, (addr | iotlb.addr_mask) - addr + 1);
-        if (!(iotlb.perm & (1 << is_write))) {
-            goto translate_fail;
-        }
-
-        fv = address_space_to_flatview(iotlb.target_as);
-        *target_as = iotlb.target_as;
+    if (!plen_out) {
+        plen_out = &plen;
     }
     }
 
 
-    *xlat = addr;
+    section = address_space_translate_internal(
+            flatview_to_dispatch(fv), addr, xlat,
+            plen_out, is_mmio);
 
 
-    if (page_mask == (hwaddr)(-1)) {
-        /* Not behind an IOMMU, use default page size. */
-        page_mask = ~TARGET_PAGE_MASK;
+    iommu_mr = memory_region_get_iommu(section->mr);
+    if (unlikely(iommu_mr)) {
+        return address_space_translate_iommu(iommu_mr, xlat,
+                                             plen_out, page_mask_out,
+                                             is_write, is_mmio,
+                                             target_as);
     }
     }
-
     if (page_mask_out) {
     if (page_mask_out) {
-        *page_mask_out = page_mask;
-    }
-
-    if (plen_out) {
-        *plen_out = plen;
+        /* Not behind an IOMMU, use default page size. */
+        *page_mask_out = ~TARGET_PAGE_MASK;
     }
     }
 
 
     return *section;
     return *section;
-
-translate_fail:
-    return (MemoryRegionSection) { .mr = &io_mem_unassigned };
 }
 }
 
 
 /* Called from RCU critical section */
 /* Called from RCU critical section */
@@ -3606,33 +3641,130 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
                                  hwaddr len,
                                  hwaddr len,
                                  bool is_write)
                                  bool is_write)
 {
 {
-    cache->len = len;
-    cache->as = as;
-    cache->xlat = addr;
-    return len;
+    AddressSpaceDispatch *d;
+    hwaddr l;
+    MemoryRegion *mr;
+
+    assert(len > 0);
+
+    l = len;
+    cache->fv = address_space_get_flatview(as);
+    d = flatview_to_dispatch(cache->fv);
+    cache->mrs = *address_space_translate_internal(d, addr, &cache->xlat, &l, true);
+
+    mr = cache->mrs.mr;
+    memory_region_ref(mr);
+    if (memory_access_is_direct(mr, is_write)) {
+        l = flatview_extend_translation(cache->fv, addr, len, mr,
+                                        cache->xlat, l, is_write);
+        cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
+    } else {
+        cache->ptr = NULL;
+    }
+
+    cache->len = l;
+    cache->is_write = is_write;
+    return l;
 }
 }
 
 
 void address_space_cache_invalidate(MemoryRegionCache *cache,
 void address_space_cache_invalidate(MemoryRegionCache *cache,
                                     hwaddr addr,
                                     hwaddr addr,
                                     hwaddr access_len)
                                     hwaddr access_len)
 {
 {
+    assert(cache->is_write);
+    if (likely(cache->ptr)) {
+        invalidate_and_set_dirty(cache->mrs.mr, addr + cache->xlat, access_len);
+    }
 }
 }
 
 
 void address_space_cache_destroy(MemoryRegionCache *cache)
 void address_space_cache_destroy(MemoryRegionCache *cache)
 {
 {
-    cache->as = NULL;
+    if (!cache->mrs.mr) {
+        return;
+    }
+
+    if (xen_enabled()) {
+        xen_invalidate_map_cache_entry(cache->ptr);
+    }
+    memory_region_unref(cache->mrs.mr);
+    flatview_unref(cache->fv);
+    cache->mrs.mr = NULL;
+    cache->fv = NULL;
+}
+
+/* Called from RCU critical section.  This function has the same
+ * semantics as address_space_translate, but it only works on a
+ * predefined range of a MemoryRegion that was mapped with
+ * address_space_cache_init.
+ */
+static inline MemoryRegion *address_space_translate_cached(
+    MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat,
+    hwaddr *plen, bool is_write)
+{
+    MemoryRegionSection section;
+    MemoryRegion *mr;
+    IOMMUMemoryRegion *iommu_mr;
+    AddressSpace *target_as;
+
+    assert(!cache->ptr);
+    *xlat = addr + cache->xlat;
+
+    mr = cache->mrs.mr;
+    iommu_mr = memory_region_get_iommu(mr);
+    if (!iommu_mr) {
+        /* MMIO region.  */
+        return mr;
+    }
+
+    section = address_space_translate_iommu(iommu_mr, xlat, plen,
+                                            NULL, is_write, true,
+                                            &target_as);
+    return section.mr;
+}
+
+/* Called from RCU critical section. address_space_read_cached uses this
+ * out of line function when the target is an MMIO or IOMMU region.
+ */
+void
+address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
+                                   void *buf, int len)
+{
+    hwaddr addr1, l;
+    MemoryRegion *mr;
+
+    l = len;
+    mr = address_space_translate_cached(cache, addr, &addr1, &l, false);
+    flatview_read_continue(cache->fv,
+                           addr, MEMTXATTRS_UNSPECIFIED, buf, len,
+                           addr1, l, mr);
+}
+
+/* Called from RCU critical section. address_space_write_cached uses this
+ * out of line function when the target is an MMIO or IOMMU region.
+ */
+void
+address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
+                                    const void *buf, int len)
+{
+    hwaddr addr1, l;
+    MemoryRegion *mr;
+
+    l = len;
+    mr = address_space_translate_cached(cache, addr, &addr1, &l, true);
+    flatview_write_continue(cache->fv,
+                            addr, MEMTXATTRS_UNSPECIFIED, buf, len,
+                            addr1, l, mr);
 }
 }
 
 
 #define ARG1_DECL                MemoryRegionCache *cache
 #define ARG1_DECL                MemoryRegionCache *cache
 #define ARG1                     cache
 #define ARG1                     cache
-#define SUFFIX                   _cached
-#define TRANSLATE(addr, ...)     \
-    address_space_translate(cache->as, cache->xlat + (addr), __VA_ARGS__)
-#define IS_DIRECT(mr, is_write)  true
-#define MAP_RAM(mr, ofs)         qemu_map_ram_ptr((mr)->ram_block, ofs)
+#define SUFFIX                   _cached_slow
+#define TRANSLATE(...)           address_space_translate_cached(cache, __VA_ARGS__)
+#define IS_DIRECT(mr, is_write)  memory_access_is_direct(mr, is_write)
+#define MAP_RAM(mr, ofs)         (cache->ptr + (ofs - cache->xlat))
 #define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len)
 #define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len)
-#define RCU_READ_LOCK()          rcu_read_lock()
-#define RCU_READ_UNLOCK()        rcu_read_unlock()
+#define RCU_READ_LOCK()          ((void)0)
+#define RCU_READ_UNLOCK()        ((void)0)
 #include "memory_ldst.inc.c"
 #include "memory_ldst.inc.c"
 
 
 /* virtual memory access for debug (includes writing to ROM) */
 /* virtual memory access for debug (includes writing to ROM) */

+ 21 - 12
hw/i386/multiboot.c

@@ -291,12 +291,16 @@ int load_multiboot(FWCfgState *fw_cfg,
     cmdline_len = strlen(kernel_filename) + 1;
     cmdline_len = strlen(kernel_filename) + 1;
     cmdline_len += strlen(kernel_cmdline) + 1;
     cmdline_len += strlen(kernel_cmdline) + 1;
     if (initrd_filename) {
     if (initrd_filename) {
-        const char *r = initrd_filename;
+        const char *r = get_opt_value(initrd_filename, NULL);
         cmdline_len += strlen(r) + 1;
         cmdline_len += strlen(r) + 1;
         mbs.mb_mods_avail = 1;
         mbs.mb_mods_avail = 1;
-        while (*(r = get_opt_value(NULL, 0, r))) {
-           mbs.mb_mods_avail++;
-           r++;
+        while (1) {
+            mbs.mb_mods_avail++;
+            r = get_opt_value(r, NULL);
+            if (!*r) {
+                break;
+            }
+            r++;
         }
         }
     }
     }
 
 
@@ -313,7 +317,8 @@ int load_multiboot(FWCfgState *fw_cfg,
 
 
     if (initrd_filename) {
     if (initrd_filename) {
         const char *next_initrd;
         const char *next_initrd;
-        char not_last, tmpbuf[strlen(initrd_filename) + 1];
+        char not_last;
+        char *one_file = NULL;
 
 
         mbs.offset_mods = mbs.mb_buf_size;
         mbs.offset_mods = mbs.mb_buf_size;
 
 
@@ -322,24 +327,26 @@ int load_multiboot(FWCfgState *fw_cfg,
             int mb_mod_length;
             int mb_mod_length;
             uint32_t offs = mbs.mb_buf_size;
             uint32_t offs = mbs.mb_buf_size;
 
 
-            next_initrd = get_opt_value(tmpbuf, sizeof(tmpbuf), initrd_filename);
+            next_initrd = get_opt_value(initrd_filename, &one_file);
             not_last = *next_initrd;
             not_last = *next_initrd;
             /* if a space comes after the module filename, treat everything
             /* if a space comes after the module filename, treat everything
                after that as parameters */
                after that as parameters */
-            hwaddr c = mb_add_cmdline(&mbs, tmpbuf);
-            if ((next_space = strchr(tmpbuf, ' ')))
+            hwaddr c = mb_add_cmdline(&mbs, one_file);
+            next_space = strchr(one_file, ' ');
+            if (next_space) {
                 *next_space = '\0';
                 *next_space = '\0';
-            mb_debug("multiboot loading module: %s", tmpbuf);
-            mb_mod_length = get_image_size(tmpbuf);
+            }
+            mb_debug("multiboot loading module: %s", one_file);
+            mb_mod_length = get_image_size(one_file);
             if (mb_mod_length < 0) {
             if (mb_mod_length < 0) {
-                error_report("Failed to open file '%s'", tmpbuf);
+                error_report("Failed to open file '%s'", one_file);
                 exit(1);
                 exit(1);
             }
             }
 
 
             mbs.mb_buf_size = TARGET_PAGE_ALIGN(mb_mod_length + mbs.mb_buf_size);
             mbs.mb_buf_size = TARGET_PAGE_ALIGN(mb_mod_length + mbs.mb_buf_size);
             mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size);
             mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size);
 
 
-            load_image(tmpbuf, (unsigned char *)mbs.mb_buf + offs);
+            load_image(one_file, (unsigned char *)mbs.mb_buf + offs);
             mb_add_mod(&mbs, mbs.mb_buf_phys + offs,
             mb_add_mod(&mbs, mbs.mb_buf_phys + offs,
                        mbs.mb_buf_phys + offs + mb_mod_length, c);
                        mbs.mb_buf_phys + offs + mb_mod_length, c);
 
 
@@ -347,6 +354,8 @@ int load_multiboot(FWCfgState *fw_cfg,
                      (char *)mbs.mb_buf + offs,
                      (char *)mbs.mb_buf + offs,
                      (char *)mbs.mb_buf + offs + mb_mod_length, c);
                      (char *)mbs.mb_buf + offs + mb_mod_length, c);
             initrd_filename = next_initrd+1;
             initrd_filename = next_initrd+1;
+            g_free(one_file);
+            one_file = NULL;
         } while (not_last);
         } while (not_last);
     }
     }
 
 

+ 8 - 1
hw/mem/pc-dimm.c

@@ -118,9 +118,16 @@ static int pc_dimm_slot2bitmap(Object *obj, void *opaque)
 
 
 int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp)
 int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp)
 {
 {
-    unsigned long *bitmap = bitmap_new(max_slots);
+    unsigned long *bitmap;
     int slot = 0;
     int slot = 0;
 
 
+    if (max_slots <= 0) {
+        error_setg(errp, "no slots where allocated, please specify "
+                   "the 'slots' option");
+        return slot;
+    }
+
+    bitmap = bitmap_new(max_slots);
     object_child_foreach(qdev_get_machine(), pc_dimm_slot2bitmap, bitmap);
     object_child_foreach(qdev_get_machine(), pc_dimm_slot2bitmap, bitmap);
 
 
     /* check if requested slot is not occupied */
     /* check if requested slot is not occupied */

+ 34 - 45
include/exec/cpu-all.h

@@ -168,51 +168,40 @@ extern unsigned long reserved_va;
 #else
 #else
 
 
 #include "exec/hwaddr.h"
 #include "exec/hwaddr.h"
-uint32_t lduw_phys(AddressSpace *as, hwaddr addr);
-uint32_t ldl_phys(AddressSpace *as, hwaddr addr);
-uint64_t ldq_phys(AddressSpace *as, hwaddr addr);
-void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val);
-void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val);
-void stl_phys(AddressSpace *as, hwaddr addr, uint32_t val);
-void stq_phys(AddressSpace *as, hwaddr addr, uint64_t val);
-
-uint32_t address_space_lduw(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_ldl(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint64_t address_space_ldq(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stw(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stl(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stq(AddressSpace *as, hwaddr addr, uint64_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-
-uint32_t lduw_phys_cached(MemoryRegionCache *cache, hwaddr addr);
-uint32_t ldl_phys_cached(MemoryRegionCache *cache, hwaddr addr);
-uint64_t ldq_phys_cached(MemoryRegionCache *cache, hwaddr addr);
-void stl_phys_notdirty_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
-void stw_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
-void stl_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
-void stq_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val);
-
-uint32_t address_space_lduw_cached(MemoryRegionCache *cache, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_ldl_cached(MemoryRegionCache *cache, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint64_t address_space_ldq_cached(MemoryRegionCache *cache, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stl_notdirty_cached(MemoryRegionCache *cache, hwaddr addr,
-                            uint32_t val, MemTxAttrs attrs, MemTxResult *result);
-void address_space_stw_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stl_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stq_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
+
+#define SUFFIX
+#define ARG1         as
+#define ARG1_DECL    AddressSpace *as
+#define TARGET_ENDIANNESS
+#include "exec/memory_ldst.inc.h"
+
+#define SUFFIX       _cached_slow
+#define ARG1         cache
+#define ARG1_DECL    MemoryRegionCache *cache
+#define TARGET_ENDIANNESS
+#include "exec/memory_ldst.inc.h"
+
+static inline void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)
+{
+    address_space_stl_notdirty(as, addr, val,
+                               MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+#define SUFFIX
+#define ARG1         as
+#define ARG1_DECL    AddressSpace *as
+#define TARGET_ENDIANNESS
+#include "exec/memory_ldst_phys.inc.h"
+
+/* Inline fast path for direct RAM access.  */
+#define ENDIANNESS
+#include "exec/memory_ldst_cached.inc.h"
+
+#define SUFFIX       _cached
+#define ARG1         cache
+#define ARG1_DECL    MemoryRegionCache *cache
+#define TARGET_ENDIANNESS
+#include "exec/memory_ldst_phys.inc.h"
 #endif
 #endif
 
 
 /* page related stuff */
 /* page related stuff */

+ 3 - 0
include/exec/memory-internal.h

@@ -31,6 +31,9 @@ static inline AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as)
     return flatview_to_dispatch(address_space_to_flatview(as));
     return flatview_to_dispatch(address_space_to_flatview(as));
 }
 }
 
 
+FlatView *address_space_get_flatview(AddressSpace *as);
+void flatview_unref(FlatView *view);
+
 extern const MemoryRegionOps unassigned_mem_ops;
 extern const MemoryRegionOps unassigned_mem_ops;
 
 
 bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
 bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,

+ 96 - 113
include/exec/memory.h

@@ -1676,57 +1676,91 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
  * @result: location to write the success/failure of the transaction;
  * @result: location to write the success/failure of the transaction;
  *   if NULL, this information is discarded
  *   if NULL, this information is discarded
  */
  */
-uint32_t address_space_ldub(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_lduw_le(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_lduw_be(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_ldl_le(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_ldl_be(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint64_t address_space_ldq_le(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint64_t address_space_ldq_be(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stb(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stw_le(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stw_be(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stl_le(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stl_be(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stq_le(AddressSpace *as, hwaddr addr, uint64_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stq_be(AddressSpace *as, hwaddr addr, uint64_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-
-uint32_t ldub_phys(AddressSpace *as, hwaddr addr);
-uint32_t lduw_le_phys(AddressSpace *as, hwaddr addr);
-uint32_t lduw_be_phys(AddressSpace *as, hwaddr addr);
-uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr);
-uint32_t ldl_be_phys(AddressSpace *as, hwaddr addr);
-uint64_t ldq_le_phys(AddressSpace *as, hwaddr addr);
-uint64_t ldq_be_phys(AddressSpace *as, hwaddr addr);
-void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val);
-void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val);
-void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val);
-void stl_le_phys(AddressSpace *as, hwaddr addr, uint32_t val);
-void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val);
-void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val);
-void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val);
+
+#define SUFFIX
+#define ARG1         as
+#define ARG1_DECL    AddressSpace *as
+#include "exec/memory_ldst.inc.h"
+
+#define SUFFIX
+#define ARG1         as
+#define ARG1_DECL    AddressSpace *as
+#include "exec/memory_ldst_phys.inc.h"
 
 
 struct MemoryRegionCache {
 struct MemoryRegionCache {
+    void *ptr;
     hwaddr xlat;
     hwaddr xlat;
     hwaddr len;
     hwaddr len;
-    AddressSpace *as;
+    FlatView *fv;
+    MemoryRegionSection mrs;
+    bool is_write;
 };
 };
 
 
-#define MEMORY_REGION_CACHE_INVALID ((MemoryRegionCache) { .as = NULL })
+#define MEMORY_REGION_CACHE_INVALID ((MemoryRegionCache) { .mrs.mr = NULL })
+
+
+/* address_space_ld*_cached: load from a cached #MemoryRegion
+ * address_space_st*_cached: store into a cached #MemoryRegion
+ *
+ * These functions perform a load or store of the byte, word,
+ * longword or quad to the specified address.  The address is
+ * a physical address in the AddressSpace, but it must lie within
+ * a #MemoryRegion that was mapped with address_space_cache_init.
+ *
+ * The _le suffixed functions treat the data as little endian;
+ * _be indicates big endian; no suffix indicates "same endianness
+ * as guest CPU".
+ *
+ * The "guest CPU endianness" accessors are deprecated for use outside
+ * target-* code; devices should be CPU-agnostic and use either the LE
+ * or the BE accessors.
+ *
+ * @cache: previously initialized #MemoryRegionCache to be accessed
+ * @addr: address within the address space
+ * @val: data value, for stores
+ * @attrs: memory transaction attributes
+ * @result: location to write the success/failure of the transaction;
+ *   if NULL, this information is discarded
+ */
+
+#define SUFFIX       _cached_slow
+#define ARG1         cache
+#define ARG1_DECL    MemoryRegionCache *cache
+#include "exec/memory_ldst.inc.h"
+
+/* Inline fast path for direct RAM access.  */
+static inline uint8_t address_space_ldub_cached(MemoryRegionCache *cache,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
+{
+    assert(addr < cache->len);
+    if (likely(cache->ptr)) {
+        return ldub_p(cache->ptr + addr);
+    } else {
+        return address_space_ldub_cached_slow(cache, addr, attrs, result);
+    }
+}
+
+static inline void address_space_stb_cached(MemoryRegionCache *cache,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
+{
+    assert(addr < cache->len);
+    if (likely(cache->ptr)) {
+        stb_p(cache->ptr + addr, val);
+    } else {
+        address_space_stb_cached_slow(cache, addr, val, attrs, result);
+    }
+}
+
+#define ENDIANNESS   _le
+#include "exec/memory_ldst_cached.inc.h"
+
+#define ENDIANNESS   _be
+#include "exec/memory_ldst_cached.inc.h"
+
+#define SUFFIX       _cached
+#define ARG1         cache
+#define ARG1_DECL    MemoryRegionCache *cache
+#include "exec/memory_ldst_phys.inc.h"
 
 
 /* address_space_cache_init: prepare for repeated access to a physical
 /* address_space_cache_init: prepare for repeated access to a physical
  * memory region
  * memory region
@@ -1772,72 +1806,6 @@ void address_space_cache_invalidate(MemoryRegionCache *cache,
  */
  */
 void address_space_cache_destroy(MemoryRegionCache *cache);
 void address_space_cache_destroy(MemoryRegionCache *cache);
 
 
-/* address_space_ld*_cached: load from a cached #MemoryRegion
- * address_space_st*_cached: store into a cached #MemoryRegion
- *
- * These functions perform a load or store of the byte, word,
- * longword or quad to the specified address.  The address is
- * a physical address in the AddressSpace, but it must lie within
- * a #MemoryRegion that was mapped with address_space_cache_init.
- *
- * The _le suffixed functions treat the data as little endian;
- * _be indicates big endian; no suffix indicates "same endianness
- * as guest CPU".
- *
- * The "guest CPU endianness" accessors are deprecated for use outside
- * target-* code; devices should be CPU-agnostic and use either the LE
- * or the BE accessors.
- *
- * @cache: previously initialized #MemoryRegionCache to be accessed
- * @addr: address within the address space
- * @val: data value, for stores
- * @attrs: memory transaction attributes
- * @result: location to write the success/failure of the transaction;
- *   if NULL, this information is discarded
- */
-uint32_t address_space_ldub_cached(MemoryRegionCache *cache, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_lduw_le_cached(MemoryRegionCache *cache, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_lduw_be_cached(MemoryRegionCache *cache, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_ldl_le_cached(MemoryRegionCache *cache, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_ldl_be_cached(MemoryRegionCache *cache, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint64_t address_space_ldq_le_cached(MemoryRegionCache *cache, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint64_t address_space_ldq_be_cached(MemoryRegionCache *cache, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stb_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stw_le_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stw_be_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stl_le_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stl_be_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stq_le_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stq_be_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-
-uint32_t ldub_phys_cached(MemoryRegionCache *cache, hwaddr addr);
-uint32_t lduw_le_phys_cached(MemoryRegionCache *cache, hwaddr addr);
-uint32_t lduw_be_phys_cached(MemoryRegionCache *cache, hwaddr addr);
-uint32_t ldl_le_phys_cached(MemoryRegionCache *cache, hwaddr addr);
-uint32_t ldl_be_phys_cached(MemoryRegionCache *cache, hwaddr addr);
-uint64_t ldq_le_phys_cached(MemoryRegionCache *cache, hwaddr addr);
-uint64_t ldq_be_phys_cached(MemoryRegionCache *cache, hwaddr addr);
-void stb_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
-void stw_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
-void stw_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
-void stl_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
-void stl_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
-void stq_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val);
-void stq_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val);
 /* address_space_get_iotlb_entry: translate an address into an IOTLB
 /* address_space_get_iotlb_entry: translate an address into an IOTLB
  * entry. Should be called from an RCU critical section.
  * entry. Should be called from an RCU critical section.
  */
  */
@@ -1925,6 +1893,13 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
                                    MemoryRegion *mr);
                                    MemoryRegion *mr);
 void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
 void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
 
 
+/* Internal functions, part of the implementation of address_space_read_cached
+ * and address_space_write_cached.  */
+void address_space_read_cached_slow(MemoryRegionCache *cache,
+                                    hwaddr addr, void *buf, int len);
+void address_space_write_cached_slow(MemoryRegionCache *cache,
+                                     hwaddr addr, const void *buf, int len);
+
 static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
 static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
 {
 {
     if (is_write) {
     if (is_write) {
@@ -1993,7 +1968,11 @@ address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,
                           void *buf, int len)
                           void *buf, int len)
 {
 {
     assert(addr < cache->len && len <= cache->len - addr);
     assert(addr < cache->len && len <= cache->len - addr);
-    address_space_read(cache->as, cache->xlat + addr, MEMTXATTRS_UNSPECIFIED, buf, len);
+    if (likely(cache->ptr)) {
+        memcpy(buf, cache->ptr + addr, len);
+    } else {
+        address_space_read_cached_slow(cache, addr, buf, len);
+    }
 }
 }
 
 
 /**
 /**
@@ -2009,7 +1988,11 @@ address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,
                            void *buf, int len)
                            void *buf, int len)
 {
 {
     assert(addr < cache->len && len <= cache->len - addr);
     assert(addr < cache->len && len <= cache->len - addr);
-    address_space_write(cache->as, cache->xlat + addr, MEMTXATTRS_UNSPECIFIED, buf, len);
+    if (likely(cache->ptr)) {
+        memcpy(cache->ptr + addr, buf, len);
+    } else {
+        address_space_write_cached_slow(cache, addr, buf, len);
+    }
 }
 }
 
 
 #endif
 #endif

+ 71 - 0
include/exec/memory_ldst.inc.h

@@ -0,0 +1,71 @@
+/*
+ *  Physical memory access templates
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *  Copyright (c) 2015 Linaro, Inc.
+ *  Copyright (c) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef TARGET_ENDIANNESS
+extern uint32_t glue(address_space_lduw, SUFFIX)(ARG1_DECL,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
+extern uint32_t glue(address_space_ldl, SUFFIX)(ARG1_DECL,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
+extern uint64_t glue(address_space_ldq, SUFFIX)(ARG1_DECL,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stw, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stl, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stq, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
+#else
+extern uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
+extern uint32_t glue(address_space_lduw_le, SUFFIX)(ARG1_DECL,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
+extern uint32_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
+extern uint32_t glue(address_space_ldl_le, SUFFIX)(ARG1_DECL,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
+extern uint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
+extern uint64_t glue(address_space_ldq_le, SUFFIX)(ARG1_DECL,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
+extern uint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stb, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stw_le, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stw_be, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stl_le, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stl_be, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stq_le, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
+extern void glue(address_space_stq_be, SUFFIX)(ARG1_DECL,
+    hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
+#endif
+
+#undef ARG1_DECL
+#undef ARG1
+#undef SUFFIX
+#undef TARGET_ENDIANNESS

+ 108 - 0
include/exec/memory_ldst_cached.inc.h

@@ -0,0 +1,108 @@
+/*
+ *  Memory access templates for MemoryRegionCache
+ *
+ *  Copyright (c) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define ADDRESS_SPACE_LD_CACHED(size) \
+    glue(glue(address_space_ld, size), glue(ENDIANNESS, _cached))
+#define ADDRESS_SPACE_LD_CACHED_SLOW(size) \
+    glue(glue(address_space_ld, size), glue(ENDIANNESS, _cached_slow))
+#define LD_P(size) \
+    glue(glue(ld, size), glue(ENDIANNESS, _p))
+
+static inline uint32_t ADDRESS_SPACE_LD_CACHED(l)(MemoryRegionCache *cache,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
+{
+    assert(addr < cache->len && 4 <= cache->len - addr);
+    if (likely(cache->ptr)) {
+        return LD_P(l)(cache->ptr + addr);
+    } else {
+        return ADDRESS_SPACE_LD_CACHED_SLOW(l)(cache, addr, attrs, result);
+    }
+}
+
+static inline uint64_t ADDRESS_SPACE_LD_CACHED(q)(MemoryRegionCache *cache,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
+{
+    assert(addr < cache->len && 8 <= cache->len - addr);
+    if (likely(cache->ptr)) {
+        return LD_P(q)(cache->ptr + addr);
+    } else {
+        return ADDRESS_SPACE_LD_CACHED_SLOW(q)(cache, addr, attrs, result);
+    }
+}
+
+static inline uint32_t ADDRESS_SPACE_LD_CACHED(uw)(MemoryRegionCache *cache,
+    hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
+{
+    assert(addr < cache->len && 2 <= cache->len - addr);
+    if (likely(cache->ptr)) {
+        return LD_P(uw)(cache->ptr + addr);
+    } else {
+        return ADDRESS_SPACE_LD_CACHED_SLOW(uw)(cache, addr, attrs, result);
+    }
+}
+
+#undef ADDRESS_SPACE_LD_CACHED
+#undef ADDRESS_SPACE_LD_CACHED_SLOW
+#undef LD_P
+
+#define ADDRESS_SPACE_ST_CACHED(size) \
+    glue(glue(address_space_st, size), glue(ENDIANNESS, _cached))
+#define ADDRESS_SPACE_ST_CACHED_SLOW(size) \
+    glue(glue(address_space_st, size), glue(ENDIANNESS, _cached_slow))
+#define ST_P(size) \
+    glue(glue(st, size), glue(ENDIANNESS, _p))
+
+static inline void ADDRESS_SPACE_ST_CACHED(l)(MemoryRegionCache *cache,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
+{
+    assert(addr < cache->len && 4 <= cache->len - addr);
+    if (likely(cache->ptr)) {
+        ST_P(l)(cache->ptr + addr, val);
+    } else {
+        ADDRESS_SPACE_ST_CACHED_SLOW(l)(cache, addr, val, attrs, result);
+    }
+}
+
+static inline void ADDRESS_SPACE_ST_CACHED(w)(MemoryRegionCache *cache,
+    hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
+{
+    assert(addr < cache->len && 2 <= cache->len - addr);
+    if (likely(cache->ptr)) {
+        ST_P(w)(cache->ptr + addr, val);
+    } else {
+        ADDRESS_SPACE_ST_CACHED_SLOW(w)(cache, addr, val, attrs, result);
+    }
+}
+
+static inline void ADDRESS_SPACE_ST_CACHED(q)(MemoryRegionCache *cache,
+    hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result)
+{
+    assert(addr < cache->len && 8 <= cache->len - addr);
+    if (likely(cache->ptr)) {
+        ST_P(q)(cache->ptr + addr, val);
+    } else {
+        ADDRESS_SPACE_ST_CACHED_SLOW(q)(cache, addr, val, attrs, result);
+    }
+}
+
+#undef ADDRESS_SPACE_ST_CACHED
+#undef ADDRESS_SPACE_ST_CACHED_SLOW
+#undef ST_P
+
+#undef ENDIANNESS

+ 147 - 0
include/exec/memory_ldst_phys.inc.h

@@ -0,0 +1,147 @@
+/*
+ *  Physical memory access templates
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *  Copyright (c) 2015 Linaro, Inc.
+ *  Copyright (c) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef TARGET_ENDIANNESS
+static inline uint32_t glue(ldl_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
+{
+    return glue(address_space_ldl, SUFFIX)(ARG1, addr,
+                                           MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline uint64_t glue(ldq_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
+{
+    return glue(address_space_ldq, SUFFIX)(ARG1, addr,
+                                           MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline uint32_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
+{
+    return glue(address_space_lduw, SUFFIX)(ARG1, addr,
+                                            MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
+{
+    glue(address_space_stl, SUFFIX)(ARG1, addr, val,
+                                    MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
+{
+    glue(address_space_stw, SUFFIX)(ARG1, addr, val,
+                                    MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
+{
+    glue(address_space_stq, SUFFIX)(ARG1, addr, val,
+                                    MEMTXATTRS_UNSPECIFIED, NULL);
+}
+#else
+static inline uint32_t glue(ldl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
+{
+    return glue(address_space_ldl_le, SUFFIX)(ARG1, addr,
+                                              MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline uint32_t glue(ldl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
+{
+    return glue(address_space_ldl_be, SUFFIX)(ARG1, addr,
+                                              MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline uint64_t glue(ldq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
+{
+    return glue(address_space_ldq_le, SUFFIX)(ARG1, addr,
+                                              MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline uint64_t glue(ldq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
+{
+    return glue(address_space_ldq_be, SUFFIX)(ARG1, addr,
+                                              MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline uint32_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
+{
+    return glue(address_space_ldub, SUFFIX)(ARG1, addr,
+                                            MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline uint32_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
+{
+    return glue(address_space_lduw_le, SUFFIX)(ARG1, addr,
+                                               MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline uint32_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
+{
+    return glue(address_space_lduw_be, SUFFIX)(ARG1, addr,
+                                               MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline void glue(stl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
+{
+    glue(address_space_stl_le, SUFFIX)(ARG1, addr, val,
+                                       MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline void glue(stl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
+{
+    glue(address_space_stl_be, SUFFIX)(ARG1, addr, val,
+                                       MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
+{
+    glue(address_space_stb, SUFFIX)(ARG1, addr, val,
+                                    MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
+{
+    glue(address_space_stw_le, SUFFIX)(ARG1, addr, val,
+                                       MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
+{
+    glue(address_space_stw_be, SUFFIX)(ARG1, addr, val,
+                                       MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline void glue(stq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
+{
+    glue(address_space_stq_le, SUFFIX)(ARG1, addr, val,
+                                       MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static inline void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
+{
+    glue(address_space_stq_be, SUFFIX)(ARG1, addr, val,
+                                       MEMTXATTRS_UNSPECIFIED, NULL);
+}
+#endif
+
+#undef ARG1_DECL
+#undef ARG1
+#undef SUFFIX
+#undef TARGET_ENDIANNESS

+ 1 - 1
include/qemu-common.h

@@ -137,7 +137,7 @@ char *qemu_find_file(int type, const char *name);
 /* OS specific functions */
 /* OS specific functions */
 void os_setup_early_signal_handling(void);
 void os_setup_early_signal_handling(void);
 char *os_find_datadir(void);
 char *os_find_datadir(void);
-void os_parse_cmd_args(int index, const char *optarg);
+int os_parse_cmd_args(int index, const char *optarg);
 
 
 #include "qemu/module.h"
 #include "qemu/module.h"
 
 

+ 1 - 2
include/qemu/option.h

@@ -28,8 +28,7 @@
 
 
 #include "qemu/queue.h"
 #include "qemu/queue.h"
 
 
-const char *get_opt_name(char *buf, int buf_size, const char *p, char delim);
-const char *get_opt_value(char *buf, int buf_size, const char *p);
+const char *get_opt_value(const char *p, char **value);
 
 
 void parse_option_size(const char *name, const char *value,
 void parse_option_size(const char *name, const char *value,
                        uint64_t *ret, Error **errp);
                        uint64_t *ret, Error **errp);

+ 1 - 0
include/qom/object.h

@@ -1302,6 +1302,7 @@ Object *object_get_internal_root(void);
  *
  *
  * Returns: The final component in the object's canonical path.  The canonical
  * Returns: The final component in the object's canonical path.  The canonical
  * path is the path within the composition tree starting from the root.
  * path is the path within the composition tree starting from the root.
+ * %NULL if the object doesn't have a parent (and thus a canonical path).
  */
  */
 gchar *object_get_canonical_path_component(Object *obj);
 gchar *object_get_canonical_path_component(Object *obj);
 
 

+ 0 - 1
include/sysemu/hostmem.h

@@ -52,7 +52,6 @@ struct HostMemoryBackend {
     Object parent;
     Object parent;
 
 
     /* protected */
     /* protected */
-    char *id;
     uint64_t size;
     uint64_t size;
     bool merge, dump;
     bool merge, dump;
     bool prealloc, force_prealloc, is_mapped, share;
     bool prealloc, force_prealloc, is_mapped, share;

+ 2 - 2
memory.c

@@ -298,7 +298,7 @@ static bool flatview_ref(FlatView *view)
     return atomic_fetch_inc_nonzero(&view->ref) > 0;
     return atomic_fetch_inc_nonzero(&view->ref) > 0;
 }
 }
 
 
-static void flatview_unref(FlatView *view)
+void flatview_unref(FlatView *view)
 {
 {
     if (atomic_fetch_dec(&view->ref) == 1) {
     if (atomic_fetch_dec(&view->ref) == 1) {
         trace_flatview_destroy_rcu(view, view->root);
         trace_flatview_destroy_rcu(view, view->root);
@@ -822,7 +822,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
     }
     }
 }
 }
 
 
-static FlatView *address_space_get_flatview(AddressSpace *as)
+FlatView *address_space_get_flatview(AddressSpace *as)
 {
 {
     FlatView *view;
     FlatView *view;
 
 

+ 0 - 126
memory_ldst.inc.c

@@ -95,24 +95,6 @@ uint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL,
                                                     DEVICE_BIG_ENDIAN);
                                                     DEVICE_BIG_ENDIAN);
 }
 }
 
 
-uint32_t glue(ldl_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
-{
-    return glue(address_space_ldl, SUFFIX)(ARG1, addr,
-                                           MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-uint32_t glue(ldl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
-{
-    return glue(address_space_ldl_le, SUFFIX)(ARG1, addr,
-                                              MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-uint32_t glue(ldl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
-{
-    return glue(address_space_ldl_be, SUFFIX)(ARG1, addr,
-                                              MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
 /* warning: addr must be aligned */
 /* warning: addr must be aligned */
 static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
 static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
     hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
     hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
@@ -189,24 +171,6 @@ uint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL,
                                                     DEVICE_BIG_ENDIAN);
                                                     DEVICE_BIG_ENDIAN);
 }
 }
 
 
-uint64_t glue(ldq_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
-{
-    return glue(address_space_ldq, SUFFIX)(ARG1, addr,
-                                           MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-uint64_t glue(ldq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
-{
-    return glue(address_space_ldq_le, SUFFIX)(ARG1, addr,
-                                              MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-uint64_t glue(ldq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
-{
-    return glue(address_space_ldq_be, SUFFIX)(ARG1, addr,
-                                              MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
 uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
 uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
     hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
     hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
 {
 {
@@ -241,12 +205,6 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
     return val;
     return val;
 }
 }
 
 
-uint32_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
-{
-    return glue(address_space_ldub, SUFFIX)(ARG1, addr,
-                                            MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
 /* warning: addr must be aligned */
 /* warning: addr must be aligned */
 static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
 static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
     hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
     hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
@@ -323,24 +281,6 @@ uint32_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL,
                                        DEVICE_BIG_ENDIAN);
                                        DEVICE_BIG_ENDIAN);
 }
 }
 
 
-uint32_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
-{
-    return glue(address_space_lduw, SUFFIX)(ARG1, addr,
-                                            MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-uint32_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
-{
-    return glue(address_space_lduw_le, SUFFIX)(ARG1, addr,
-                                               MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-uint32_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
-{
-    return glue(address_space_lduw_be, SUFFIX)(ARG1, addr,
-                                               MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
 /* warning: addr must be aligned. The ram page is not masked as dirty
 /* warning: addr must be aligned. The ram page is not masked as dirty
    and the code inside is not invalidated. It is useful if the dirty
    and the code inside is not invalidated. It is useful if the dirty
    bits are used to track modified PTEs */
    bits are used to track modified PTEs */
@@ -380,12 +320,6 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
     RCU_READ_UNLOCK();
     RCU_READ_UNLOCK();
 }
 }
 
 
-void glue(stl_phys_notdirty, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
-{
-    glue(address_space_stl_notdirty, SUFFIX)(ARG1, addr, val,
-                                             MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
 /* warning: addr must be aligned */
 /* warning: addr must be aligned */
 static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
 static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
     hwaddr addr, uint32_t val, MemTxAttrs attrs,
     hwaddr addr, uint32_t val, MemTxAttrs attrs,
@@ -460,24 +394,6 @@ void glue(address_space_stl_be, SUFFIX)(ARG1_DECL,
                                              result, DEVICE_BIG_ENDIAN);
                                              result, DEVICE_BIG_ENDIAN);
 }
 }
 
 
-void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
-{
-    glue(address_space_stl, SUFFIX)(ARG1, addr, val,
-                                    MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-void glue(stl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
-{
-    glue(address_space_stl_le, SUFFIX)(ARG1, addr, val,
-                                       MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-void glue(stl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
-{
-    glue(address_space_stl_be, SUFFIX)(ARG1, addr, val,
-                                       MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
 void glue(address_space_stb, SUFFIX)(ARG1_DECL,
 void glue(address_space_stb, SUFFIX)(ARG1_DECL,
     hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
     hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
 {
 {
@@ -509,12 +425,6 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
     RCU_READ_UNLOCK();
     RCU_READ_UNLOCK();
 }
 }
 
 
-void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
-{
-    glue(address_space_stb, SUFFIX)(ARG1, addr, val,
-                                    MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
 /* warning: addr must be aligned */
 /* warning: addr must be aligned */
 static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
 static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
     hwaddr addr, uint32_t val, MemTxAttrs attrs,
     hwaddr addr, uint32_t val, MemTxAttrs attrs,
@@ -589,24 +499,6 @@ void glue(address_space_stw_be, SUFFIX)(ARG1_DECL,
                                DEVICE_BIG_ENDIAN);
                                DEVICE_BIG_ENDIAN);
 }
 }
 
 
-void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
-{
-    glue(address_space_stw, SUFFIX)(ARG1, addr, val,
-                                    MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
-{
-    glue(address_space_stw_le, SUFFIX)(ARG1, addr, val,
-                                       MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
-{
-    glue(address_space_stw_be, SUFFIX)(ARG1, addr, val,
-                                       MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
 static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
 static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
     hwaddr addr, uint64_t val, MemTxAttrs attrs,
     hwaddr addr, uint64_t val, MemTxAttrs attrs,
     MemTxResult *result, enum device_endian endian)
     MemTxResult *result, enum device_endian endian)
@@ -680,24 +572,6 @@ void glue(address_space_stq_be, SUFFIX)(ARG1_DECL,
                                              DEVICE_BIG_ENDIAN);
                                              DEVICE_BIG_ENDIAN);
 }
 }
 
 
-void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
-{
-    glue(address_space_stq, SUFFIX)(ARG1, addr, val,
-                                    MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-void glue(stq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
-{
-    glue(address_space_stq_le, SUFFIX)(ARG1, addr, val,
-                                       MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
-{
-    glue(address_space_stq_be, SUFFIX)(ARG1, addr, val,
-                                       MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
 #undef ARG1_DECL
 #undef ARG1_DECL
 #undef ARG1
 #undef ARG1
 #undef SUFFIX
 #undef SUFFIX

+ 1 - 1
numa.c

@@ -580,7 +580,7 @@ static int query_memdev(Object *obj, void *opaque)
 
 
         m->value = g_malloc0(sizeof(*m->value));
         m->value = g_malloc0(sizeof(*m->value));
 
 
-        m->value->id = object_property_get_str(obj, "id", NULL);
+        m->value->id = object_get_canonical_path_component(obj);
         m->value->has_id = !!m->value->id;
         m->value->has_id = !!m->value->id;
 
 
         m->value->size = object_property_get_uint(obj, "size",
         m->value->size = object_property_get_uint(obj, "size",

+ 5 - 1
os-posix.c

@@ -165,7 +165,7 @@ static bool os_parse_runas_uid_gid(const char *optarg)
  * Parse OS specific command line options.
  * Parse OS specific command line options.
  * return 0 if option handled, -1 otherwise
  * return 0 if option handled, -1 otherwise
  */
  */
-void os_parse_cmd_args(int index, const char *optarg)
+int os_parse_cmd_args(int index, const char *optarg)
 {
 {
     switch (index) {
     switch (index) {
 #ifdef CONFIG_SLIRP
 #ifdef CONFIG_SLIRP
@@ -199,7 +199,11 @@ void os_parse_cmd_args(int index, const char *optarg)
         fips_set_state(true);
         fips_set_state(true);
         break;
         break;
 #endif
 #endif
+    default:
+        return -1;
     }
     }
+
+    return 0;
 }
 }
 
 
 static void change_process_uid(void)
 static void change_process_uid(void)

+ 2 - 2
os-win32.c

@@ -93,9 +93,9 @@ void os_set_line_buffering(void)
  * Parse OS specific command line options.
  * Parse OS specific command line options.
  * return 0 if option handled, -1 otherwise
  * return 0 if option handled, -1 otherwise
  */
  */
-void os_parse_cmd_args(int index, const char *optarg)
+int os_parse_cmd_args(int index, const char *optarg)
 {
 {
-    return;
+    return -1;
 }
 }
 
 
 int qemu_create_pidfile(const char *filename)
 int qemu_create_pidfile(const char *filename)

+ 73 - 10
qemu-doc.texi

@@ -39,6 +39,7 @@
 * QEMU User space emulator::
 * QEMU User space emulator::
 * Implementation notes::
 * Implementation notes::
 * Deprecated features::
 * Deprecated features::
+* Supported build platforms::
 * License::
 * License::
 * Index::
 * Index::
 @end menu
 @end menu
@@ -2786,16 +2787,6 @@ which is the default.
 
 
 @section System emulator command line arguments
 @section System emulator command line arguments
 
 
-@subsection -no-kvm-pit-reinjection (since 1.3.0)
-
-The ``-no-kvm-pit-reinjection'' argument is now a
-synonym for setting ``-global kvm-pit.lost_tick_policy=discard''.
-
-@subsection -no-kvm-irqchip (since 1.3.0)
-
-The ``-no-kvm-irqchip'' argument is now a synonym for
-setting ``-machine kernel_irqchip=off''.
-
 @subsection -no-kvm (since 1.3.0)
 @subsection -no-kvm (since 1.3.0)
 
 
 The ``-no-kvm'' argument is now a synonym for setting
 The ``-no-kvm'' argument is now a synonym for setting
@@ -2931,6 +2922,11 @@ The @code{-localtime} option has been replaced by @code{-rtc base=localtime}.
 
 
 The @code{-startdate} option has been replaced by @code{-rtc base=@var{date}}.
 The @code{-startdate} option has been replaced by @code{-rtc base=@var{date}}.
 
 
+@subsection -virtioconsole (since 2.13.0)
+
+Option @option{-virtioconsole} has been replaced by
+@option{-device virtconsole}.
+
 @section qemu-img command line arguments
 @section qemu-img command line arguments
 
 
 @subsection convert -s (since 2.0.0)
 @subsection convert -s (since 2.0.0)
@@ -2981,6 +2977,73 @@ The ``xlnx-zcu102'' machine has the same features and capabilites in QEMU.
 In order to prevent QEMU from automatically opening an image's backing
 In order to prevent QEMU from automatically opening an image's backing
 chain, use ``"backing": null'' instead.
 chain, use ``"backing": null'' instead.
 
 
+@node Supported build platforms
+@appendix Supported build platforms
+
+QEMU aims to support building and executing on multiple host OS platforms.
+This appendix outlines which platforms are the major build targets. These
+platforms are used as the basis for deciding upon the minimum required
+versions of 3rd party software QEMU depends on. The supported platforms
+are the targets for automated testing performed by the project when patches
+are submitted for review, and tested before and after merge.
+
+If a platform is not listed here, it does not imply that QEMU won't work.
+If an unlisted platform has comparable software versions to a listed platform,
+there is every expectation that it will work. Bug reports are welcome for
+problems encountered on unlisted platforms unless they are clearly older
+vintage than what is described here.
+
+Note that when considering software versions shipped in distros as support
+targets, QEMU considers only the version number, and assumes the features in
+that distro match the upstream release with the same version. In other words,
+if a distro backports extra features to the software in their distro, QEMU
+upstream code will not add explicit support for those backports, unless the
+feature is auto-detectable in a manner that works for the upstream releases
+too.
+
+The Repology site @url{https://repology.org} is a useful resource to identify
+currently shipped versions of software in various operating systems, though
+it does not cover all distros listed below.
+
+@section Linux OS
+
+For distributions with frequent, short-lifetime releases, the project will
+aim to support all versions that are not end of life by their respective
+vendors. For the purposes of identifying supported software versions, the
+project will look at Fedora, Ubuntu, and openSUSE distros. Other short-
+lifetime distros will be assumed to ship similar software versions.
+
+For distributions with long-lifetime releases, the project will aim to support
+the most recent major version at all times. Support for the previous major
+version will be dropped 2 years after the new major version is released. For
+the purposes of identifying supported software versions, the project will look
+at RHEL, Debian, Ubuntu LTS, and SLES distros. Other long-lifetime distros will
+be assumed to ship similar software versions.
+
+@section Windows
+
+The project supports building with current versions of the MinGW toolchain,
+hosted on Linux.
+
+@section macOS
+
+The project supports building with the two most recent versions of macOS, with
+the current homebrew package set available.
+
+@section FreeBSD
+
+The project aims to support the all the versions which are not end of life.
+
+@section NetBSD
+
+The project aims to support the most recent major version at all times. Support
+for the previous major version will be dropped 2 years after the new major
+version is released.
+
+@section OpenBSD
+
+The project aims to support the all the versions which are not end of life.
+
 @node License
 @node License
 @appendix License
 @appendix License
 
 

+ 1 - 14
qemu-options.hx

@@ -3675,10 +3675,7 @@ STEXI
 @item -virtioconsole @var{c}
 @item -virtioconsole @var{c}
 @findex -virtioconsole
 @findex -virtioconsole
 Set virtio console.
 Set virtio console.
-
-This option is maintained for backward compatibility.
-
-Please use @code{-device virtconsole} for the new way of invocation.
+This option is deprecated, please use @option{-device virtconsole} instead.
 ETEXI
 ETEXI
 
 
 DEF("show-cursor", 0, QEMU_OPTION_show_cursor, \
 DEF("show-cursor", 0, QEMU_OPTION_show_cursor, \
@@ -3917,16 +3914,6 @@ ETEXI
 HXCOMM Deprecated by -machine accel=tcg property
 HXCOMM Deprecated by -machine accel=tcg property
 DEF("no-kvm", 0, QEMU_OPTION_no_kvm, "", QEMU_ARCH_I386)
 DEF("no-kvm", 0, QEMU_OPTION_no_kvm, "", QEMU_ARCH_I386)
 
 
-HXCOMM Deprecated by kvm-pit driver properties
-DEF("no-kvm-pit-reinjection", 0, QEMU_OPTION_no_kvm_pit_reinjection,
-    "", QEMU_ARCH_I386)
-
-HXCOMM Deprecated by -machine kernel_irqchip=on|off property
-DEF("no-kvm-irqchip", 0, QEMU_OPTION_no_kvm_irqchip, "", QEMU_ARCH_I386)
-
-HXCOMM Deprecated (ignored)
-DEF("tdf", 0, QEMU_OPTION_tdf,"", QEMU_ARCH_ALL)
-
 DEF("msg", HAS_ARG, QEMU_OPTION_msg,
 DEF("msg", HAS_ARG, QEMU_OPTION_msg,
     "-msg timestamp[=on|off]\n"
     "-msg timestamp[=on|off]\n"
     "                change the format of messages\n"
     "                change the format of messages\n"

+ 3 - 2
qom/object.c

@@ -1644,8 +1644,9 @@ gchar *object_get_canonical_path_component(Object *obj)
     ObjectProperty *prop = NULL;
     ObjectProperty *prop = NULL;
     GHashTableIter iter;
     GHashTableIter iter;
 
 
-    g_assert(obj);
-    g_assert(obj->parent != NULL);
+    if (obj->parent == NULL) {
+        return NULL;
+    }
 
 
     g_hash_table_iter_init(&iter, obj->parent->properties);
     g_hash_table_iter_init(&iter, obj->parent->properties);
     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {

+ 0 - 6
qom/object_interfaces.c

@@ -65,12 +65,6 @@ Object *user_creatable_add_type(const char *type, const char *id,
 
 
     assert(qdict);
     assert(qdict);
     obj = object_new(type);
     obj = object_new(type);
-    if (object_property_find(obj, "id", NULL)) {
-        object_property_set_str(obj, id, "id", &local_err);
-        if (local_err) {
-            goto out;
-        }
-    }
     visit_start_struct(v, NULL, NULL, 0, &local_err);
     visit_start_struct(v, NULL, NULL, 0, &local_err);
     if (local_err) {
     if (local_err) {
         goto out;
         goto out;

+ 1 - 1
rules.mak

@@ -73,7 +73,7 @@ expand-objs = $(strip $(sort $(filter %.o,$1)) \
 # must link with the C++ compiler, not the plain C compiler.
 # must link with the C++ compiler, not the plain C compiler.
 LINKPROG = $(or $(CXX),$(CC))
 LINKPROG = $(or $(CXX),$(CC))
 
 
-LINK = $(call quiet-command, $(LINKPROG) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \
+LINK = $(call quiet-command, $(LINKPROG) $(QEMU_LDFLAGS) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \
        $(call process-archive-undefs, $1) \
        $(call process-archive-undefs, $1) \
        $(version-obj-y) $(call extract-libs,$1) $(LIBS),"LINK","$(TARGET_DIR)$@")
        $(version-obj-y) $(call extract-libs,$1) $(LIBS),"LINK","$(TARGET_DIR)$@")
 
 

+ 28 - 0
scripts/checkpatch.pl

@@ -265,8 +265,36 @@ our @typeList = (
 	qr{${Ident}_handler_fn},
 	qr{${Ident}_handler_fn},
 	qr{target_(?:u)?long},
 	qr{target_(?:u)?long},
 	qr{hwaddr},
 	qr{hwaddr},
+        # external libraries
 	qr{xml${Ident}},
 	qr{xml${Ident}},
 	qr{xendevicemodel_handle},
 	qr{xendevicemodel_handle},
+	# Glib definitions
+	qr{gchar},
+	qr{gshort},
+	qr{glong},
+	qr{gint},
+	qr{gboolean},
+	qr{guchar},
+	qr{gushort},
+	qr{gulong},
+	qr{guint},
+	qr{gfloat},
+	qr{gdouble},
+	qr{gpointer},
+	qr{gconstpointer},
+	qr{gint8},
+	qr{guint8},
+	qr{gint16},
+	qr{guint16},
+	qr{gint32},
+	qr{guint32},
+	qr{gint64},
+	qr{guint64},
+	qr{gsize},
+	qr{gssize},
+	qr{goffset},
+	qr{gintptr},
+	qr{guintptr},
 );
 );
 
 
 # This can be modified by sub possible.  Since it can be empty, be careful
 # This can be modified by sub possible.  Since it can be empty, be careful

+ 0 - 6
scripts/update-linux-headers.sh

@@ -118,9 +118,6 @@ for arch in $ARCHLIST; do
         cp "$tmpdir/include/asm/unistd-common.h" "$output/linux-headers/asm-arm/"
         cp "$tmpdir/include/asm/unistd-common.h" "$output/linux-headers/asm-arm/"
     fi
     fi
     if [ $arch = x86 ]; then
     if [ $arch = x86 ]; then
-        cat <<-EOF >"$output/include/standard-headers/asm-x86/hyperv.h"
-        /* this is a temporary placeholder until kvm_para.h stops including it */
-EOF
         cp "$tmpdir/include/asm/unistd_32.h" "$output/linux-headers/asm-x86/"
         cp "$tmpdir/include/asm/unistd_32.h" "$output/linux-headers/asm-x86/"
         cp "$tmpdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/"
         cp "$tmpdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/"
         cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/"
         cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/"
@@ -144,9 +141,6 @@ else
     cp "$linux/COPYING" "$output/linux-headers"
     cp "$linux/COPYING" "$output/linux-headers"
 fi
 fi
 
 
-cat <<EOF >$output/linux-headers/asm-x86/hyperv.h
-#include "standard-headers/asm-x86/hyperv.h"
-EOF
 cat <<EOF >$output/linux-headers/linux/virtio_config.h
 cat <<EOF >$output/linux-headers/linux/virtio_config.h
 #include "standard-headers/linux/virtio_config.h"
 #include "standard-headers/linux/virtio_config.h"
 EOF
 EOF

+ 1 - 1
target/cris/translate.c

@@ -3047,7 +3047,7 @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
     return insn_len;
     return insn_len;
 }
 }
 
 
-#include "translate_v10.c"
+#include "translate_v10.inc.c"
 
 
 /*
 /*
  * Delay slots on QEMU/CRIS.
  * Delay slots on QEMU/CRIS.

+ 0 - 0
target/cris/translate_v10.c → target/cris/translate_v10.inc.c


+ 3 - 1
target/i386/cpu.c

@@ -416,7 +416,8 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
             NULL /* hv_vpindex_access */, NULL /* hv_msr_reset_access */,
             NULL /* hv_vpindex_access */, NULL /* hv_msr_reset_access */,
             NULL /* hv_msr_stats_access */, NULL /* hv_reftsc_access */,
             NULL /* hv_msr_stats_access */, NULL /* hv_reftsc_access */,
             NULL /* hv_msr_idle_access */, NULL /* hv_msr_frequency_access */,
             NULL /* hv_msr_idle_access */, NULL /* hv_msr_frequency_access */,
-            NULL, NULL, NULL, NULL,
+            NULL /* hv_msr_debug_access */, NULL /* hv_msr_reenlightenment_access */,
+            NULL, NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
@@ -4770,6 +4771,7 @@ static Property x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
     DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
     DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
     DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
     DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
     DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
+    DEFINE_PROP_BOOL("hv-reenlightenment", X86CPU, hyperv_reenlightenment, false),
     DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
     DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
     DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
     DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
     DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
     DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),

+ 4 - 0
target/i386/cpu.h

@@ -1174,6 +1174,9 @@ typedef struct CPUX86State {
     uint64_t msr_hv_synic_sint[HV_SINT_COUNT];
     uint64_t msr_hv_synic_sint[HV_SINT_COUNT];
     uint64_t msr_hv_stimer_config[HV_STIMER_COUNT];
     uint64_t msr_hv_stimer_config[HV_STIMER_COUNT];
     uint64_t msr_hv_stimer_count[HV_STIMER_COUNT];
     uint64_t msr_hv_stimer_count[HV_STIMER_COUNT];
+    uint64_t msr_hv_reenlightenment_control;
+    uint64_t msr_hv_tsc_emulation_control;
+    uint64_t msr_hv_tsc_emulation_status;
 
 
     uint64_t msr_rtit_ctrl;
     uint64_t msr_rtit_ctrl;
     uint64_t msr_rtit_status;
     uint64_t msr_rtit_status;
@@ -1297,6 +1300,7 @@ struct X86CPU {
     bool hyperv_synic;
     bool hyperv_synic;
     bool hyperv_stimer;
     bool hyperv_stimer;
     bool hyperv_frequencies;
     bool hyperv_frequencies;
+    bool hyperv_reenlightenment;
     bool check_cpuid;
     bool check_cpuid;
     bool enforce_cpuid;
     bool enforce_cpuid;
     bool expose_kvm;
     bool expose_kvm;

+ 8 - 1
target/i386/hyperv-proto.h

@@ -35,7 +35,7 @@
 #define HV_RESET_AVAILABLE           (1u << 7)
 #define HV_RESET_AVAILABLE           (1u << 7)
 #define HV_REFERENCE_TSC_AVAILABLE   (1u << 9)
 #define HV_REFERENCE_TSC_AVAILABLE   (1u << 9)
 #define HV_ACCESS_FREQUENCY_MSRS     (1u << 11)
 #define HV_ACCESS_FREQUENCY_MSRS     (1u << 11)
-
+#define HV_ACCESS_REENLIGHTENMENTS_CONTROL  (1u << 13)
 
 
 /*
 /*
  * HV_CPUID_FEATURES.EDX bits
  * HV_CPUID_FEATURES.EDX bits
@@ -129,6 +129,13 @@
 #define HV_X64_MSR_CRASH_CTL                    0x40000105
 #define HV_X64_MSR_CRASH_CTL                    0x40000105
 #define HV_CRASH_CTL_NOTIFY                     (1ull << 63)
 #define HV_CRASH_CTL_NOTIFY                     (1ull << 63)
 
 
+/*
+ * Reenlightenment notification MSRs
+ */
+#define HV_X64_MSR_REENLIGHTENMENT_CONTROL      0x40000106
+#define HV_X64_MSR_TSC_EMULATION_CONTROL        0x40000107
+#define HV_X64_MSR_TSC_EMULATION_STATUS         0x40000108
+
 /*
 /*
  * Hypercall status code
  * Hypercall status code
  */
  */

+ 38 - 1
target/i386/kvm.c

@@ -90,6 +90,7 @@ static bool has_msr_hv_runtime;
 static bool has_msr_hv_synic;
 static bool has_msr_hv_synic;
 static bool has_msr_hv_stimer;
 static bool has_msr_hv_stimer;
 static bool has_msr_hv_frequencies;
 static bool has_msr_hv_frequencies;
+static bool has_msr_hv_reenlightenment;
 static bool has_msr_xss;
 static bool has_msr_xss;
 static bool has_msr_spec_ctrl;
 static bool has_msr_spec_ctrl;
 static bool has_msr_smi_count;
 static bool has_msr_smi_count;
@@ -583,7 +584,8 @@ static bool hyperv_enabled(X86CPU *cpu)
             cpu->hyperv_vpindex ||
             cpu->hyperv_vpindex ||
             cpu->hyperv_runtime ||
             cpu->hyperv_runtime ||
             cpu->hyperv_synic ||
             cpu->hyperv_synic ||
-            cpu->hyperv_stimer);
+            cpu->hyperv_stimer ||
+            cpu->hyperv_reenlightenment);
 }
 }
 
 
 static int kvm_arch_set_tsc_khz(CPUState *cs)
 static int kvm_arch_set_tsc_khz(CPUState *cs)
@@ -669,6 +671,16 @@ static int hyperv_handle_properties(CPUState *cs)
         }
         }
         env->features[FEAT_HYPERV_EDX] |= HV_GUEST_CRASH_MSR_AVAILABLE;
         env->features[FEAT_HYPERV_EDX] |= HV_GUEST_CRASH_MSR_AVAILABLE;
     }
     }
+    if (cpu->hyperv_reenlightenment) {
+        if (!has_msr_hv_reenlightenment) {
+            fprintf(stderr,
+                    "Hyper-V Reenlightenment MSRs "
+                    "(requested by 'hv-reenlightenment' cpu flag) "
+                    "are not supported by kernel\n");
+            return -ENOSYS;
+        }
+        env->features[FEAT_HYPERV_EAX] |= HV_ACCESS_REENLIGHTENMENTS_CONTROL;
+    }
     env->features[FEAT_HYPERV_EDX] |= HV_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
     env->features[FEAT_HYPERV_EDX] |= HV_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
     if (cpu->hyperv_reset) {
     if (cpu->hyperv_reset) {
         if (!has_msr_hv_reset) {
         if (!has_msr_hv_reset) {
@@ -1215,6 +1227,9 @@ static int kvm_get_supported_msrs(KVMState *s)
                 case HV_X64_MSR_TSC_FREQUENCY:
                 case HV_X64_MSR_TSC_FREQUENCY:
                     has_msr_hv_frequencies = true;
                     has_msr_hv_frequencies = true;
                     break;
                     break;
+                case HV_X64_MSR_REENLIGHTENMENT_CONTROL:
+                    has_msr_hv_reenlightenment = true;
+                    break;
                 case MSR_IA32_SPEC_CTRL:
                 case MSR_IA32_SPEC_CTRL:
                     has_msr_spec_ctrl = true;
                     has_msr_spec_ctrl = true;
                     break;
                     break;
@@ -1778,6 +1793,14 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
                 kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC,
                 kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC,
                                   env->msr_hv_tsc);
                                   env->msr_hv_tsc);
             }
             }
+            if (cpu->hyperv_reenlightenment) {
+                kvm_msr_entry_add(cpu, HV_X64_MSR_REENLIGHTENMENT_CONTROL,
+                                  env->msr_hv_reenlightenment_control);
+                kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_CONTROL,
+                                  env->msr_hv_tsc_emulation_control);
+                kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_STATUS,
+                                  env->msr_hv_tsc_emulation_status);
+            }
         }
         }
         if (cpu->hyperv_vapic) {
         if (cpu->hyperv_vapic) {
             kvm_msr_entry_add(cpu, HV_X64_MSR_APIC_ASSIST_PAGE,
             kvm_msr_entry_add(cpu, HV_X64_MSR_APIC_ASSIST_PAGE,
@@ -2140,6 +2163,11 @@ static int kvm_get_msrs(X86CPU *cpu)
     if (cpu->hyperv_time) {
     if (cpu->hyperv_time) {
         kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, 0);
         kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, 0);
     }
     }
+    if (cpu->hyperv_reenlightenment) {
+        kvm_msr_entry_add(cpu, HV_X64_MSR_REENLIGHTENMENT_CONTROL, 0);
+        kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_CONTROL, 0);
+        kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_STATUS, 0);
+    }
     if (has_msr_hv_crash) {
     if (has_msr_hv_crash) {
         int j;
         int j;
 
 
@@ -2397,6 +2425,15 @@ static int kvm_get_msrs(X86CPU *cpu)
             env->msr_hv_stimer_count[(index - HV_X64_MSR_STIMER0_COUNT)/2] =
             env->msr_hv_stimer_count[(index - HV_X64_MSR_STIMER0_COUNT)/2] =
                                 msrs[i].data;
                                 msrs[i].data;
             break;
             break;
+        case HV_X64_MSR_REENLIGHTENMENT_CONTROL:
+            env->msr_hv_reenlightenment_control = msrs[i].data;
+            break;
+        case HV_X64_MSR_TSC_EMULATION_CONTROL:
+            env->msr_hv_tsc_emulation_control = msrs[i].data;
+            break;
+        case HV_X64_MSR_TSC_EMULATION_STATUS:
+            env->msr_hv_tsc_emulation_status = msrs[i].data;
+            break;
         case MSR_MTRRdefType:
         case MSR_MTRRdefType:
             env->mtrr_deftype = msrs[i].data;
             env->mtrr_deftype = msrs[i].data;
             break;
             break;

+ 24 - 0
target/i386/machine.c

@@ -713,6 +713,29 @@ static const VMStateDescription vmstate_msr_hyperv_stimer = {
     }
     }
 };
 };
 
 
+static bool hyperv_reenlightenment_enable_needed(void *opaque)
+{
+    X86CPU *cpu = opaque;
+    CPUX86State *env = &cpu->env;
+
+    return env->msr_hv_reenlightenment_control != 0 ||
+        env->msr_hv_tsc_emulation_control != 0 ||
+        env->msr_hv_tsc_emulation_status != 0;
+}
+
+static const VMStateDescription vmstate_msr_hyperv_reenlightenment = {
+    .name = "cpu/msr_hyperv_reenlightenment",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = hyperv_reenlightenment_enable_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64(env.msr_hv_reenlightenment_control, X86CPU),
+        VMSTATE_UINT64(env.msr_hv_tsc_emulation_control, X86CPU),
+        VMSTATE_UINT64(env.msr_hv_tsc_emulation_status, X86CPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static bool avx512_needed(void *opaque)
 static bool avx512_needed(void *opaque)
 {
 {
     X86CPU *cpu = opaque;
     X86CPU *cpu = opaque;
@@ -1005,6 +1028,7 @@ VMStateDescription vmstate_x86_cpu = {
         &vmstate_msr_hyperv_runtime,
         &vmstate_msr_hyperv_runtime,
         &vmstate_msr_hyperv_synic,
         &vmstate_msr_hyperv_synic,
         &vmstate_msr_hyperv_stimer,
         &vmstate_msr_hyperv_stimer,
+        &vmstate_msr_hyperv_reenlightenment,
         &vmstate_avx512,
         &vmstate_avx512,
         &vmstate_xss,
         &vmstate_xss,
         &vmstate_tsc_khz,
         &vmstate_tsc_khz,

+ 17 - 15
target/i386/sev.c

@@ -430,7 +430,8 @@ static int
 sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
 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)
 {
 {
-    guchar *pdh_data, *cert_chain_data;
+    guchar *pdh_data = NULL;
+    guchar *cert_chain_data = NULL;
     struct sev_user_data_pdh_cert_export export = {};
     struct sev_user_data_pdh_cert_export export = {};
     int err, r;
     int err, r;
 
 
@@ -471,8 +472,9 @@ e_free:
 SevCapability *
 SevCapability *
 sev_get_capabilities(void)
 sev_get_capabilities(void)
 {
 {
-    SevCapability *cap;
-    guchar *pdh_data, *cert_chain_data;
+    SevCapability *cap = NULL;
+    guchar *pdh_data = NULL;
+    guchar *cert_chain_data = NULL;
     size_t pdh_len = 0, cert_chain_len = 0;
     size_t pdh_len = 0, cert_chain_len = 0;
     uint32_t ebx;
     uint32_t ebx;
     int fd;
     int fd;
@@ -486,7 +488,7 @@ sev_get_capabilities(void)
 
 
     if (sev_get_pdh_info(fd, &pdh_data, &pdh_len,
     if (sev_get_pdh_info(fd, &pdh_data, &pdh_len,
                          &cert_chain_data, &cert_chain_len)) {
                          &cert_chain_data, &cert_chain_len)) {
-        return NULL;
+        goto out;
     }
     }
 
 
     cap = g_new0(SevCapability, 1);
     cap = g_new0(SevCapability, 1);
@@ -502,9 +504,9 @@ sev_get_capabilities(void)
      */
      */
     cap->reduced_phys_bits = 1;
     cap->reduced_phys_bits = 1;
 
 
+out:
     g_free(pdh_data);
     g_free(pdh_data);
     g_free(cert_chain_data);
     g_free(cert_chain_data);
-
     close(fd);
     close(fd);
     return cap;
     return cap;
 }
 }
@@ -530,7 +532,7 @@ sev_launch_start(SEVState *s)
 {
 {
     gsize sz;
     gsize sz;
     int ret = 1;
     int ret = 1;
-    int fw_error;
+    int fw_error, rc;
     QSevGuestInfo *sev = s->sev_info;
     QSevGuestInfo *sev = s->sev_info;
     struct kvm_sev_launch_start *start;
     struct kvm_sev_launch_start *start;
     guchar *session = NULL, *dh_cert = NULL;
     guchar *session = NULL, *dh_cert = NULL;
@@ -543,7 +545,7 @@ sev_launch_start(SEVState *s)
                                             &error_abort);
                                             &error_abort);
     if (sev->session_file) {
     if (sev->session_file) {
         if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) {
         if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) {
-            return 1;
+            goto out;
         }
         }
         start->session_uaddr = (unsigned long)session;
         start->session_uaddr = (unsigned long)session;
         start->session_len = sz;
         start->session_len = sz;
@@ -551,18 +553,18 @@ sev_launch_start(SEVState *s)
 
 
     if (sev->dh_cert_file) {
     if (sev->dh_cert_file) {
         if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) {
         if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) {
-            return 1;
+            goto out;
         }
         }
         start->dh_uaddr = (unsigned long)dh_cert;
         start->dh_uaddr = (unsigned long)dh_cert;
         start->dh_len = sz;
         start->dh_len = sz;
     }
     }
 
 
     trace_kvm_sev_launch_start(start->policy, session, dh_cert);
     trace_kvm_sev_launch_start(start->policy, session, dh_cert);
-    ret = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error);
-    if (ret < 0) {
+    rc = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error);
+    if (rc < 0) {
         error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
         error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
                 __func__, ret, fw_error, fw_error_to_str(fw_error));
                 __func__, ret, fw_error, fw_error_to_str(fw_error));
-        return 1;
+        goto out;
     }
     }
 
 
     object_property_set_int(OBJECT(sev), start->handle, "handle",
     object_property_set_int(OBJECT(sev), start->handle, "handle",
@@ -570,12 +572,13 @@ sev_launch_start(SEVState *s)
     sev_set_guest_state(SEV_STATE_LAUNCH_UPDATE);
     sev_set_guest_state(SEV_STATE_LAUNCH_UPDATE);
     s->handle = start->handle;
     s->handle = start->handle;
     s->policy = start->policy;
     s->policy = start->policy;
+    ret = 0;
 
 
+out:
     g_free(start);
     g_free(start);
     g_free(session);
     g_free(session);
     g_free(dh_cert);
     g_free(dh_cert);
-
-    return 0;
+    return ret;
 }
 }
 
 
 static int
 static int
@@ -712,7 +715,7 @@ sev_guest_init(const char *id)
     uint32_t host_cbitpos;
     uint32_t host_cbitpos;
     struct sev_user_data_status status = {};
     struct sev_user_data_status status = {};
 
 
-    s = g_new0(SEVState, 1);
+    sev_state = s = g_new0(SEVState, 1);
     s->sev_info = lookup_sev_guest_info(id);
     s->sev_info = lookup_sev_guest_info(id);
     if (!s->sev_info) {
     if (!s->sev_info) {
         error_report("%s: '%s' is not a valid '%s' object",
         error_report("%s: '%s' is not a valid '%s' object",
@@ -720,7 +723,6 @@ sev_guest_init(const char *id)
         goto err;
         goto err;
     }
     }
 
 
-    sev_state = s;
     s->state = SEV_STATE_UNINIT;
     s->state = SEV_STATE_UNINIT;
 
 
     host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
     host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);

+ 1 - 1
target/mips/translate.c

@@ -20500,7 +20500,7 @@ void mips_tcg_init(void)
                                        "fcr31");
                                        "fcr31");
 }
 }
 
 
-#include "translate_init.c"
+#include "translate_init.inc.c"
 
 
 void cpu_mips_realize_env(CPUMIPSState *env)
 void cpu_mips_realize_env(CPUMIPSState *env)
 {
 {

+ 0 - 0
target/mips/translate_init.c → target/mips/translate_init.inc.c


+ 1 - 1
target/ppc/int_helper.c

@@ -379,7 +379,7 @@ target_ulong helper_divso(CPUPPCState *env, target_ulong arg1,
 target_ulong helper_602_mfrom(target_ulong arg)
 target_ulong helper_602_mfrom(target_ulong arg)
 {
 {
     if (likely(arg < 602)) {
     if (likely(arg < 602)) {
-#include "mfrom_table.c"
+#include "mfrom_table.inc.c"
         return mfrom_ROM_table[arg];
         return mfrom_ROM_table[arg];
     } else {
     } else {
         return 0;
         return 0;

+ 0 - 0
target/ppc/mfrom_table.c → target/ppc/mfrom_table.inc.c


+ 1 - 1
target/ppc/translate.c

@@ -6991,7 +6991,7 @@ GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \
 };
 };
 
 
 #include "helper_regs.h"
 #include "helper_regs.h"
-#include "translate_init.c"
+#include "translate_init.inc.c"
 
 
 /*****************************************************************************/
 /*****************************************************************************/
 /* Misc PowerPC helpers */
 /* Misc PowerPC helpers */

+ 0 - 1
target/ppc/translate_init.c → target/ppc/translate_init.inc.c

@@ -18,7 +18,6 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
  */
 
 
-#include "qemu/osdep.h"
 #include "disas/bfd.h"
 #include "disas/bfd.h"
 #include "exec/gdbstub.h"
 #include "exec/gdbstub.h"
 #include "kvm_ppc.h"
 #include "kvm_ppc.h"

+ 0 - 18
tests/test-qemu-opts.c

@@ -459,8 +459,6 @@ static void test_opts_parse(void)
 {
 {
     Error *err = NULL;
     Error *err = NULL;
     QemuOpts *opts;
     QemuOpts *opts;
-    char long_key[129];
-    char *params;
 
 
     /* Nothing */
     /* Nothing */
     opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort);
     opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort);
@@ -471,22 +469,6 @@ static void test_opts_parse(void)
     g_assert_cmpuint(opts_count(opts), ==, 1);
     g_assert_cmpuint(opts_count(opts), ==, 1);
     g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
     g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
 
 
-    /* Long key */
-    memset(long_key, 'a', 127);
-    long_key[127] = 'z';
-    long_key[128] = 0;
-    params = g_strdup_printf("%s=v", long_key);
-    opts = qemu_opts_parse(&opts_list_03, params + 1, NULL, &error_abort);
-    g_assert_cmpuint(opts_count(opts), ==, 1);
-    g_assert_cmpstr(qemu_opt_get(opts, long_key + 1), ==, "v");
-
-    /* Overlong key gets truncated */
-    opts = qemu_opts_parse(&opts_list_03, params, NULL, &error_abort);
-    g_assert(opts_count(opts) == 1);
-    long_key[127] = 0;
-    g_assert_cmpstr(qemu_opt_get(opts, long_key), ==, "v");
-    g_free(params);
-
     /* Multiple keys, last one wins */
     /* Multiple keys, last one wins */
     opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3",
     opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3",
                            false, &error_abort);
                            false, &error_abort);

+ 11 - 11
ui/vnc-enc-zrle.c

@@ -199,56 +199,56 @@ static void zrle_write_u8(VncState *vs, uint8_t value)
 
 
 #define ZRLE_BPP 8
 #define ZRLE_BPP 8
 #define ZYWRLE_ENDIAN ENDIAN_NO
 #define ZYWRLE_ENDIAN ENDIAN_NO
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 #undef ZRLE_BPP
 #undef ZRLE_BPP
 
 
 #define ZRLE_BPP 15
 #define ZRLE_BPP 15
 #undef ZYWRLE_ENDIAN
 #undef ZYWRLE_ENDIAN
 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 
 
 #undef ZYWRLE_ENDIAN
 #undef ZYWRLE_ENDIAN
 #define ZYWRLE_ENDIAN ENDIAN_BIG
 #define ZYWRLE_ENDIAN ENDIAN_BIG
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 
 
 #undef ZRLE_BPP
 #undef ZRLE_BPP
 #define ZRLE_BPP 16
 #define ZRLE_BPP 16
 #undef ZYWRLE_ENDIAN
 #undef ZYWRLE_ENDIAN
 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 
 
 #undef ZYWRLE_ENDIAN
 #undef ZYWRLE_ENDIAN
 #define ZYWRLE_ENDIAN ENDIAN_BIG
 #define ZYWRLE_ENDIAN ENDIAN_BIG
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 
 
 #undef ZRLE_BPP
 #undef ZRLE_BPP
 #define ZRLE_BPP 32
 #define ZRLE_BPP 32
 #undef ZYWRLE_ENDIAN
 #undef ZYWRLE_ENDIAN
 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 
 
 #undef ZYWRLE_ENDIAN
 #undef ZYWRLE_ENDIAN
 #define ZYWRLE_ENDIAN ENDIAN_BIG
 #define ZYWRLE_ENDIAN ENDIAN_BIG
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 
 
 #define ZRLE_COMPACT_PIXEL 24a
 #define ZRLE_COMPACT_PIXEL 24a
 #undef ZYWRLE_ENDIAN
 #undef ZYWRLE_ENDIAN
 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 
 
 #undef ZYWRLE_ENDIAN
 #undef ZYWRLE_ENDIAN
 #define ZYWRLE_ENDIAN ENDIAN_BIG
 #define ZYWRLE_ENDIAN ENDIAN_BIG
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 
 
 #undef ZRLE_COMPACT_PIXEL
 #undef ZRLE_COMPACT_PIXEL
 #define ZRLE_COMPACT_PIXEL 24b
 #define ZRLE_COMPACT_PIXEL 24b
 #undef ZYWRLE_ENDIAN
 #undef ZYWRLE_ENDIAN
 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 
 
 #undef ZYWRLE_ENDIAN
 #undef ZYWRLE_ENDIAN
 #define ZYWRLE_ENDIAN ENDIAN_BIG
 #define ZYWRLE_ENDIAN ENDIAN_BIG
-#include "vnc-enc-zrle-template.c"
+#include "vnc-enc-zrle.inc.c"
 #undef ZRLE_COMPACT_PIXEL
 #undef ZRLE_COMPACT_PIXEL
 #undef ZRLE_BPP
 #undef ZRLE_BPP
 
 

+ 0 - 0
ui/vnc-enc-zrle-template.c → ui/vnc-enc-zrle.inc.c


+ 79 - 71
util/qemu-option.c

@@ -43,26 +43,23 @@
  * first byte of the option name)
  * first byte of the option name)
  *
  *
  * The option name is delimited by delim (usually , or =) or the string end
  * The option name is delimited by delim (usually , or =) or the string end
- * and is copied into buf. If the option name is longer than buf_size, it is
- * truncated. buf is always zero terminated.
+ * and is copied into option. The caller is responsible for free'ing option
+ * when no longer required.
  *
  *
  * The return value is the position of the delimiter/zero byte after the option
  * The return value is the position of the delimiter/zero byte after the option
  * name in p.
  * name in p.
  */
  */
-const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
+static const char *get_opt_name(const char *p, char **option, char delim)
 {
 {
-    char *q;
+    char *offset = strchr(p, delim);
 
 
-    q = buf;
-    while (*p != '\0' && *p != delim) {
-        if (q && (q - buf) < buf_size - 1)
-            *q++ = *p;
-        p++;
+    if (offset) {
+        *option = g_strndup(p, offset - p);
+        return offset;
+    } else {
+        *option = g_strdup(p);
+        return p + strlen(p);
     }
     }
-    if (q)
-        *q = '\0';
-
-    return p;
 }
 }
 
 
 /*
 /*
@@ -73,25 +70,37 @@ const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
  * delimiter is fixed to be comma which starts a new option. To specify an
  * delimiter is fixed to be comma which starts a new option. To specify an
  * option value that contains commas, double each comma.
  * option value that contains commas, double each comma.
  */
  */
-const char *get_opt_value(char *buf, int buf_size, const char *p)
+const char *get_opt_value(const char *p, char **value)
 {
 {
-    char *q;
+    size_t capacity = 0, length;
+    const char *offset;
+
+    *value = NULL;
+    while (1) {
+        offset = strchr(p, ',');
+        if (!offset) {
+            offset = p + strlen(p);
+        }
 
 
-    q = buf;
-    while (*p != '\0') {
-        if (*p == ',') {
-            if (*(p + 1) != ',')
-                break;
-            p++;
+        length = offset - p;
+        if (*offset != '\0' && *(offset + 1) == ',') {
+            length++;
+        }
+        if (value) {
+            *value = g_renew(char, *value, capacity + length + 1);
+            strncpy(*value + capacity, p, length);
+            (*value)[capacity + length] = '\0';
         }
         }
-        if (q && (q - buf) < buf_size - 1)
-            *q++ = *p;
-        p++;
+        capacity += length;
+        if (*offset == '\0' ||
+            *(offset + 1) != ',') {
+            break;
+        }
+
+        p += (offset - p) + 2;
     }
     }
-    if (q)
-        *q = '\0';
 
 
-    return p;
+    return offset;
 }
 }
 
 
 static void parse_option_bool(const char *name, const char *value, bool *ret,
 static void parse_option_bool(const char *name, const char *value, bool *ret,
@@ -165,50 +174,43 @@ void parse_option_size(const char *name, const char *value,
 
 
 bool has_help_option(const char *param)
 bool has_help_option(const char *param)
 {
 {
-    size_t buflen = strlen(param) + 1;
-    char *buf = g_malloc(buflen);
     const char *p = param;
     const char *p = param;
     bool result = false;
     bool result = false;
 
 
-    while (*p) {
-        p = get_opt_value(buf, buflen, p);
+    while (*p && !result) {
+        char *value;
+
+        p = get_opt_value(p, &value);
         if (*p) {
         if (*p) {
             p++;
             p++;
         }
         }
 
 
-        if (is_help_option(buf)) {
-            result = true;
-            goto out;
-        }
+        result = is_help_option(value);
+        g_free(value);
     }
     }
 
 
-out:
-    g_free(buf);
     return result;
     return result;
 }
 }
 
 
-bool is_valid_option_list(const char *param)
+bool is_valid_option_list(const char *p)
 {
 {
-    size_t buflen = strlen(param) + 1;
-    char *buf = g_malloc(buflen);
-    const char *p = param;
-    bool result = true;
+    char *value = NULL;
+    bool result = false;
 
 
     while (*p) {
     while (*p) {
-        p = get_opt_value(buf, buflen, p);
-        if (*p && !*++p) {
-            result = false;
+        p = get_opt_value(p, &value);
+        if ((*p && !*++p) ||
+            (!*value || *value == ',')) {
             goto out;
             goto out;
         }
         }
 
 
-        if (!*buf || *buf == ',') {
-            result = false;
-            goto out;
-        }
+        g_free(value);
+        value = NULL;
     }
     }
 
 
+    result = true;
 out:
 out:
-    g_free(buf);
+    g_free(value);
     return result;
     return result;
 }
 }
 
 
@@ -490,7 +492,7 @@ int qemu_opt_unset(QemuOpts *opts, const char *name)
     }
     }
 }
 }
 
 
-static void opt_set(QemuOpts *opts, const char *name, const char *value,
+static void opt_set(QemuOpts *opts, const char *name, char *value,
                     bool prepend, Error **errp)
                     bool prepend, Error **errp)
 {
 {
     QemuOpt *opt;
     QemuOpt *opt;
@@ -499,6 +501,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
 
 
     desc = find_desc_by_name(opts->list->desc, name);
     desc = find_desc_by_name(opts->list->desc, name);
     if (!desc && !opts_accepts_any(opts)) {
     if (!desc && !opts_accepts_any(opts)) {
+        g_free(value);
         error_setg(errp, QERR_INVALID_PARAMETER, name);
         error_setg(errp, QERR_INVALID_PARAMETER, name);
         return;
         return;
     }
     }
@@ -512,8 +515,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
         QTAILQ_INSERT_TAIL(&opts->head, opt, next);
         QTAILQ_INSERT_TAIL(&opts->head, opt, next);
     }
     }
     opt->desc = desc;
     opt->desc = desc;
-    opt->str = g_strdup(value);
-    assert(opt->str);
+    opt->str = value;
     qemu_opt_parse(opt, &local_err);
     qemu_opt_parse(opt, &local_err);
     if (local_err) {
     if (local_err) {
         error_propagate(errp, local_err);
         error_propagate(errp, local_err);
@@ -524,7 +526,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
 void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
 void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
                   Error **errp)
                   Error **errp)
 {
 {
-    opt_set(opts, name, value, false, errp);
+    opt_set(opts, name, g_strdup(value), false, errp);
 }
 }
 
 
 void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
 void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
@@ -757,7 +759,8 @@ void qemu_opts_print(QemuOpts *opts, const char *separator)
 static void opts_do_parse(QemuOpts *opts, const char *params,
 static void opts_do_parse(QemuOpts *opts, const char *params,
                           const char *firstname, bool prepend, Error **errp)
                           const char *firstname, bool prepend, Error **errp)
 {
 {
-    char option[128], value[1024];
+    char *option = NULL;
+    char *value = NULL;
     const char *p,*pe,*pc;
     const char *p,*pe,*pc;
     Error *local_err = NULL;
     Error *local_err = NULL;
 
 
@@ -768,39 +771,45 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
             /* found "foo,more" */
             /* found "foo,more" */
             if (p == params && firstname) {
             if (p == params && firstname) {
                 /* implicitly named first option */
                 /* implicitly named first option */
-                pstrcpy(option, sizeof(option), firstname);
-                p = get_opt_value(value, sizeof(value), p);
+                option = g_strdup(firstname);
+                p = get_opt_value(p, &value);
             } else {
             } else {
                 /* option without value, probably a flag */
                 /* option without value, probably a flag */
-                p = get_opt_name(option, sizeof(option), p, ',');
+                p = get_opt_name(p, &option, ',');
                 if (strncmp(option, "no", 2) == 0) {
                 if (strncmp(option, "no", 2) == 0) {
                     memmove(option, option+2, strlen(option+2)+1);
                     memmove(option, option+2, strlen(option+2)+1);
-                    pstrcpy(value, sizeof(value), "off");
+                    value = g_strdup("off");
                 } else {
                 } else {
-                    pstrcpy(value, sizeof(value), "on");
+                    value = g_strdup("on");
                 }
                 }
             }
             }
         } else {
         } else {
             /* found "foo=bar,more" */
             /* found "foo=bar,more" */
-            p = get_opt_name(option, sizeof(option), p, '=');
-            if (*p != '=') {
-                break;
-            }
+            p = get_opt_name(p, &option, '=');
+            assert(*p == '=');
             p++;
             p++;
-            p = get_opt_value(value, sizeof(value), p);
+            p = get_opt_value(p, &value);
         }
         }
         if (strcmp(option, "id") != 0) {
         if (strcmp(option, "id") != 0) {
             /* store and parse */
             /* store and parse */
             opt_set(opts, option, value, prepend, &local_err);
             opt_set(opts, option, value, prepend, &local_err);
+            value = NULL;
             if (local_err) {
             if (local_err) {
                 error_propagate(errp, local_err);
                 error_propagate(errp, local_err);
-                return;
+                goto cleanup;
             }
             }
         }
         }
         if (*p != ',') {
         if (*p != ',') {
             break;
             break;
         }
         }
+        g_free(option);
+        g_free(value);
+        option = value = NULL;
     }
     }
+
+ cleanup:
+    g_free(option);
+    g_free(value);
 }
 }
 
 
 /**
 /**
@@ -819,7 +828,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
                             bool permit_abbrev, bool defaults, Error **errp)
                             bool permit_abbrev, bool defaults, Error **errp)
 {
 {
     const char *firstname;
     const char *firstname;
-    char value[1024], *id = NULL;
+    char *id = NULL;
     const char *p;
     const char *p;
     QemuOpts *opts;
     QemuOpts *opts;
     Error *local_err = NULL;
     Error *local_err = NULL;
@@ -828,11 +837,9 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
     firstname = permit_abbrev ? list->implied_opt_name : NULL;
     firstname = permit_abbrev ? list->implied_opt_name : NULL;
 
 
     if (strncmp(params, "id=", 3) == 0) {
     if (strncmp(params, "id=", 3) == 0) {
-        get_opt_value(value, sizeof(value), params+3);
-        id = value;
+        get_opt_value(params + 3, &id);
     } else if ((p = strstr(params, ",id=")) != NULL) {
     } else if ((p = strstr(params, ",id=")) != NULL) {
-        get_opt_value(value, sizeof(value), p+4);
-        id = value;
+        get_opt_value(p + 4, &id);
     }
     }
 
 
     /*
     /*
@@ -844,6 +851,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
      */
      */
     assert(!defaults || list->merge_lists);
     assert(!defaults || list->merge_lists);
     opts = qemu_opts_create(list, id, !defaults, &local_err);
     opts = qemu_opts_create(list, id, !defaults, &local_err);
+    g_free(id);
     if (opts == NULL) {
     if (opts == NULL) {
         error_propagate(errp, local_err);
         error_propagate(errp, local_err);
         return NULL;
         return NULL;

+ 13 - 20
util/qemu-thread-posix.c

@@ -482,7 +482,6 @@ static void __attribute__((constructor)) qemu_thread_atexit_init(void)
 }
 }
 
 
 
 
-#ifdef CONFIG_PTHREAD_SETNAME_NP
 typedef struct {
 typedef struct {
     void *(*start_routine)(void *);
     void *(*start_routine)(void *);
     void *arg;
     void *arg;
@@ -495,16 +494,18 @@ static void *qemu_thread_start(void *args)
     void *(*start_routine)(void *) = qemu_thread_args->start_routine;
     void *(*start_routine)(void *) = qemu_thread_args->start_routine;
     void *arg = qemu_thread_args->arg;
     void *arg = qemu_thread_args->arg;
 
 
+#ifdef CONFIG_PTHREAD_SETNAME_NP
     /* Attempt to set the threads name; note that this is for debug, so
     /* Attempt to set the threads name; note that this is for debug, so
      * we're not going to fail if we can't set it.
      * we're not going to fail if we can't set it.
      */
      */
-    pthread_setname_np(pthread_self(), qemu_thread_args->name);
+    if (name_threads && qemu_thread_args->name) {
+        pthread_setname_np(pthread_self(), qemu_thread_args->name);
+    }
+#endif
     g_free(qemu_thread_args->name);
     g_free(qemu_thread_args->name);
     g_free(qemu_thread_args);
     g_free(qemu_thread_args);
     return start_routine(arg);
     return start_routine(arg);
 }
 }
-#endif
-
 
 
 void qemu_thread_create(QemuThread *thread, const char *name,
 void qemu_thread_create(QemuThread *thread, const char *name,
                        void *(*start_routine)(void*),
                        void *(*start_routine)(void*),
@@ -513,6 +514,7 @@ void qemu_thread_create(QemuThread *thread, const char *name,
     sigset_t set, oldset;
     sigset_t set, oldset;
     int err;
     int err;
     pthread_attr_t attr;
     pthread_attr_t attr;
+    QemuThreadArgs *qemu_thread_args;
 
 
     err = pthread_attr_init(&attr);
     err = pthread_attr_init(&attr);
     if (err) {
     if (err) {
@@ -527,22 +529,13 @@ void qemu_thread_create(QemuThread *thread, const char *name,
     sigfillset(&set);
     sigfillset(&set);
     pthread_sigmask(SIG_SETMASK, &set, &oldset);
     pthread_sigmask(SIG_SETMASK, &set, &oldset);
 
 
-#ifdef CONFIG_PTHREAD_SETNAME_NP
-    if (name_threads) {
-        QemuThreadArgs *qemu_thread_args;
-        qemu_thread_args = g_new0(QemuThreadArgs, 1);
-        qemu_thread_args->name = g_strdup(name);
-        qemu_thread_args->start_routine = start_routine;
-        qemu_thread_args->arg = arg;
-
-        err = pthread_create(&thread->thread, &attr,
-                             qemu_thread_start, qemu_thread_args);
-    } else
-#endif
-    {
-        err = pthread_create(&thread->thread, &attr,
-                             start_routine, arg);
-    }
+    qemu_thread_args = g_new0(QemuThreadArgs, 1);
+    qemu_thread_args->name = g_strdup(name);
+    qemu_thread_args->start_routine = start_routine;
+    qemu_thread_args->arg = arg;
+
+    err = pthread_create(&thread->thread, &attr,
+                         qemu_thread_start, qemu_thread_args);
 
 
     if (err)
     if (err)
         error_exit(err, __func__);
         error_exit(err, __func__);

+ 6 - 18
vl.c

@@ -3138,11 +3138,6 @@ int main(int argc, char **argv, char **envp)
                 exit(1);
                 exit(1);
             }
             }
             switch(popt->index) {
             switch(popt->index) {
-            case QEMU_OPTION_no_kvm_irqchip: {
-                olist = qemu_find_opts("machine");
-                qemu_opts_parse_noisily(olist, "kernel_irqchip=off", false);
-                break;
-            }
             case QEMU_OPTION_cpu:
             case QEMU_OPTION_cpu:
                 /* hw initialization will check this */
                 /* hw initialization will check this */
                 cpu_model = optarg;
                 cpu_model = optarg;
@@ -3587,6 +3582,8 @@ int main(int argc, char **argv, char **envp)
                 }
                 }
                 break;
                 break;
             case QEMU_OPTION_virtiocon:
             case QEMU_OPTION_virtiocon:
+                warn_report("This option is deprecated, "
+                            "use '-device virtconsole' instead");
                 add_device_config(DEV_VIRTCON, optarg);
                 add_device_config(DEV_VIRTCON, optarg);
                 default_virtcon = 0;
                 default_virtcon = 0;
                 if (strncmp(optarg, "mon:", 4) == 0) {
                 if (strncmp(optarg, "mon:", 4) == 0) {
@@ -3694,18 +3691,6 @@ int main(int argc, char **argv, char **envp)
                 olist = qemu_find_opts("machine");
                 olist = qemu_find_opts("machine");
                 qemu_opts_parse_noisily(olist, "accel=tcg", false);
                 qemu_opts_parse_noisily(olist, "accel=tcg", false);
                 break;
                 break;
-            case QEMU_OPTION_no_kvm_pit_reinjection: {
-                static GlobalProperty kvm_pit_lost_tick_policy = {
-                    .driver   = "kvm-pit",
-                    .property = "lost_tick_policy",
-                    .value    = "discard",
-                };
-
-                warn_report("deprecated, replaced by "
-                            "-global kvm-pit.lost_tick_policy=discard");
-                qdev_prop_register_global(&kvm_pit_lost_tick_policy);
-                break;
-            }
             case QEMU_OPTION_accel:
             case QEMU_OPTION_accel:
                 accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
                 accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
                                                      optarg, true);
                                                      optarg, true);
@@ -4031,7 +4016,10 @@ int main(int argc, char **argv, char **envp)
                 }
                 }
                 break;
                 break;
             default:
             default:
-                os_parse_cmd_args(popt->index, optarg);
+                if (os_parse_cmd_args(popt->index, optarg)) {
+                    error_report("Option not supported in this build");
+                    exit(1);
+                }
             }
             }
         }
         }
     }
     }