1. 23 9月, 2020 2 次提交
    • S
      qemu/atomic.h: rename atomic_ to qatomic_ · d73415a3
      Stefan Hajnoczi 提交于
      clang's C11 atomic_fetch_*() functions only take a C11 atomic type
      pointer argument. QEMU uses direct types (int, etc) and this causes a
      compiler error when a QEMU code calls these functions in a source file
      that also included <stdatomic.h> via a system header file:
      
        $ CC=clang CXX=clang++ ./configure ... && make
        ../util/async.c:79:17: error: address argument to atomic operation must be a pointer to _Atomic type ('unsigned int *' invalid)
      
      Avoid using atomic_*() names in QEMU's atomic.h since that namespace is
      used by <stdatomic.h>. Prefix QEMU's APIs with 'q' so that atomic.h
      and <stdatomic.h> can co-exist. I checked /usr/include on my machine and
      searched GitHub for existing "qatomic_" users but there seem to be none.
      
      This patch was generated using:
      
        $ git grep -h -o '\<atomic\(64\)\?_[a-z0-9_]\+' include/qemu/atomic.h | \
          sort -u >/tmp/changed_identifiers
        $ for identifier in $(</tmp/changed_identifiers); do
              sed -i "s%\<$identifier\>%q$identifier%g" \
                  $(git grep -I -l "\<$identifier\>")
          done
      
      I manually fixed line-wrap issues and misaligned rST tables.
      Signed-off-by: NStefan Hajnoczi <stefanha@redhat.com>
      Reviewed-by: NPhilippe Mathieu-Daudé <philmd@redhat.com>
      Acked-by: NPaolo Bonzini <pbonzini@redhat.com>
      Message-Id: <20200923105646.47864-1-stefanha@redhat.com>
      d73415a3
    • I
      smp: drop support for deprecated (invalid topologies) · c4332cd1
      Igor Mammedov 提交于
      it's was deprecated since 3.1
      
      Support for invalid topologies is removed, the user must ensure
      that topologies described with -smp include all possible cpus,
      i.e. (sockets * cores * threads) == maxcpus or QEMU will
      exit with error.
      Signed-off-by: NIgor Mammedov <imammedo@redhat.com>
      Message-Id: <20200911133202.938754-1-imammedo@redhat.com>
      Signed-off-by: NEduardo Habkost <ehabkost@redhat.com>
      c4332cd1
  2. 19 9月, 2020 1 次提交
  3. 17 9月, 2020 13 次提交
  4. 10 9月, 2020 1 次提交
  5. 09 9月, 2020 2 次提交
  6. 02 9月, 2020 5 次提交
  7. 01 9月, 2020 2 次提交
  8. 28 8月, 2020 1 次提交
  9. 27 8月, 2020 1 次提交
    • M
      i386/acpi: fix inconsistent QEMU/OVMF device paths · af1b80ae
      Michael S. Tsirkin 提交于
      macOS uses ACPI UIDs to build the DevicePath for NVRAM boot options,
      while OVMF firmware gets them via an internal channel through QEMU.
      Due to a bug in QEMU ACPI currently UEFI firmware and ACPI have
      different values, and this makes the underlying operating system
      unable to report its boot option.
      
      The particular node in question is the primary PciRoot (PCI0 in ACPI),
      which for some reason gets assigned 1 in ACPI UID and 0 in the
      DevicePath. This is due to the _UID assigned to it by build_dsdt in
      hw/i386/acpi-build.c Which does not correspond to the primary PCI
      identifier given by pcibus_num in hw/pci/pci.c
      
      Reference with the device paths, OVMF startup logs, and ACPI table
      dumps (SysReport):
      https://github.com/acidanthera/bugtracker/issues/1050
      
      In UEFI v2.8, section "10.4.2 Rules with ACPI _HID and _UID" ends with
      the paragraph,
      
          Root PCI bridges will use the plug and play ID of PNP0A03, This will
          be stored in the ACPI Device Path _HID field, or in the Expanded
          ACPI Device Path _CID field to match the ACPI name space. The _UID
          in the ACPI Device Path structure must match the _UID in the ACPI
          name space.
      
      (See especially the last sentence.)
      
      Considering *extra* root bridges / root buses (with bus number > 0),
      QEMU's ACPI generator actually does the right thing; since QEMU commit
      c96d9286 ("i386/acpi-build: more traditional _UID and _HID for PXB
      root buses", 2015-06-11).
      
      However, the _UID values for root bridge zero (on both i440fx and q35)
      have always been "wrong" (from UEFI perspective), going back in QEMU to
      commit 74523b85 ("i386: add ACPI table files from seabios",
      2013-10-14).
      
      Even in SeaBIOS, these _UID values have always been 1; see commit
      a4d357638c57 ("Port rombios32 code from bochs-bios.", 2008-03-08) for
      i440fx, and commit ecbe3fd61511 ("seabios: q35: add dsdt", 2012-12-01)
      for q35.
      
      Cc: qemu-stable@nongnu.org
      Suggested-by: NLaszlo Ersek <lersek@redhat.com>
      Tested-by: NVitaly Cheptsov <vit9696@protonmail.com>
      Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
      Reviewed-by: NLaszlo Ersek <lersek@redhat.com>
      af1b80ae
  10. 21 8月, 2020 3 次提交
  11. 19 8月, 2020 1 次提交
  12. 27 7月, 2020 1 次提交
    • H
      hw/pci-host: save/restore pci host config register · 2ebc2121
      Hogan Wang 提交于
      The pci host config register is used to save PCI address for
      read/write config data. If guest writes a value to config register,
      and then QEMU pauses the vcpu to migrate, after the migration, the guest
      will continue to write pci config data, and the write data will be ignored
      because of new qemu process losing the config register state.
      
      To trigger the bug:
      1. guest is booting in seabios.
      2. guest enables the SMRAM in seabios:piix4_apmc_smm_setup, and then
         expects to disable the SMRAM by pci_config_writeb.
      3. after guest writes the pci host config register, QEMU pauses vcpu
         to finish migration.
      4. guest write of config data(0x0A) fails to disable the SMRAM because
         the config register state is lost.
      5. guest continues to boot and crashes in ipxe option ROM due to SMRAM
         in enabled state.
      
      Example Reproducer:
      
      step 1. Make modifications to seabios and qemu for increase reproduction
      efficiency, write 0xf0 to 0x402 port notify qemu to stop vcpu after
      0x0cf8 port wrote i440 configure register. qemu stop vcpu when catch
      0x402 port wrote 0xf0.
      
      seabios:/src/hw/pci.c
      @@ -52,6 +52,11 @@ void pci_config_writeb(u16 bdf, u32 addr, u8 val)
               writeb(mmconfig_addr(bdf, addr), val);
           } else {
               outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD);
      +       if (bdf == 0 && addr == 0x72 && val == 0xa) {
      +            dprintf(1, "stop vcpu\n");
      +            outb(0xf0, 0x402); // notify qemu to stop vcpu
      +            dprintf(1, "resume vcpu\n");
      +        }
               outb(val, PORT_PCI_DATA + (addr & 3));
           }
       }
      
      qemu:hw/char/debugcon.c
      @@ -60,6 +61,9 @@ static void debugcon_ioport_write(void *opaque, hwaddr addr, uint64_t val,
           printf(" [debugcon: write addr=0x%04" HWADDR_PRIx " val=0x%02" PRIx64 "]\n", addr, val);
       #endif
      
      +    if (ch == 0xf0) {
      +        vm_stop(RUN_STATE_PAUSED);
      +    }
           /* XXX this blocks entire thread. Rewrite to use
            * qemu_chr_fe_write and background I/O callbacks */
           qemu_chr_fe_write_all(&s->chr, &ch, 1);
      
      step 2. start vm1 by the following command line, and then vm stopped.
      $ qemu-system-x86_64 -machine pc-i440fx-5.0,accel=kvm\
       -netdev tap,ifname=tap-test,id=hostnet0,vhost=on,downscript=no,script=no\
       -device virtio-net-pci,netdev=hostnet0,id=net0,bus=pci.0,addr=0x13,bootindex=3\
       -device cirrus-vga,id=video0,vgamem_mb=16,bus=pci.0,addr=0x2\
       -chardev file,id=seabios,path=/var/log/test.seabios,append=on\
       -device isa-debugcon,iobase=0x402,chardev=seabios\
       -monitor stdio
      
      step 3. start vm2 to accept vm1 state.
      $ qemu-system-x86_64 -machine pc-i440fx-5.0,accel=kvm\
       -netdev tap,ifname=tap-test1,id=hostnet0,vhost=on,downscript=no,script=no\
       -device virtio-net-pci,netdev=hostnet0,id=net0,bus=pci.0,addr=0x13,bootindex=3\
       -device cirrus-vga,id=video0,vgamem_mb=16,bus=pci.0,addr=0x2\
       -chardev file,id=seabios,path=/var/log/test.seabios,append=on\
       -device isa-debugcon,iobase=0x402,chardev=seabios\
       -monitor stdio \
       -incoming tcp:127.0.0.1:8000
      
      step 4. execute the following qmp command in vm1 to migrate.
      (qemu) migrate tcp:127.0.0.1:8000
      
      step 5. execute the following qmp command in vm2 to resume vcpu.
      (qemu) cont
      Before this patch, we get KVM "emulation failure" error on vm2.
      This patch fixes it.
      
      Cc: qemu-stable@nongnu.org
      Signed-off-by: NHogan Wang <hogan.wang@huawei.com>
      Message-Id: <20200727084621.3279-1-hogan.wang@huawei.com>
      Reported-by: N"Dr. David Alan Gilbert" <dgilbert@redhat.com>
      Reviewed-by: NMichael S. Tsirkin <mst@redhat.com>
      Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
      2ebc2121
  13. 24 7月, 2020 1 次提交
  14. 22 7月, 2020 1 次提交
  15. 11 7月, 2020 1 次提交
    • A
      pc: fix leak in pc_system_flash_cleanup_unused · 0b33521e
      Alexander Bulekov 提交于
      tries to fix a leak detected when building with --enable-sanitizers:
      ./i386-softmmu/qemu-system-i386
      Upon exit:
      ==13576==ERROR: LeakSanitizer: detected memory leaks
      
      Direct leak of 1216 byte(s) in 1 object(s) allocated from:
          #0 0x7f9d2ed5c628 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5)
          #1 0x7f9d2e963500 in g_malloc (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.)
          #2 0x55fa646d25cc in object_new_with_type /tmp/qemu/qom/object.c:686
          #3 0x55fa63dbaa88 in qdev_new /tmp/qemu/hw/core/qdev.c:140
          #4 0x55fa638a533f in pc_pflash_create /tmp/qemu/hw/i386/pc_sysfw.c:88
          #5 0x55fa638a54c4 in pc_system_flash_create /tmp/qemu/hw/i386/pc_sysfw.c:106
          #6 0x55fa646caa1d in object_init_with_type /tmp/qemu/qom/object.c:369
          #7 0x55fa646d20b5 in object_initialize_with_type /tmp/qemu/qom/object.c:511
          #8 0x55fa646d2606 in object_new_with_type /tmp/qemu/qom/object.c:687
          #9 0x55fa639431e9 in qemu_init /tmp/qemu/softmmu/vl.c:3878
          #10 0x55fa6335c1b8 in main /tmp/qemu/softmmu/main.c:48
          #11 0x7f9d2cf06e0a in __libc_start_main ../csu/libc-start.c:308
          #12 0x55fa6335f8e9 in _start (/tmp/qemu/build/i386-softmmu/qemu-system-i386)
      Signed-off-by: NAlexander Bulekov <alxndr@bu.edu>
      Message-Id: <20200701145231.19531-1-alxndr@bu.edu>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      0b33521e
  16. 10 7月, 2020 4 次提交
    • M
      error: Eliminate error_propagate() manually · 992861fb
      Markus Armbruster 提交于
      When all we do with an Error we receive into a local variable is
      propagating to somewhere else, we can just as well receive it there
      right away.  The previous two commits did that for sufficiently simple
      cases with Coccinelle.  Do it for several more manually.
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: NEric Blake <eblake@redhat.com>
      Message-Id: <20200707160613.848843-37-armbru@redhat.com>
      992861fb
    • M
      error: Eliminate error_propagate() with Coccinelle, part 1 · 668f62ec
      Markus Armbruster 提交于
      When all we do with an Error we receive into a local variable is
      propagating to somewhere else, we can just as well receive it there
      right away.  Convert
      
          if (!foo(..., &err)) {
              ...
              error_propagate(errp, err);
              ...
              return ...
          }
      
      to
      
          if (!foo(..., errp)) {
              ...
              ...
              return ...
          }
      
      where nothing else needs @err.  Coccinelle script:
      
          @rule1 forall@
          identifier fun, err, errp, lbl;
          expression list args, args2;
          binary operator op;
          constant c1, c2;
          symbol false;
          @@
               if (
          (
          -        fun(args, &err, args2)
          +        fun(args, errp, args2)
          |
          -        !fun(args, &err, args2)
          +        !fun(args, errp, args2)
          |
          -        fun(args, &err, args2) op c1
          +        fun(args, errp, args2) op c1
          )
                  )
               {
                   ... when != err
                       when != lbl:
                       when strict
          -        error_propagate(errp, err);
                   ... when != err
          (
                   return;
          |
                   return c2;
          |
                   return false;
          )
               }
      
          @rule2 forall@
          identifier fun, err, errp, lbl;
          expression list args, args2;
          expression var;
          binary operator op;
          constant c1, c2;
          symbol false;
          @@
          -    var = fun(args, &err, args2);
          +    var = fun(args, errp, args2);
               ... when != err
               if (
          (
                   var
          |
                   !var
          |
                   var op c1
          )
                  )
               {
                   ... when != err
                       when != lbl:
                       when strict
          -        error_propagate(errp, err);
                   ... when != err
          (
                   return;
          |
                   return c2;
          |
                   return false;
          |
                   return var;
          )
               }
      
          @depends on rule1 || rule2@
          identifier err;
          @@
          -    Error *err = NULL;
               ... when != err
      
      Not exactly elegant, I'm afraid.
      
      The "when != lbl:" is necessary to avoid transforming
      
               if (fun(args, &err)) {
                   goto out
               }
               ...
           out:
               error_propagate(errp, err);
      
      even though other paths to label out still need the error_propagate().
      For an actual example, see sclp_realize().
      
      Without the "when strict", Coccinelle transforms vfio_msix_setup(),
      incorrectly.  I don't know what exactly "when strict" does, only that
      it helps here.
      
      The match of return is narrower than what I want, but I can't figure
      out how to express "return where the operand doesn't use @err".  For
      an example where it's too narrow, see vfio_intx_enable().
      
      Silently fails to convert hw/arm/armsse.c, because Coccinelle gets
      confused by ARMSSE being used both as typedef and function-like macro
      there.  Converted manually.
      
      Line breaks tidied up manually.  One nested declaration of @local_err
      deleted manually.  Preexisting unwanted blank line dropped in
      hw/riscv/sifive_e.c.
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: NEric Blake <eblake@redhat.com>
      Message-Id: <20200707160613.848843-35-armbru@redhat.com>
      668f62ec
    • M
      error: Avoid unnecessary error_propagate() after error_setg() · dcfe4805
      Markus Armbruster 提交于
      Replace
      
          error_setg(&err, ...);
          error_propagate(errp, err);
      
      by
      
          error_setg(errp, ...);
      
      Related pattern:
      
          if (...) {
              error_setg(&err, ...);
              goto out;
          }
          ...
       out:
          error_propagate(errp, err);
          return;
      
      When all paths to label out are that way, replace by
      
          if (...) {
              error_setg(errp, ...);
              return;
          }
      
      and delete the label along with the error_propagate().
      
      When we have at most one other path that actually needs to propagate,
      and maybe one at the end that where propagation is unnecessary, e.g.
      
          foo(..., &err);
          if (err) {
              goto out;
          }
          ...
          bar(..., &err);
       out:
          error_propagate(errp, err);
          return;
      
      move the error_propagate() to where it's needed, like
      
          if (...) {
              foo(..., &err);
              error_propagate(errp, err);
              return;
          }
          ...
          bar(..., errp);
          return;
      
      and transform the error_setg() as above.
      
      In some places, the transformation results in obviously unnecessary
      error_propagate().  The next few commits will eliminate them.
      
      Bonus: the elimination of gotos will make later patches in this series
      easier to review.
      
      Candidates for conversion tracked down with this Coccinelle script:
      
          @@
          identifier err, errp;
          expression list args;
          @@
          -    error_setg(&err, args);
          +    error_setg(errp, args);
               ... when != err
               error_propagate(errp, err);
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: NEric Blake <eblake@redhat.com>
      Message-Id: <20200707160613.848843-34-armbru@redhat.com>
      dcfe4805
    • M
      qom: Use returned bool to check for failure, Coccinelle part · 778a2dc5
      Markus Armbruster 提交于
      The previous commit enables conversion of
      
          foo(..., &err);
          if (err) {
              ...
          }
      
      to
      
          if (!foo(..., errp)) {
              ...
          }
      
      for QOM functions that now return true / false on success / error.
      Coccinelle script:
      
          @@
          identifier fun = {
              object_apply_global_props, object_initialize_child_with_props,
              object_initialize_child_with_propsv, object_property_get,
              object_property_get_bool, object_property_parse, object_property_set,
              object_property_set_bool, object_property_set_int,
              object_property_set_link, object_property_set_qobject,
              object_property_set_str, object_property_set_uint, object_set_props,
              object_set_propv, user_creatable_add_dict,
              user_creatable_complete, user_creatable_del
          };
          expression list args, args2;
          typedef Error;
          Error *err;
          @@
          -    fun(args, &err, args2);
          -    if (err)
          +    if (!fun(args, &err, args2))
               {
                   ...
               }
      
      Fails to convert hw/arm/armsse.c, because Coccinelle gets confused by
      ARMSSE being used both as typedef and function-like macro there.
      Convert manually.
      
      Line breaks tidied up manually.
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: NEric Blake <eblake@redhat.com>
      Reviewed-by: NVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Message-Id: <20200707160613.848843-29-armbru@redhat.com>
      778a2dc5